在矩形内创建文本,缩小时消失

Creating a text inside a rectangle disappearing when zooming out

提问人:BayerIntern 提问时间:11/14/2023 最后编辑:Trenton McKinneyBayerIntern 更新时间:11/16/2023 访问量:91

问:

我想使用 matplotlib 为甘特图创建一个带有文本的矩形。但是,如果要放大和缩小,则文本不应大于矩形。因此,一旦文本(具有固定字体大小)大于矩形,它就会消失,并且当它再次变小时(放大),它应该再次出现。

这是一个简单文本的示例,其问题是文本在缩放时不会停留在矩形内(一旦变大就不会消失)。

from matplotlib import pyplot as plt, patches
plt.rcParams["figure.figsize"] = [7.00, 3.50]
plt.rcParams["figure.autolayout"] = True
fig = plt.figure()
ax = fig.add_subplot(111)
rectangle = patches.Rectangle((0, 0), 3, 3, edgecolor='orange',
facecolor="green", linewidth=7)
ax.add_patch(rectangle)
rx, ry = rectangle.get_xy()
cx = rx + rectangle.get_width()/2.0
cy = ry + rectangle.get_height()/2.0
ax.annotate("Rectangle", (cx, cy), color='black', weight='bold', fontsize=10, ha='center', va='center')
plt.xlim([-5, 5])
plt.ylim([-5, 5])
plt.show()

文本现在应该消失了

Text should disappear now

python matplotlib 文本 矩形

评论


答:

0赞 simon 11/14/2023 #1

若要监视绘图的缩放状态,可以连接到 Axes 类的“xlim_changed”和“ylim_changed”事件。除了缩放状态外,您可能还想考虑图形大小的变化,您可以通过图形画布的“resize_event”进行监控。

下面,我调整了你的代码,以便

  • 文本被隐藏,只要你的 X 限制 wrt 的比率。图高度或 y 极限的比率 wrt。图形宽度是原始值的两倍以上(宽度为 2·10/7,高度为 2·10/3.5,其中 10 是下限 -5 和上限 5 之间的距离,2 是给定示例中似乎产生良好结果的值)——这个比率很重要, 以便您对矩形屏幕大小的实际变化做出反应,而不是对图像坐标中的大小做出反应;
  • 一旦比率小于原始比率的两倍,文本就会再次显示。
from matplotlib import pyplot as plt, patches

plt.rcParams["figure.figsize"] = [7.00, 3.50]
plt.rcParams["figure.autolayout"] = True
fig = plt.figure()
ax = fig.add_subplot(111)
rectangle = patches.Rectangle((0, 0), 3, 3, edgecolor="orange",
                              facecolor="green", linewidth=7)
ax.add_patch(rectangle)
rx, ry = rectangle.get_xy()
cx = rx + rectangle.get_width()/2.0
cy = ry + rectangle.get_height()/2.0
annotation = ax.annotate("Rectangle", (cx, cy), color="black", weight="bold",
                         fontsize=10, ha="center", va="center")

def on_size_change(*unused_events):
    xlim, ylim, figsize = ax.get_xlim(), ax.get_ylim(), fig.get_size_inches()
    x_ratio = (xlim[1] - xlim[0]) / figsize[0]  # xlim dist. over fig. width
    y_ratio = (ylim[1] - ylim[0]) / figsize[1]  # ylim dist. over fig. height
    visible = x_ratio <= 20 / 7. and y_ratio <= 20 / 3.5
    annotation.set_visible(visible)

ax.callbacks.connect("xlim_changed", on_size_change)
ax.callbacks.connect("ylim_changed", on_size_change)
fig.canvas.mpl_connect("resize_event", on_size_change)

plt.xlim([-5, 5])
plt.ylim([-5, 5])
plt.show()

或者,您可能希望使文本的显示和隐藏直接取决于矩形的屏幕大小(只要矩形的宽度和高度都大于文本的宽度和高度,就显示文本)。在这种情况下,您可能需要按如下方式调整函数:on_size_change()

def on_size_change(*unused_events):
    annotation.set_visible(True)  # Text must be visible to get correct size
    rct_box = rectangle.get_window_extent()
    txt_box = annotation.get_window_extent()
    visible = rct_box.width > txt_box.width and rct_box.height > txt_box.height
    annotation.set_visible(visible)

这可能还不完美,但我希望它能让您了解如何进行。

评论

0赞 BayerIntern 11/16/2023
多谢!您展示的解决方案是满足我需求的完美基础。
0赞 simon 11/16/2023
@BayerIntern 不客气!:)