2016-12-22 5 views
1

Im Anschluss an my previous question habe ich die Koordinaten der Textbeschriftungsbox in Abbildung Bruchkoordinaten und versuchte, die Koordinaten des Pfeilfeldes in der gleichen Weise zu erhalten.Ermitteln der Koordinaten des Pfeils in einer Matplotlib-Annotation

Aber die Koordinaten ich nicht auf den Pfeil entsprechen, denn wenn ich eine Linie zeichnen über die gleichen Koordinaten nicht auf es nicht liegen:

import numpy as np 
import matplotlib 
matplotlib.use('agg') 
import matplotlib.pyplot as plt 

def f(x): 
    return 10 * np.sin(3*x)**4 

x = np.linspace(0, 2*np.pi, 100) 
y = f(x) 

fig, ax = plt.subplots() 
ax.plot(x,y) 

xpt = 1.75 
ypt = f(xpt) 
xy = ax.transData.transform([xpt, ypt]) 
xy = fig.transFigure.inverted().transform(xy) 

xytext = xy + [0.1, -0.1] 
rdx, rdy = 0, 1 
ann = ax.annotate('A point', xy=xy, xycoords='figure fraction', 
      xytext=xytext, textcoords='figure fraction', 
      arrowprops=dict(arrowstyle='->', connectionstyle="arc3", 
          relpos=(rdx, rdy)), 
      bbox=dict(fc='gray', edgecolor='k', alpha=0.5), 
      ha='left', va='top' 
      ) 
fig.canvas.draw() 

leader_line_box = ann.arrow_patch.get_extents() 
print(leader_line_box) 
leader_line_box = fig.transFigure.inverted().transform(leader_line_box) 
print(leader_line_box) 

from matplotlib.lines import Line2D 
line = Line2D(leader_line_box.T[0], leader_line_box.T[1],transform=fig.transFigure, lw=2, color='m') 
ax.add_line(line) 

plt.savefig('test.png') 

enter image description here

Wie kann Ich bekomme dieKoordinaten des Annotationspfeils in Zahlenbrucheinheiten und was ist bei meinem Versuch hier schiefgelaufen?

+0

Ich denke, es macht genau das, was Sie sagen: Zeichnen Sie eine Linie von links unten nach oben rechts von der Pfeilbegrenzungsbox. Wenn Sie möchten, dass die Linie mit dem Pfeil ausgerichtet ist, können Sie einfach '[:: - 1]' setzen, um entweder xdata oder ydata umzukehren. Sind das nicht die Koordinaten, nach denen du gesucht hast? Wo soll die Linie geplottet werden? – whrrgarbl

+0

Hmm - Ich denke du hast Recht. Was ich wirklich will, sind die Koordinaten des Schwanzes und der Kopf des Pfeils selbst. – xnx

Antwort

1

Der einfachste Weg, in diesem speziellen Fall ist die x-Koordinaten in umgekehrten

nur Unentschieden
line = Line2D(leader_line_box.T[0][::-1], leader_line_box.T[1],transform=fig.transFigure, lw=2, color='m') 

Wenn Sie eine allgemeine Lösung benötigen,

verts = ann.arrow_patch.get_path()._vertices 
tverts= fig.transFigure.inverted().transform(verts) 
index = [0,2] 
line = Line2D([tverts[index[0],0],tverts[index[1],0]], [tverts[index[0],1],tverts[index[1],1]], 
       transform=fig.transFigure, lw=2, color='m') 
ax.add_line(line) 

Dies funktioniert für jede Pfeilrichtung (nach oben oder nach unten, Osten oder Westen), ist aber spezifisch für die arrowprops Argumente arrowstyle='->' und connectionstyle="arc3". Wenn Sie einen anderen Pfeilstil oder Verbindungsstil verwenden, müssen Sie index auf verschiedene Werte setzen, die Sie finden, indem Sie die entsprechenden Indizes aus dem in verts gespeicherten Array auswählen.


In einem sehr allgemeinen Fall kann man unter der folgenden aussehen auch:

box = ann.arrow_patch._posA_posB 
tbox = fig.transFigure.inverted().transform(leader_line_box) 
print tbox 
line = Line2D(tbox.T[0], tbox.T[1],transform=fig.transFigure) 

Dies wird jedoch die Zeile zwischen dem kommentierten Punkt und den Text selbst. Im Allgemeinen kann sich diese Linie vom tatsächlichen Pfeil unterscheiden, abhängig vom verwendeten Pfeilstil.

1

Sie sind fast da, Sie haben die Koordinaten der Begrenzungsbox des Pfeils, der die Box mit dem Pfeil als Diagonale gezeichnet ist. Von diesem können wir die Kopf-/Endkoordinaten finden.

Die Bounding Box-Koordinaten sind in der Reihenfolge [[left, bottom], [right, top]] angegeben. Hier befindet sich der Pfeilkopf oben links und der Schwanz unten rechts. Wir können also zwei Linien zeichnen, um diese visuell zu markieren. Ersetzen Sie diesen Abschnitt in Ihrem Code mit diesem:

from matplotlib.lines import Line2D 
dl = 0.01 # some arbitrary length for the marker line 
head = [leader_line_box.T[0][0], leader_line_box.T[1][1]] 
line_head = Line2D([head[0],head[0]+dl], [head[1],head[1]+dl], 
    transform=fig.transFigure, lw=2, color='r') # mark head with red 
ax.add_line(line_head) 

tail = [leader_line_box.T[0][1], leader_line_box.T[1][0]] 
line_tail = Line2D([tail[0],tail[0]+dl], [tail[1],tail[1]+dl], 
    transform=fig.transFigure, lw=2, color='g') # mark tail with green 
ax.add_line(line_tail) 

Ergebnisse in der folgenden Handlung:

plot with arrow head and tail marked

Verwandte Themen