2012-10-12 4 views
77

Ich bin relativ neu zu beiden Python/Matplotlib und über das Ipython-Notebook. Ich versuche, einem vorhandenen Diagramm einige Anmerkungszeilen hinzuzufügen, und ich kann nicht herausfinden, wie die Linien in einem Diagramm dargestellt werden. So zum Beispiel, wenn wir plotten folgende:Hinzufügen einer beliebigen Zeile zu einem Matplotlib-Plot in Ipython-Notebook

import numpy as np 
np.random.seed(5) 
x = arange(1, 101) 
y = 20 + 3 * x + np.random.normal(0, 60, 100) 
p = plot(x, y, "o") 

ich folgendes Diagramm:

beautiful scatter plot

Wie würde ich eine vertikale Linie von (70.100) in bis zu (70.250) ? Was ist mit einer diagonalen Linie von (70,100) bis (90,200)?

Ich habe ein paar Dinge mit Line2D() versucht, was in nichts als Verwirrung auf meiner Seite. In R würde ich einfach die segments() -Funktion verwenden, die Liniensegmente hinzufügen würde. Gibt es ein Äquivalent in matplotlib?

Antwort

131

Sie direkt die Linien zeichnen können Sie, indem das plot Befehl mit den entsprechenden Daten (Grenzen der Segmente) wollen :

plot([x1, x2], [y1, y2], color='k', linestyle='-', linewidth=2)

(natürlich können Sie die Farbe wählen, Linienbreite, Linienstil, etc.)

Von Ihrem Beispiel:

import numpy as np 
import matplotlib.pyplot as plt 

np.random.seed(5) 
x = np.arange(1, 101) 
y = 20 + 3 * x + np.random.normal(0, 60, 100) 
plt.plot(x, y, "o") 


# draw vertical line from (70,100) to (70, 250) 
plt.plot([70, 70], [100, 250], 'k-', lw=2) 

# draw diagonal line from (70, 90) to (90, 200) 
plt.plot([70, 90], [90, 200], 'k-') 

plt.show() 

new chart

+0

tolle Antwort mit ausgezeichneten und vollständigen Illustrationen! vielen, vielen Dank! –

+2

Kleine Korrektur, der obige Code sollte 'x = np.arange (1, 101)' lesen. –

+0

Dies zeichnet keine Linie, sondern nur ein Segment. Die Frage, wie man eine Linie wirft, wirft zwei gegebene Punkte unbeantwortet. – Alexey

30

Mit vlines:

import numpy as np 
np.random.seed(5) 
x = arange(1, 101) 
y = 20 + 3 * x + np.random.normal(0, 60, 100) 
p = plot(x, y, "o") 
vlines(70,100,250) 

Die Basisrufsteuerung Signaturen sind:

vlines(x, ymin, ymax) 
hlines(y, xmin, xmax) 
+2

das ist ausgezeichnet. Ich hatte die 'vline()' oder 'hline()' Funktionen nicht gesehen. Was ist mit diagonalen Linien? Ich habe die Frage bearbeitet, um das diagonale Bit hinzuzufügen, nachdem Sie mir die H & V-Linien gezeigt haben. –

+0

Versuchen Sie einen 'DataFrame' mit den x, y Koordinaten zu machen und zeichnen Sie mit' style = 'k-'' –

+0

Vielen Dank, das ist sehr praktisch – Alex

35

Es ist nicht zu spät für die Neuankömmlinge.

plt.axvline(x, color='r') 

http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.axvline

sie den Bereich von y als auch nimmt, ymin und ymax verwendet.

+1

Die Min/Max-Parameter von axhline und axvline sind skalare Werte zwischen 0 und 1, die Linien in Bezug auf die Kante des Diagramms darstellen. Obwohl es ein gutes Werkzeug ist, ist es wahrscheinlich nicht die beste Lösung für die Problemstellung des Autors beim Zeichnen von Anmerkungszeilen. – binarysubstrate

+1

Dies ist perfekt, wenn Sie im Hintergrund eine Anmerkungszeile hinzufügen möchten, die den gesamten Graphen umfasst. Wenn ich die gewählte Lösung oben verwende, um eine vertikale Linie bei x = 1 zu zeichnen, muss ich min und max y angeben, und dann ändert sich die Darstellung automatisch mit einem Puffer, so dass sich die Linie nicht über die gesamte Zeichnung erstreckt das ist ein Streit. Dies ist eleganter und ändert die Größe der Handlung nicht. – Bonnie

1

Matplolib erlaubt jetzt "Anmerkungszeilen", wie das OP es suchte. Die annotate()-Funktion ermöglicht mehrere Formen von Verbindungspfaden, und ein kopfloser und tailless Pfeil, d. H. Eine einfache Linie, ist einer von ihnen.

ax.annotate("", 
      xy=(0.2, 0.2), xycoords='data', 
      xytext=(0.8, 0.8), textcoords='data', 
      arrowprops=dict(arrowstyle="-", 
         connectionstyle="arc3, rad=0"), 
      ) 

In the documentation es sagt, dass Sie nur einen Pfeil mit einem leeren String als erstes Argument ziehen können.

Aus dem Beispiel des OP:

%matplotlib notebook 
import numpy as np 
import matplotlib.pyplot as plt 

np.random.seed(5) 
x = np.arange(1, 101) 
y = 20 + 3 * x + np.random.normal(0, 60, 100) 
plt.plot(x, y, "o") 


# draw vertical line from (70,100) to (70, 250) 
plt.annotate("", 
       xy=(70, 100), xycoords='data', 
       xytext=(70, 250), textcoords='data', 
       arrowprops=dict(arrowstyle="-", 
           connectionstyle="arc3,rad=0."), 
      ) 

# draw diagonal line from (70, 90) to (90, 200) 
plt.annotate("", 
       xy=(70, 90), xycoords='data', 
       xytext=(90, 200), textcoords='data', 
       arrowprops=dict(arrowstyle="-", 
           connectionstyle="arc3,rad=0."), 
      ) 

plt.show() 

Example inline image

Genau wie im Ansatz in gcalmettes Antwort, können Sie die Farbe, Linienbreite, Linienstil, etc. wählen ..

Hier ist eine Änderung zu einem Teil des Codes, der eine der beiden Beispielzeilen rot, breiter und nicht 100% undurchsichtig machen würde.

# draw vertical line from (70,100) to (70, 250) 
plt.annotate("", 
       xy=(70, 100), xycoords='data', 
       xytext=(70, 250), textcoords='data', 
       arrowprops=dict(arrowstyle="-", 
           edgecolor = "red", 
           linewidth=5, 
           alpha=0.65, 
           connectionstyle="arc3,rad=0."), 
      ) 

Sie können auch Kurve zur Verbindungslinie hinzufügen, indem Sie die connectionstyle Einstellung.