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

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

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


person Artium    schedule 26.05.2011    source источник
comment
Как определить, где брать красные точки?   -  person Sword22    schedule 27.05.2011
comment
@ Sword22 Все графики имеют одинаковую ось X. Красные точки — это в основном список значений по оси X.   -  person Artium    schedule 27.05.2011


Ответы (4)


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

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

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

пример вертикальных линий между сюжетами

person DSM    schedule 27.05.2011

Соответствующая документация:
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()

введите здесь описание изображения

person mechanical_meat    schedule 27.05.2011
comment
Мне очень нравится твой ответ. Однако в моем случае горизонтальные и вертикальные поля присутствуют, если я запускаю ваш код. Любая идея, как удалить их? - person Rickson; 23.12.2016
comment
Чтобы быть более точным. В моем случае диапазон оси x составляет [-5,20] вместо [0,20] и f. е. для последнего графика диапазон оси Y составляет [-1000,8000] вместо [0,7000]. Пробовал почти все (автомасштабирование, узкая ось, релим и т. д.) безуспешно. - person Rickson; 23.12.2016
comment
Если кому-то еще интересно: Это вызвано генерацией точек разброса. - person Rickson; 24.12.2016
comment
почему у xticklabels странный ввод ()? - person Parthiban Rajendran; 23.10.2018

[Обновление от 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')
person clesenne    schedule 26.03.2013

Я бы попробовал axvline(x, y1, y2) (ссылка), но не думаю, что любой из вариантов в pyplot будет рисовать что-то, что охватывает несколько подзаговоров/графиков.

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

person matt b    schedule 27.05.2011
comment
Извинения. В моем ответе нет новой информации, которой нет в вашем. Я уже собрал пример, поэтому подумал, что все равно опубликую. +1 вам за то, что вы намного быстрее. - person mechanical_meat; 27.05.2011
comment
согласен с Джонатаном, ответ с исходным кодом и примерами намного лучше, чем без него, скорость не в счет! - person matt b; 27.05.2011
comment
Если попробовать по-вашему, то линия скрыта за набором осей врезки. Что я делаю не так? - person ; 30.06.2014