【问题标题】:Plotting a line over several graphs在多个图形上绘制一条线
【发布时间】:2011-05-26 23:37:21
【问题描述】:

我不知道这东西是怎么称呼的,也不知道怎么形容,所以标题可能有点误导。

第一个附加图是用 pyplot 创建的。我想画一条穿过所有图表的直线,而不是我目前使用的三个红点。在pyplot中可能吗?第二张图片是我正在寻找的。

【问题讨论】:

  • 如何确定在哪里取红点?
  • @Sword22 所有图表都有相同的 x 轴。红点基本上是 x 轴值的列表。

标签: python plot numerical matplotlib


【解决方案1】:

您可以通过关闭相关行的剪裁来实现这一点。可能有一种更简洁的方法来做到这一点——你可以直接在主框架上画线——但以下方法对我有用:

from matplotlib import pyplot as plt
from numpy import arange, sin, cos

xx = arange(100)
cut = (xx > 0) & (xx % 17 == 0)
y1 = sin(xx)
y2 = (xx**2) % 2.0+cos(xx+0.5)

fig = plt.figure()
ax1 = fig.add_subplot(211)
ax1.plot(xx, y1, c="blue",zorder=1)
ax1.scatter(xx[cut], y1[cut], c="red",zorder=2)
ax2 = fig.add_subplot(212)
ax2.plot(xx, y2, c="green",zorder=1)
ax2.scatter(xx[cut], y2[cut], c="red",zorder=2)

for x in xx[cut]:
    ax1.axvline(x=x,ymin=-1.2,ymax=1,c="red",linewidth=2,zorder=0, clip_on=False)
    ax2.axvline(x=x,ymin=0,ymax=1.2,c="red",linewidth=2, zorder=0,clip_on=False)

plt.draw()
fig.savefig('pic.png')

通过更多的工作,您可以修改线条图以处理多个子图窗口的一般情况,但我非常懒惰。 :^)

【讨论】:

    【解决方案2】:

    相关文档:
    http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.axvline

    编辑:因为@DSM's answer 比我的要好得多,所以我羞耻地合并了一些答案,试图让我的答案不那么糟糕。

    我尝试处理列中多个子图的一般情况(即不是多个子图的更一般情况,例如在网格中)。

    感谢@DSM 的回答和@Artium 的问题。

    import matplotlib.pyplot as plt
    import numpy as np
    
    def main():
        fig = plt.figure() 
    
        x = np.arange(20)
        y1 = np.cos(x)
        y2 = (x**2)
        y3 = (x**3)
        yn = (y1,y2,y3)
        cut = (x > 0) & (x % 2 == 0)
        COLORS = ('b','g','k')
    
        for i,y in enumerate(yn):
            ax = fig.add_subplot(len(yn),1,i+1)
    
            ax.plot(x, y,ls='solid', color=COLORS[i], zorder=1) 
            ax.scatter(x[cut], y[cut], c='r', zorder=2)
    
            if i != len(yn) - 1:
                ax.set_xticklabels( () )
    
            for j in x[cut]:
                if i != len(yn) - 1:
                    ax.axvline(x=j, ymin=-1.2, ymax=1,
                               c='r', lw=2, zorder=0, clip_on=False)
                else:
                    ax.axvline(x=j, ymin=0, ymax=1,
                               c='r', lw=2, zorder=0, clip_on=False)
    
        fig.suptitle('Matplotlib Vertical Line Example')
        plt.show()
    
    if __name__ == '__main__':
        main()
    

    【讨论】:

    • 我真的很喜欢你的回答。但是,在我的情况下,如果我运行您的代码,则会出现水平和垂直边距。知道如何删除它们吗?
    • 更准确地说。在我的例子中,xaxis 的范围是 [-5,20] 而不是 [0,20] 和 f。 e.对于最后一个图,y 轴范围是 [-1000,8000] 而不是 [0,7000]。尝试了几乎任何东西(自动缩放、紧轴、relim 等)但没有成功。
    • 如果别人有兴趣:是散点的产生造成的。
    • 为什么 xticklabels 有一个奇怪的输入 ()?
    【解决方案3】:

    [更新 03/2013] 在 matplotlib 的较新版本中,ConnectionPatch 大大简化了此任务。当需要覆盖两个以上的子图时,它特别有用。

    from matplotlib import pyplot as plt
    from matplotlib.patches import ConnectionPatch
    from numpy import arange, sin, cos
    
    xx = arange(100)
    cut = (xx > 0) & (xx % 17 == 0)
    y1 = sin(xx)
    y2 = (xx**2) % 2.0+cos(xx+0.5)
    
    fig = plt.figure()
    ax1 = fig.add_subplot(211)
    ax1.plot(xx, y1, c="blue")
    ax1.scatter(xx[cut], y1[cut], c="red")
    ax2 = fig.add_subplot(212)
    ax2.plot(xx, y2, c="green")
    ax2.scatter(xx[cut], y2[cut], c="red")
    
    for x in xx[cut]:
        con = ConnectionPatch(xyA=(x, -1.5), xyB=(x, 1.5),
            coordsA="data", coordsB="data", axesA=ax2, axesB=ax1,
            arrowstyle="-", linewidth=2, color="red")
        ax2.add_artist(con)
    
    plt.draw()
    fig.savefig('pic.png')
    

    【讨论】:

      【解决方案4】:

      我会尝试axvline(x, y1, y2) (link),但我认为 pyplot 中的任何选项都不会绘制跨越多个子图/图表的东西。

      如果是这样的话,我会尝试在图中的每个点绘制相同的垂直线,希望将相同的意图传达给查看者。

      【讨论】:

      • 道歉。我的回答没有提供您没有的任何新信息。我已经整理了一个例子,所以我想我还是会发布。为您 +1 更快。
      • 同意乔纳森的观点,有源代码和示例的答案比没有的要好得多,速度不算数!
      • 如果我尝试你的方式,这条线隐藏在插入轴组的后面。我做错了什么?
      猜你喜欢
      • 2020-11-09
      • 2019-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多