matplotlib - 根据形状大小

时间:2016-08-09 15:33:34

标签: python matplotlib

我通过以下方式在形状中添加文字: ax.text(x,y,'text', ha='center', va='center',bbox=dict(boxstyle='circle', fc="w", ec="k"),fontsize=10)(ax是AxesSubplot)

问题在于,在更改字符串长度时,我无法使圆的大小保持不变。我希望文字大小调整为圆形大小,而不是相反。 如果字符串是空的,则圆圈甚至完全消失。

我发现问题的唯一障碍是动态地根据字符串的len设置fontsize参数,但这太难看了,而且圆形大小不是完全不变的。

编辑(添加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()

虽然字符串len不同,但尝试使两个圆圈的大小相同。目前看起来像这样:

enter image description here

1 个答案:

答案 0 :(得分:0)

我有一个非常肮脏和硬核的解决方案,需要非常深入的matplotlib知识。它并不完美,但可能会给你一些如何开始的想法。

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

目前你必须在ipython中运行它,因为必须在get_window_extent()之前绘制图形。因此,在添加文本之后必须调用fig.show(),但在绘制圆之前!然后我们可以得到文本的坐标,找出中间的位置,并在文本周围添加一个半径的圆圈。完成后,我们重绘画布以使用新圆圈进行更新。当然,您可以更多地定制圆圈(边缘颜色,面部颜色,线宽等),查看the Circle class

输出图示例: enter image description here