<think>我们已经在图中添加了水平线(垂直于y轴),现在用户要求添加垂直于x轴的实线(即垂直线)并在最上方添加文字。
具体需求:添加一组固定值的数据(即x轴上的固定位置)用垂直于x轴的实线表示,在实线最上方添加文字。
修改步骤:
1. 使用`plt.axvline(x=value, ...)`添加垂直线,其中value是固定值。
2. 在垂直线的上方(即图形顶部)添加文字。由于垂直线是垂直的,最上方通常指的是图形y轴的最大值位置。
我们可以选择在数据坐标系中,将文字放在(value, y_max)的位置,或者使用相对坐标(坐标轴坐标系)将文字放在图形顶部中间。
但是用户要求“在实线最上方添加文字”,这里有两种理解:
a) 在垂直线的顶端(图形顶部)添加文字,即文字位于图形上方且与垂直线对齐。
b) 在垂直线的上方(沿着垂直线方向的最上端)添加文字,即文字位于垂直线的上方,但不一定在图形最顶部。
根据用户描述,应该是第一种:在图形的顶部,垂直线的正上方添加文字标注。
我们可以这样实现:
- 使用数据坐标:x=固定值,y=图形y轴的最大值(或稍微超过最大值的位置)来放置文字。
- 或者使用坐标轴坐标:x=固定值对应的坐标轴坐标(0到1之间),y=1(即顶部),但需要将固定值转换为坐标轴坐标。
考虑到图形可能缩放,使用坐标轴坐标可以保证文字始终在图形顶部,但水平位置会随固定值变化。
使用数据坐标则文字会随图形y轴范围变化。
这里我们选择数据坐标,因为文字应该与垂直线在x方向对齐,而y方向我们希望它在图形顶部上方一点。
具体步骤:
- 添加垂直线:`plt.axvline(x=target_x, color='blue', linestyle='-', linewidth=2, label='固定值线')`
- 获取当前y轴的最大值(即y轴的上限):`ymax = plt.ylim()[1]`
- 在位置`(target_x, ymax*1.02)`处添加文字(这样文字会在图形顶部上方2%的位置)
另外,为了让文字在垂直线的正上方,我们可以设置水平对齐为居中,这样文字的中心就在垂直线上。
修改代码示例:
假设我们要添加的固定值为x=1.5,文字标注为“目标值”。
在原有代码基础上修改:
- 在绘制完直方图和PDF曲线后,添加垂直线和文字。
注意:由于我们之前已经有一个固定值线(水平线),现在要添加的是垂直线,所以变量名要区分。
我们将之前的水平线命名为`target_value_h`(水平),现在添加的垂直线命名为`target_value_v`(垂直)。
完整代码修改部分如下:
</think>### 添加垂直于x轴的固定值实线及文字标注方法
根据您的需求,我将提供在正态分布图中添加垂直于x轴的固定值实线并在其上方添加文字的完整解决方案。以下是修改后的代码:
```python
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
# 设置正态分布参数
mu = 0 # 均值
sigma = 1 # 标准差
sample_size = 1000
# 生成正态分布数据
data = np.random.normal(mu, sigma, sample_size)
# 计算概率密度函数(PDF)
x = np.linspace(mu - 4.5*sigma, mu + 4.5*sigma, 200)
pdf = norm.pdf(x, mu, sigma)
# 创建图形
plt.figure(figsize=(12, 7))
# 绘制直方图
plt.hist(data, bins=30, density=True, alpha=0.6, color='skyblue',
edgecolor='black', label='样本数据')
# 绘制PDF曲线
plt.plot(x, pdf, 'r-', linewidth=2.5,
label=f'正态分布PDF ($\mu={mu}$, $\sigma={sigma}$)')
# 计算和标注±3σ区域
lower_3sigma = mu - 3*sigma
upper_3sigma = mu + 3*sigma
# 填充±3σ区域
mask = (x >= lower_3sigma) & (x <= upper_3sigma)
plt.fill_between(x, pdf, where=mask, color='lightgreen', alpha=0.4,
label=f'±3$\sigma$区域 (99.6%数据)')
# 添加垂直线标记±3σ边界
plt.axvline(lower_3sigma, color='darkgreen', linestyle='--', linewidth=1.5)
plt.axvline(upper_3sigma, color='darkgreen', linestyle='--', linewidth=1.5)
# --- 新增部分:添加垂直于x轴的固定值实线及文字标注 ---
target_x = 1.8 # 用户指定的固定x值
label_text = "目标值线" # 要在线上方显示的文字
# 添加垂直于x轴的实线
plt.axvline(x=target_x, color='purple', linestyle='-',
linewidth=2.5, label=label_text)
# 在实线上方添加文字标注
# 计算文字位置:x=目标值,y=PDF最大值上方10%
text_y = max(pdf) * 1.10
plt.text(target_x, text_y, label_text,
horizontalalignment='center', # 水平居中
verticalalignment='bottom', # 文字底部对齐到位置
fontsize=12,
color='purple',
fontweight='bold',
bbox=dict(facecolor='white', alpha=0.8, edgecolor='purple', boxstyle='round'))
# 添加文本标注
plt.text(lower_3sigma, max(pdf)*0.05, f'$\mu-3\sigma$={lower_3sigma:.2f}',
horizontalalignment='center', fontsize=11)
plt.text(upper_3sigma, max(pdf)*0.05, f'$\mu+3\sigma$={upper_3sigma:.2f}',
horizontalalignment='center', fontsize=11)
plt.text(mu, max(pdf)*0.8, f'99.6%数据落在\n±3$\sigma$范围内',
horizontalalignment='center', fontsize=12,
bbox=dict(facecolor='white', alpha=0.8))
# 添加图例和标签
plt.xlabel('数值', fontsize=12)
plt.ylabel('概率密度', fontsize=12)
plt.title('包含±3$\sigma$区域和固定值线的正态分布', fontsize=14)
plt.legend(loc='upper right', fontsize=11)
plt.grid(True, linestyle='--', alpha=0.7)
plt.tight_layout()
plt.show()
```
### 关键实现说明
1. **垂直于x轴的实线添加**
- 使用`plt.axvline(x=target_x, ...)`创建垂直线
- `target_x`指定x轴上的固定位置(垂直于x轴)
- 设置紫色实线(`color='purple'`)和线宽2.5(`linewidth=2.5`)
- 添加到图例中,标签为`label_text`
2. **文字标注定位**
- 文字位置设置为`(target_x, text_y)`:
- x坐标:与垂直线位置一致(`target_x`)
- y坐标:PDF最大值上方10% (`max(pdf) * 1.10`)
- 水平居中(`horizontalalignment='center'`)
- 文字底部对齐(`verticalalignment='bottom'`)
- 添加圆角白色背景框增强可读性
3. **优雅的文字呈现**
- 使用粗体字(`fontweight='bold'`)
- 紫色文字与线条颜色一致
- 圆角文本框(`boxstyle='round'`)
- 半透明背景(`alpha=0.8`)
### 应用场景
这种方法特别适用于:
1. **质量控制**:标记特定阈值(如规范上限)[^1]
2. **假设检验**:显示显著性边界($\alpha=0.05$)
3. **异常检测**:标识异常值边界
4. **决策分析**:可视化决策阈值位置