Я не знаю, как эта штука называется или даже как ее описать, поэтому название может немного вводить в заблуждение.
Первый прикрепленный график был создан с помощью pyplot. Я хотел бы нарисовать прямую линию, которая проходит через все графики, вместо трех красных точек, которые я сейчас использую. Возможно ли это в pyplot? Второе изображение - это то, что я ищу.
Построение линии на нескольких графиках
Ответы (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')
Приложив немного больше усилий, вы могли бы изменить рисунок линии, чтобы справиться с общим случаем нескольких окон подзаголовков, но я очень ленив. :^)
Соответствующая документация:
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()
[Обновление от 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')
Я бы попробовал axvline(x, y1, y2)
(ссылка), но не думаю, что любой из вариантов в pyplot будет рисовать что-то, что охватывает несколько подзаговоров/графиков.
Если это так, я бы просто попытался провести одну и ту же вертикальную линию в каждой точке графика, надеясь, что зрителю будет передано одно и то же намерение.