Matplotlib fill_between未达指定X位置问题求助
解决Matplotlib fill_between填充高斯曲线未到达指定X位置的问题
问题根源
你的代码中np.linspace()默认仅生成50个采样点,目标X值especificacion=23.52并不在这个采样数组里。fill_between只能基于已有的x点进行填充,最终会停在x数组中最接近且小于等于23.52的那个点,视觉上就出现了填充未到指定位置的情况。
解决方案
方案1:提升采样点密度(简单高效)
给np.linspace()增加num参数,生成足够多的采样点,让填充区域视觉上完全贴合指定位置:
x = np.linspace(mean-(3*std), mean+(3*std), num=1000)
采样点数越多,填充精度越高,1000个点足以满足绝大多数可视化需求。
方案2:手动插入目标X点(绝对精确)
如果需要填充区域严格停在23.52位置,可以手动将该值插入x数组并重新计算对应y值:
# 生成原始采样数组 x = np.linspace(mean-(3*std), mean+(3*std)) # 插入目标值并重新排序 x = np.sort(np.append(x, especificacion)) # 重新计算高斯曲线y值 y = gaussian_curve(x, mean, std)
修改后的完整代码(方案1示例)
from scipy.stats import norm import numpy as np import matplotlib.pyplot as plt fig, ax = plt.subplots(figsize=(10,8)) mean = 29.02 std = 4.01 especificacion = 23.52 def gaussian_curve(x, mu, sigma): return norm.pdf(x, loc=mu, scale=sigma) # 提升采样点密度到1000 x = np.linspace(mean-(3*std), mean+(3*std), num=1000) y = gaussian_curve(x, mean, std) ax.plot(x, y, color='blue') fcr2 = mean-(std*1.2812) ax.set_xlim([mean-(3*std), mean+(3*std)]) ax.fill_between(x, 0, y, where=(x<=fcr2), hatch='///', color='blue', alpha=0.2) ax.fill_between(x, 0, y, where=(x<=especificacion), color='red', alpha=0.4) valor_y = norm.pdf(especificacion, loc=mean, scale=std) plt.annotate(f'fcr:{especificacion}', xy=(especificacion, valor_y), xytext=(especificacion, valor_y+0.02), arrowprops=dict(facecolor='black')) plt.annotate(f'fc10:{round(fcr2,2)}', xy=(round(fcr2,2), 0), xytext=(round(fcr2,2), 0.01), arrowprops=dict(facecolor='black')) plt.show()
为什么之前的尝试无效
- 调整
especificacion+0.3无法解决本质问题,因为x数组依然没有匹配的采样点,填充还是会停在最近的点; - 改变绘制顺序不影响采样点的密度问题,填充精度由x数组的点决定;
- 设置X轴范围只是调整显示区域,不会改变x数组的采样点集合。
内容的提问来源于stack exchange,提问作者enalvear
相关产品推荐
相关产品推荐

