real - histograma python
Trazando una línea sobre varios gráficos (4)
Documentación relevante:
http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.axvline
Edit: dado que la respuesta de @ DSM fue mucho mejor que la mía, he incorporado vergonzosamente parte de esa respuesta en un intento por hacer que mi respuesta sea menos pobre.
He intentado manejar el caso un tanto general de múltiples subparcelas en una columna (es decir, no es el caso aún más general de múltiples subparcelas, por ejemplo, en una cuadrícula).
Gracias, @DSM, por su respuesta y @Artium por la pregunta.
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()
No sé cómo se llama esta cosa, ni siquiera cómo describirla, por lo que el título puede ser un poco engañoso.
El primer gráfico adjunto fue creado con pyplot. Me gustaría dibujar una línea recta que pase por todos los gráficos en lugar del punto rojo que utilizo actualmente. ¿Es posible en pyplot? La segunda imagen es lo que estoy buscando.
Puede hacer esto desactivando el recorte para las líneas relevantes. Probablemente haya una forma más limpia de hacer esto: es posible que pueda dibujar líneas en el marco principal directamente, pero lo siguiente funcionó para mí:
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'')
Con un poco más de trabajo, podría modificar el dibujo de línea para manejar el caso general de múltiples ventanas de subparcelas, pero estoy profundamente perezoso. : ^)
axvline(x, y1, y2)
( http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.axvline ), pero no creo que ninguna de las opciones en pyplot dibuje algo que se extienda a través de varias subparcelas / gráficos.
Si ese es el caso, solo intentaría dibujar la misma línea vertical en cada punto del gráfico, esperando que la misma intención se transmita al espectador.
[Actualización 03/2013] En las revisiones más recientes de matplotlib, hay ConnectionPatch que simplifica enormemente esta tarea. Es particularmente útil cuando hay más de dos subparcelas que deben cubrirse.
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'')