2016-08-09 442 views
0

ich einen Text in einer Form das Hinzufügen von: ax.text(x,y,'text', ha='center', va='center',bbox=dict(boxstyle='circle', fc="w", ec="k"),fontsize=10) (ax ist AxesSubplot)matplotlib - Auto-Size-Text nach Formgröße

Das Problem ist, dass ich nicht die Kreisgröße konstant machen könnte, während die Veränderung String-Länge. Ich möchte die Textgröße an die Kreisgröße anpassen und nicht umgekehrt. Der Kreis ist sogar komplett verschwunden, wenn die Zeichenfolge leer ist.

Die einzige Umgehung zu dem Problem, das ich gefunden habe, ist dynamisch den Schriftgröße Param entsprechend der Länge der Zeichenfolge festlegen, aber das ist zu hässlich und nicht immer noch die Kreisgröße ist nicht vollständig konstant.

EDIT (Hinzufügen eines MVCE):

import matplotlib.pyplot as plt 

fig = plt.figure() 
ax = fig.add_axes([0,0,1,1]) 

ax.text(0.5,0.5,'long_text', ha='center', va='center',bbox=dict(boxstyle='circle', fc="w", ec="k"),fontsize=10) 
ax.text(0.3,0.7,'short', ha='center', va='center',bbox=dict(boxstyle='circle', fc="w", ec="k"),fontsize=10) 

plt.show() 

die gleiche Größe haben beide Kreise zu machen versucht, obwohl die Zeichenfolge Len unterscheidet. Derzeit sieht wie folgt aus:

enter image description here

+2

sollten Sie eine [MCVE] (http://stackoverflow.com/help/mcve) hinzuzufügen. – Gabriel

+0

@ Gabriel, Hinzugefügt, danke. – gitewexed

Antwort

0

Ich habe eine sehr schmutzig und Hard-Core-Lösung, die sehr tiefe Kenntnis der matplotlib erfordert. Es ist nicht perfekt, aber könnte Ihnen einige Ideen geben, wie Sie anfangen können.

import matplotlib.pyplot as plt 
from matplotlib.patches import Circle 
import numpy as np 
plt.close('all') 

fig, ax = plt.subplots(1, 1, figsize=(8, 8)) 

t1 = ax.text(0.5,0.5,'long_text', ha='center', va='center',fontsize=10) 
t2 = ax.text(0.3,0.7,'short', ha='center', va='center', fontsize=10) 
t3 = ax.text(0.1,0.7,'super-long-text-that-is-long', ha='center', va='center', fontsize=10) 

fig.show() 

def text_with_circle(text_obj, axis, color, border=1.5): 
    # Get the box containing the text 
    box1 = text_obj.get_window_extent() 
    # It turned out that what you get from the box is 
    # in screen pixels, so we need to transform them 
    # to "data"-coordinates. This is done with the 
    # transformer-function below 
    transformer = axis.transData.inverted().transform 
    # Now transform the corner coordinates of the box 
    # to data-coordinates 
    [x0, y0] = transformer([box1.x0, box1.y0]) 
    [x1, y1] = transformer([box1.x1, box1.y1]) 
    # Find the x and y center coordinate 
    x_center = (x0+x1)/2. 
    y_center = (y0+y1)/2. 
    # Find the radius, add some extra to make a nice border around it 
    r = np.max([(x1-x0)/2., (y1-y0)/2.])*border 
    # Plot the a circle at the center of the text, with radius r. 
    circle = Circle((x_center, y_center), r, color=color) 
    # Add the circle to the axis. 
    # Redraw the canvas. 
    return circle 

circle1 = text_with_circle(t1, ax, 'g') 
ax.add_artist(circle1) 

circle2 = text_with_circle(t2, ax, 'r', 5) 
ax.add_artist(circle2) 

circle3 = text_with_circle(t3, ax, 'y', 1.1) 
ax.add_artist(circle3) 

fig.canvas.draw() 

Im Moment Sie dies in ipython laufen müssen, weil die Figur, bevor Sie werden muss get_window_extent() gezogen. Daher muss die fig.show() aufgerufen werden NACHDEM der Text hinzugefügt wird, aber VOR dem Kreis kann gezeichnet werden! Dann können wir die Koordinaten des Textes ermitteln, herausfinden, wo die Mitte ist und einen Kreis um den Text mit einem bestimmten Radius einfügen. Wenn dies erledigt ist, ziehen wir die Leinwand neu, um sie mit dem neuen Kreis zu aktualisieren. Natürlich können Sie den Kreis viel mehr anpassen (Kantenfarbe, Gesichtsfarbe, Linienbreite, etc.), schauen Sie in the Circle class.

Ausgabebeispiel Grundstück: enter image description here

+0

Der "richtige" Weg, dies zu tun, ist die Größe _at_ draw time zu berechnen, was mpl intern tut. – tacaswell

+0

@tcaswell Ich erkannte tatsächlich, dass ich die Frage des OP nicht beantwortete. Es hieß "Versuche, beide Kreise gleich groß zu machen, obwohl die Zeichenfolge anders ist." Ich werde eine neue Lösung finden, wenn ich heute nach Hause komme. – pathoren

+0

ha, ich habe deine Antwort gelesen und auch die Frage nicht sorgfältig gelesen. – tacaswell