在几个图上绘制一条线

时间:2021-01-18 11:58:35

I don't know how this thing is called, or even how to describe it, so the title may be a little bit misleading.

The first attached graph was created with pyplot. I would like to draw a straight line that goes through all graphs instead of the three red dot I currently use. Is it possible in pyplot? Second image is what I am looking for. 在几个图上绘制一条线在几个图上绘制一条线

我不知道这个东西是如何调用的,甚至不知道如何描述它,所以标题可能会有点误导。第一个附加图是使用pyplot创建的。我想绘制一条贯穿所有图形的直线,而不是我目前使用的三个红点。在pyplot中有可能吗?第二张图片是我要找的。

4 个解决方案

#1


26  

You can pull this off by turning clipping off for the relevant lines. There's probably a cleaner way to do this -- you might be able to draw lines on the main frame directly -- but the following worked for me:

您可以通过关闭相关线的剪切来关闭它。可能有一种更简洁的方法 - 您可以直接在主框架上绘制线条 - 但以下对我有用:

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')

With a bit more work you could modify the line drawing to handle the general case of multiple subplot windows, but I'm profoundly lazy. :^)

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

在几个图上绘制一条线

#2


11  

Relevant documentation:
http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.axvline

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

Edit: since @DSM's answer was so much better than mine I have shamefully incorporated some of that answer in an attempt to make my answer less poor.

编辑:因为@ DSM的答案比我的好得多,所以我羞愧地把一些答案合并在一起,试图让我的答案变得不那么糟糕。

I've tried to handle the somewhat-general case of multiple subplots in a column (i.e. not the even-more-general case of multiple subplots, e.g. in a grid).

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

Thanks, @DSM, for your answer and @Artium for the question.

谢谢,@ 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()

在几个图上绘制一条线

#3


6  

[Update 03/2013] In newer revisions of matplotlib, there's ConnectionPatch that greatly simplifies this task. It's particularly useful whenever there are more than two subplots that need to be covered.

[更新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


1  

I would try axvline(x, y1, y2) (link), but I don't think any of the options in pyplot will draw something that spans across several subplots/graphs.

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

If that's the case, I would just try drawing the same vertical line at each point in the graph, hoping that the same intent is conveyed to the viewer.

如果是这种情况,我会尝试在图中的每个点绘制相同的垂直线,希望将相同的意图传达给观察者。

#1


26  

You can pull this off by turning clipping off for the relevant lines. There's probably a cleaner way to do this -- you might be able to draw lines on the main frame directly -- but the following worked for me:

您可以通过关闭相关线的剪切来关闭它。可能有一种更简洁的方法 - 您可以直接在主框架上绘制线条 - 但以下对我有用:

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')

With a bit more work you could modify the line drawing to handle the general case of multiple subplot windows, but I'm profoundly lazy. :^)

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

在几个图上绘制一条线

#2


11  

Relevant documentation:
http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.axvline

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

Edit: since @DSM's answer was so much better than mine I have shamefully incorporated some of that answer in an attempt to make my answer less poor.

编辑:因为@ DSM的答案比我的好得多,所以我羞愧地把一些答案合并在一起,试图让我的答案变得不那么糟糕。

I've tried to handle the somewhat-general case of multiple subplots in a column (i.e. not the even-more-general case of multiple subplots, e.g. in a grid).

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

Thanks, @DSM, for your answer and @Artium for the question.

谢谢,@ 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()

在几个图上绘制一条线

#3


6  

[Update 03/2013] In newer revisions of matplotlib, there's ConnectionPatch that greatly simplifies this task. It's particularly useful whenever there are more than two subplots that need to be covered.

[更新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


1  

I would try axvline(x, y1, y2) (link), but I don't think any of the options in pyplot will draw something that spans across several subplots/graphs.

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

If that's the case, I would just try drawing the same vertical line at each point in the graph, hoping that the same intent is conveyed to the viewer.

如果是这种情况,我会尝试在图中的每个点绘制相同的垂直线,希望将相同的意图传达给观察者。