Python中Matplotlib填充不同长度数据集区域结果异常的问题
解决Matplotlib填充不同长度数据集区域的错误问题
问题背景
需要填充两个不同长度数据集之间的区域,数据集如下:
x1 = [0.00137221, 0.01372213, 0.02607204, 0.03910806, 0.05351629, 0.07066895, 0.08713551, 0.10634648, 0.12761578, 0.14888508, 0.17221269, 0.19691252, 0.2271012 , 0.25797599, 0.28747856, 0.31766724, 0.34373928, 0.36569468, 0.38559177] y1 = [1.03307393, 1.04661479, 1.05875486, 1.07182879, 1.08723735, 1.10544747, 1.11945525, 1.13299611, 1.14607004, 1.15540856, 1.15680934, 1.15680934, 1.15354086, 1.14513619, 1.13346303, 1.12085603, 1.10964981, 1.09891051, 1.08677043] x2 = [0.00960549, 0.03773585, 0.06929674, 0.11595197, 0.15574614, 0.18113208, 0.20994854, 0.2380789 , 0.27101201] y2 = [1.00645914, 1.02233463, 1.03821012, 1.05315175, 1.05688716, 1.05595331, 1.04894942, 1.04054475, 1.01579767]
参考插值方法编写的代码如下,但运行后填充效果错误,与LaTeX pgfplots的预期效果不符:
xfill = np.linspace(0,0.4,10) y1fill = np.interp(xfill, x1,y1) y2fill = np.interp(xfill, x2,y2) plt.plot(x1,y1) plt.plot(x2,y2) plt.fill_between(xfill, y1fill,y2fill,color = "lightgray")
错误原因
- 超出数据集范围的插值问题:
x2的最大取值为0.27101201,而xfill生成到0.4,np.interp默认会用x2最后一个y值填充超出范围的部分,导致x>0.271的区域填充错误。 - 插值点数过少:仅10个插值点导致填充区域不够平滑,与预期的连续曲线填充效果差距大。
解决方案
方法1:仅在两个数据集的共同x范围内填充
先计算两个数据集的x范围交集,只在该区间生成插值点,避免超出x2的有效范围:
import numpy as np import matplotlib.pyplot as plt # 数据集定义 x1 = [0.00137221, 0.01372213, 0.02607204, 0.03910806, 0.05351629, 0.07066895, 0.08713551, 0.10634648, 0.12761578, 0.14888508, 0.17221269, 0.19691252, 0.2271012 , 0.25797599, 0.28747856, 0.31766724, 0.34373928, 0.36569468, 0.38559177] y1 = [1.03307393, 1.04661479, 1.05875486, 1.07182879, 1.08723735, 1.10544747, 1.11945525, 1.13299611, 1.14607004, 1.15540856, 1.15680934, 1.15680934, 1.15354086, 1.14513619, 1.13346303, 1.12085603, 1.10964981, 1.09891051, 1.08677043] x2 = [0.00960549, 0.03773585, 0.06929674, 0.11595197, 0.15574614, 0.18113208, 0.20994854, 0.2380789 , 0.27101201] y2 = [1.00645914, 1.02233463, 1.03821012, 1.05315175, 1.05688716, 1.05595331, 1.04894942, 1.04054475, 1.01579767] # 计算共同x范围 min_x = max(min(x1), min(x2)) max_x = min(max(x1), max(x2)) # 生成足够多的插值点保证平滑 xfill = np.linspace(min_x, max_x, 1000) # 插值得到填充用的y值 y1fill = np.interp(xfill, x1, y1) y2fill = np.interp(xfill, x2, y2) # 绘图 plt.plot(x1, y1) plt.plot(x2, y2) plt.fill_between(xfill, y1fill, y2fill, color="lightgray") plt.show()
方法2:保留完整x范围,仅填充有效区域
如果需要保留x1的完整显示范围,仅在x2的有效区间内填充,可使用where参数控制填充区域:
import numpy as np import matplotlib.pyplot as plt # 数据集定义(同上) # 生成完整x范围的插值点 xfill = np.linspace(min(x1), max(x1), 1000) y1fill = np.interp(xfill, x1, y1) y2fill = np.interp(xfill, x2, y2) # 绘图 plt.plot(x1, y1) plt.plot(x2, y2) # 仅在x2的有效范围内填充 plt.fill_between(xfill, y1fill, y2fill, color="lightgray", where=(xfill >= min(x2)) & (xfill <= max(x2))) plt.show()
效果说明
两种方法都能解决原代码的填充错误问题:
- 方法1严格在两个数据集的共同x区间内填充,符合pgfplots的默认填充逻辑
- 方法2保留
x1的完整显示,仅填充x2覆盖的区域,避免无效插值带来的错误填充
内容的提问来源于stack exchange,提问作者Manuel Calavera
相关产品推荐
相关产品推荐

