Построение линии над несколькими графиками

Я не знаю, как называется эта вещь, или даже как ее описывать, поэтому название может немного вводить в заблуждение.

Первый прикрепленный граф был создан с помощью pyplot. Я хотел бы нарисовать прямую линию, которая проходит через все графики вместо трех красных точек, которые я использую в настоящее время. Возможно ли это в pyplot? Второе изображение - это то, что я ищу. CurrentlyWhat I am looking for

Ответы

Ответ 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')

С немного дополнительной работой вы можете изменить чертеж линии, чтобы обрабатывать общий случай с несколькими окнами подзаголовка, но я глубоко ленив.: ^)

example of cross-subplot vertical lines

Ответ 2

Соответствующая документация:
http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.axvline

Изменить: поскольку ответ @DSM был намного лучше, чем у меня, я позорно включил часть этого ответа, пытаясь сделать мой ответ менее беден.

Я попытался обработать несколько общий случай множественных подзаговоров в столбце (т.е. не более общий случай множественных подзаговоров, например, в сетке).

Спасибо, @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()

enter image description here

Ответ 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) (ссылка), но я не думаю, что любой из вариантов в pyplot будет рисовать что-то, что охватывает несколько подзаговоров/графиков.

Если это так, я просто попробую сделать одну и ту же вертикальную линию в каждой точке графика, надеясь, что те же намерения будут переданы зрителю.