2011-05-26 5 views
15

Je ne sais pas comment cette chose est appelée, ni même comment la décrire, donc le titre peut être un peu trompeur.

Le premier graphique joint a été créé avec pyplot. Je voudrais tracer une ligne droite qui traverse tous les graphiques au lieu des trois points rouges que j'utilise actuellement. Est-ce possible dans pyplot? La deuxième image est ce que je cherche. Currently What I am looking forTracer une ligne sur plusieurs graphiques

+0

Comment déterminez-vous où prendre des points rouges? – Sword22

+0

@ Sword22 Tous les graphiques ont le même axe x. Les points rouges sont essentiellement une liste de valeurs sur l'axe x. – Artium

Répondre

24

Vous pouvez retirer ceci en tournant écrêter les lignes concernées. Il y a probablement plus propre façon de le faire - vous pourriez être en mesure de tracer des lignes sur le cadre principal directement - mais ce qui suit travaillé pour moi:

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

Avec un peu plus de travail, vous pouvez modifier la ligne de dessin à gérer le cas général de plusieurs fenêtres de sous-parcage, mais je suis profondément paresseux. : ^)

example of cross-subplot vertical lines

1

Je voudrais essayer axvline(x, y1, y2) (link), mais je ne pense pas que l'une des options de pyplot attireront quelque chose qui s'étend sur plusieurs sous-placettes/graphiques.

Si c'est le cas, j'essaierais simplement de dessiner la même ligne verticale à chaque point du graphique, en espérant que la même intention soit transmise au spectateur.

+0

Excuses. Ma réponse ne présente aucune nouvelle information que la vôtre n'a pas. J'avais déjà mis en place un exemple donc je pensais que je posterais quand même. +1 à vous pour être beaucoup plus rapide. – bernie

+1

@Adam Bernier Ne vous excusez jamais de fournir un exemple de code source ... –

+0

d'accord avec Jonathan, une réponse avec le code source et des exemples est beaucoup mieux qu'un sans, la vitesse ne compte pas! –

10

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

Edit: depuis @DSM's answer était tellement mieux que le mien, je l'ai honteusement incorporé une partie de cette réponse dans une tentative de rendre ma réponse moins pauvres.

J'ai essayé de traiter le cas plutôt général de plusieurs sous-placettes dans une colonne (c'est-à-dire pas le cas encore plus général de plusieurs sous-placettes, par exemple dans une grille).

Merci, @DSM, pour votre réponse et @Artium pour la question.

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

+0

J'aime vraiment votre réponse. Cependant, dans mon cas, les marges horizontales et verticales sont présentes si je cours votre code. Une idée de comment les supprimer? – Rickson

+0

Pour être plus précis. Dans mon cas, la plage du xaxis est [-5,20] au lieu de [0,20] et f. e.pour la dernière parcelle, la plage yaxis est [-1000,8000] au lieu de [0,7000]. Essayé presque tout (autoscale, axe serré, relim etc.) sans succès. – Rickson

+0

Si quelqu'un d'autre est intéressé: Il est causé par la génération des points de dispersion. – Rickson

5

[Mise à jour 03/2013] Dans les versions les plus récentes de matplotlib, il y a ConnectionPatch qui simplifie grandement cette tâche. C'est particulièrement utile chaque fois qu'il y a plus de deux sous-placettes qui doivent être couvertes.

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