2017-06-26 1 views
1

Ich versuche Text auf Achsen zu zeichnen und diesen Text auf einen Kreis auszurichten.Text mit Achsen annotieren und als Kreis ausrichten

Genauer gesagt gibt es Punkte mit unterschiedlichen Koordinaten optimiert (x, y), die innerhalb dieses Kreises befinden und erstellt mit:

ax.scatter(x,y,s=100) 

Ich möchte jeden Punkt (Cnameb) mit dem Kreis verbinden und beschriften. Die Koordinaten des Textes sind mit (xp, yp) definiert.

So sind die Pfeile zwischen den Punkten und dem Kreis unterschiedlich lang, aber der Gesamtabstand zwischen dem Mittelpunkt und dem Kreis ist der gleiche wie in der folgenden Abbildung -> (Hinweis: die blauen Linien sind die Linien, die sein sollten . zwischen den Punkten und dem Kreis gedruckt die roten Linien sind nur zur Veranschaulichung.):

Approach

da ich den Radius definiert haben und ich weiß, um die Koordinaten der Punkte als auch die Koordinaten des Mittelpunktes Ich sollte die folgenden Schritte ausführen können:

  1. den Abstand DxMP zwischen den einzelnen Punkten berechnen und das Zentrum
  2. den Abstand zwischen den den einzelnen Punkten berechnen und den Kreis
  3. Berechnen den Winkel alpha
  4. die Punkte xp und yp berechnen, die die Koordinaten der sollte Text (die Koordinaten auf dem Kreis)

Darum habe ich den folgenden Code verwendet:

def legpoints(x,y): 
    DxMP = np.sqrt(((x - 521953) ** 2) + (y - 435179) ** 2)#521953, 435179 are the x and y coordinates of the center of the circle 
    DxCirc = np.sqrt((900000 - DxMP)**2)#The distance between the point x and the circle 
    alpha = np.arccos((np.sqrt((x - 521953)**2))/(DxMP)) 
    xp = x + (np.cos(alpha) * DxCirc) 
    yp = y + (np.sin(alpha) * DxCirc) 
    return xp,yp 


xp=legpoints(x,y)[0] 
yp=legpoints(x,y)[1] 

die komprimierten Daten haben die Form (Cnameb, x, y, xp, yp):

[('Berlin', 735.951,59991561132, 617.707,36153527966, 1.206.703,3293253453, 1.019.231,2121256208), ('Berlin', 735.965,58122088562, 617712,48195467936, 1206714,0793803122, 1.019.218,6083879157), ('Bremen', 425896,14258295257, 673.875,68843362806, 665.833,6191604546, 1270108,8219153266), ('Dortmund', 330.448,62508515653, 502638,58154814231, 987.816,52265995357, 734.203,8568234311), ('Duisburg', 281.456,9370223835, 495.636,46544709487, 913.803,62749559013, 654599,89177739131), ('Düsseldorf', 283.849,70917473407 , 471.649,47447504522, 935371,04632360162, 571.443,52693890885), ('Essen, Ruhr', 298590,41880710673, 497.973,49884993531, 941640,19382135477, 678.755,74152428762), ('Frankfurt am Main', 412.037,5979210182, 345.052,92773266998, 998077,35579369171, 825581,23014117288), ('Hamburg', 505.147,96843631176, 726.635,42284052074, 540.149,823586 92121, 1.333.686,6774791477), ('Hannover', 487540,73893698538, 594957,33199132804, 642.620,87620513374, 1315004,3411755674), ('Köln', 292.146,52126941859, 439.340,70884408138, 962192,49751825235, 451.474,98930779565), ('München', 623.290,92919537693, 125422,12264187855, 801795,74103644479, 671.052,90026201855), ('Stuttgart ‘, 445.743,44744934322, 196109,08652145317, 642.879,16415181267, 814.525,24510293454)]

Mit dem folgenden Code ich den Text zu den Achsen hinzufügen möchten, und allign als Kreis:

[ax.annotate(s=nme,xy=(x,y),xytext=(xpoint,ypoint),textcoords="data",arrowprops={"arrowstyle":"->"},color="black",alpha=0.8,fontsize=12) for nme,x,y,xpoint,ypoint in zip(Cnameb,x,y,xp,yp)] 

aber das Ergebnis ist nicht so, da die gewünschte Text ist nicht als Kreis, sondern undefiniert ....

Kann mir bitte jemand helfen ...?

Antwort

1

Ich sehe nicht, was die Entfernung in der Gleichung tun würde. Sie möchten den Punkt ermitteln, an dem die Annotation platziert werden soll, und diesen Punkt der Annotationsfunktion zuweisen.

import numpy as np 
import matplotlib.pyplot as plt 

texts=["Dresden","Berlin", "Freiburg"] 
xy = np.array([[3.5,1],[3.,2.],[0,-2]]) 

center = np.array([1.,1.]) 
radius = 5 # radius 

x,y = zip(*xy) 
cx, cy = center 
plt.scatter(x,y) 
plt.scatter(cx, cy) 

#plot a cirle 
ct = np.linspace(0,2*np.pi) 
circx, circy = radius*np.cos(ct)+cx, radius*np.sin(ct)+cy 
plt.plot(circx, circy, ls=":") 



def ann(x,y, cx, cy, r, text): 
    angle = np.arctan2(y-cy, x-cx) 
    xt, yt = r*np.cos(angle)+cx, r*np.sin(angle)+cy 
    plt.annotate(text, xy=(x,y), xytext=(xt, yt), arrowprops={"arrowstyle":"->"}) 
    plt.scatter(xt, yt, c=0) 

for t, xi,yi in zip(texts, x,y): 
    ann(xi,yi, cx, cy, radius, t) 

plt.gca().set_aspect("equal") 
plt.show() 

enter image description here

+0

Vielen Dank, das ist es! Ich habe den Fehler gemacht, die Pfeile von innen nach außen zu zeichnen und nicht umgekehrt, aber das ist viel besser. – 2Obe

+1

Das hat nichts mit der Richtung der Pfeile zu tun. Sie können '" arrowstyle ":" <- "' anstelle von '" arrowstyle ":" -> "' verwenden, um die Richtung zu ändern. – ImportanceOfBeingErnest