Matplotlib - 更改水平线上/下的线条颜色

6
我有一条折线图和两条水平线,它们各自使用不同的颜色,并且我正在用水平线的颜色填充主线穿过水平线的区域。除此之外,我希望在这些区域中使用相同的颜色来绘制主线。简而言之,当前输出: enter image description here 期望输出: enter image description here 以下是我目前正在使用的相关代码:
lower, upper = 20, 80

self.indicatorPlot.axhline(lower, color="red")
self.indicatorPlot.axhline(upper, color="green")

self.indicatorPlot.plot(self.chartTimes, self.indicatorData, color="blue")

self.indicatorPlot.fill_between(self.chartTimes, self.indicatorData, lower, where=(self.indicatorData <= lower), facecolor="red", interpolate=True)
self.indicatorPlot.fill_between(self.chartTimes, self.indicatorData, upper, where=(self.indicatorData >= upper), facecolor="green", interpolate=True)
1个回答

8
原则上,您可以将绘图分成三个部分:高于upper的值,低于lower的值以及中间的值。从这个意义上讲,此问题已经被提出并回答了,例如: 如果您的点密度足够高,这些解决方案会非常好用,因为线条最终会靠近阈值线。
但是,如果存在较大的间隙,则它们可能不适合。因此,在这里提供一种解决方案,可以插值间隙,以便线条恰好结束在阈值线上。
import numpy as np; np.random.seed(43)
import matplotlib.pyplot as plt

t = np.linspace(0,100,301)
x = np.cumsum(np.random.randn(len(t)))

lower,upper = 0,8

fig, ax=plt.subplots()

ax.axhline(lower, color="crimson")
ax.axhline(upper, color="limegreen")


def insertzeros(t, x, zero=0):
    ta = []
    positive = (x-zero) > 0
    ti = np.where(np.bitwise_xor(positive[1:], positive[:-1]))[0]
    for i in ti:
        y_ = np.sort(x[i:i+2])
        z_ = t[i:i+2][np.argsort(x[i:i+2])]
        t_ = np.interp(zero, y_, z_)
        ta.append( t_ )
    tnew = np.append( t, np.array(ta) )
    xnew = np.append( x, np.ones(len(ta))*zero )
    xnew = xnew[tnew.argsort()]
    tnew = np.sort(tnew)
    return tnew, xnew

t1,x1 = insertzeros(t,x, zero=lower)
t1,x1 = insertzeros(t1,x1, zero=upper)

xm = np.copy(x1)
xm[(x1 < lower) | (x1 > upper)] = np.nan        
ax.plot(t1,xm, color="C0")

xl = np.copy(x1)
xl[(x1 > lower)] = np.nan        
ax.plot(t1,xl, color="crimson")
#
xu = np.copy(x1)
xu[(xu < upper)] = np.nan        
ax.plot(t1,xu, color="limegreen")

ax.fill_between(t, x, lower, where=(x <= lower), facecolor="crimson", interpolate=True, alpha=0.5)
ax.fill_between(t, x, upper, where=(x >= upper), facecolor="limegreen", interpolate=True, alpha=0.5)


plt.show()

enter image description here


在点穿过下方水平线的位置仍然保持蓝色这一小问题上遇到了些麻烦,但很容易修复,只需在绘制蓝线之后再绘制水平线即可。除此之外,一切都很完美,谢谢。 - Natsukane
这基本上也是我采取的方法。由于我有时间序列数据,因此在pandas中,我很容易使用.resample('S').interpolate()使点足够密集以超过阈值。 - Eric Blum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接