问题描述
我希望使用共享同一比例尺但缺少x值的数据系列来填充Python 3x(目前我主要在v3.7中)两行之间的区域。
'fill_between'很方便,但需要两个y系列使用相同的x值 matplotlib documentation matplotlib demo
数据如下:
x1 = [0.0,3.2,10.2,15.4,19.9,24.2,27.7,33.9,50.7,67.9,83.7,102.0,105.8,119.4,129.3,140.3,146.0,150.2,158.3,166.7,168.6,171.7,173.5,175.3,184.1,203.7,220.2,221.8,226.8,231.9]
y1 = [99.95,99.99,100.11,99.59,98.24,98.5,99.21,99.46,99.35,99.18,98.71,98.26,97.92,98.02,97.63,98.49,99.17,98.85,97.35,97.43,98.66,99.36,99.14,99.08,99.25,98.74,98.82,99.73]
x2 = [-1.5,0.1,4.1,6.8,7.4,7.8,11.5,18.4,25.2,37.8,46.3,54.7,59.7,66.0,75.1,77.3,91.4,109.6,122.5,127.4,133.2,134.5,138.3,141.6,145.1,153.0,153.7,158.8,162.8,166.0,167.2,167.9,172.7,173.2,175.0,178.9,183.0,190.6,199.5,207.3,210.5,215.6,222.2,224.5,227.7,231.9]
y2 = [100.12,100.16,100.27,100.26,98.22,98.08,98.2,99.15,99.41,99.27,98.88,98.36,98.48,99.42,99.37,99.13,99.16,99.1,98.31,98.16,98.46,98.06,97.96,98.45,99.32,99.3,99.23,98.42,97.62,99.47,99.24,99.22,99.12,98.91,99.02,99.78]
fig,ax = plt.subplots(1,1,figsize=(14,6))
ax = plt.subplot(1,1)
ax.plot(x1,y1,c='blue')
ax.plot(x2,y2,c='red')
plt.show()
如果我尝试在两者之间进行填充,则会出现ValueError(因为系列的形状不同)。例如:
ax.fill_between(x1,y2)
返回:
ValueError:操作数不能与形状一起广播(30,) (46,)
我无法简单地用常见x来表示y值: approach2
这种方法通过过度绘制遮罩似乎有点不合时宜,并且无法多次重复地用于我的数据: approach3
似乎我需要将两个x系列相交并分别对每个系列的缺失y值进行插值?还是有更简单的方法让我丢失?
最终,我希望对区域进行不同的着色,例如:
ax.fill_between(x,interploate=True,where =(y1<y2),c="blue")
ax.fill_between(x,where =(y1>y2),c="red")
解决方法
您可以通过对组合的x1
和x2
进行排序来创建公共x轴。然后,您可以将x1,y1
插值到新的x轴上(对于x2,y2
也是如此):
import matplotlib.pyplot as plt
import numpy as np
x1 = [0.0,3.2,10.2,15.4,19.9,24.2,27.7,33.9,50.7,67.9,83.7,102.0,105.8,119.4,129.3,140.3,146.0,150.2,158.3,166.7,168.6,171.7,173.5,175.3,184.1,203.7,220.2,221.8,226.8,231.9]
y1 = [99.95,99.99,100.11,99.59,98.24,98.5,99.21,99.46,99.35,99.18,98.71,98.26,97.92,98.02,97.63,98.49,99.17,98.85,97.35,97.43,98.66,99.36,99.14,99.08,99.25,98.74,98.82,99.73]
x2 = [-1.5,0.1,4.1,6.8,7.4,7.8,11.5,18.4,25.2,37.8,46.3,54.7,59.7,66.0,75.1,77.3,91.4,109.6,122.5,127.4,133.2,134.5,138.3,141.6,145.1,153.0,153.7,158.8,162.8,166.0,167.2,167.9,172.7,173.2,175.0,178.9,183.0,190.6,199.5,207.3,210.5,215.6,222.2,224.5,227.7,231.9]
y2 = [100.12,100.16,100.27,100.26,98.22,98.08,98.2,99.15,99.41,99.27,98.88,98.36,98.48,99.42,99.37,99.13,99.16,99.1,98.31,98.16,98.46,98.06,97.96,98.45,99.32,99.3,99.23,98.42,97.62,99.47,99.24,99.22,99.12,98.91,99.02,99.78]
fig,ax = plt.subplots(1,1,figsize=(14,6))
ax.plot(x1,y1,c='dodgerblue')
ax.plot(x2,y2,c='crimson')
xfill = np.sort(np.concatenate([x1,x2]))
y1fill = np.interp(xfill,x1,y1)
y2fill = np.interp(xfill,x2,y2)
ax.fill_between(xfill,y1fill,y2fill,where=y1fill < y2fill,interpolate=True,color='dodgerblue',alpha=0.2)
ax.fill_between(xfill,where=y1fill > y2fill,color='crimson',alpha=0.2)
plt.show()