gpt4 book ai didi

python - matplotlib 自动缩放轴以包含注释

转载 作者:太空狗 更新时间:2023-10-30 01:03:05 24 4
gpt4 key购买 nike

有谁知道扩展绘图区域以包含注释的简单方法?我有一个图,其中一些标签是长字符串和/或多行字符串,而不是将它们剪裁到轴上,我想扩展轴以包含注释。

Autoscale_view 不会这样做,而 ax.relim 不会选取注释的位置,因此这似乎不是一个选项。

我尝试做类似下面代码的事情,它循环遍历所有注释(假设它们在数据坐标中)以获取它们的范围,然后相应地更新轴,但理想情况下我不希望我的注释在数据坐标(它们偏离实际数据点)。

xmin, xmax = plt.xlim()
ymin, ymax = plt.ylim()
# expand figure to include labels
for l in my_labels:
# get box surrounding text, in data coordinates
bbox = l.get_window_extent(renderer=plt.gcf().canvas.get_renderer())
l_xmin, l_ymin, l_xmax, l_ymax = bbox.extents
xmin = min(xmin, l_xmin); xmax = max(xmax, l_xmax); ymin = min(ymin, l_ymin); ymax = max(ymax, l_ymax)
plt.xlim(xmin, xmax)
plt.ylim(ymin, ymax)

最佳答案

我也遇到过这个问题。关键是 matplotlib 在实际绘制文本之前不会确定文本的大小。所以你需要显式调用 plt.draw(),然后调整你的边界,然后再次绘制它。

根据 documentationget_window_extent 方法应该在显示坐标而不是数据坐标中给出答案。 .但是,如果尚未绘制 Canvas ,它似乎会在您在 annotatetextcoords 关键字参数中指定的任何坐标系中做出响应。这就是为什么您上面的代码使用 textcoords='data' 而不是 'offset points' 的原因。

这是一个例子:

x = np.linspace(0,360,101)
y = np.sin(np.radians(x))

line, = plt.plot(x, y)
label = plt.annotate('finish', (360,0),
xytext=(12, 0), textcoords='offset points',
ha='left', va='center')

bbox = label.get_window_extent(plt.gcf().canvas.get_renderer())
print(bbox.extents)

plot with annotation clipped

array([ 12.     ,  -5.     ,  42.84375,   5.     ])

我们想要更改限制,使文本标签位于轴内。给定的 bbox 的值没有多大帮助:因为它是相对于标记点的点:在 x 中偏移 12 点,一个字符串显然会超过 30 点长,在 10点字体(y 中的 -5 到 5)。弄清楚如何从那里到达一组新的轴边界并非易事。

但是,如果我们在绘制完成后再次调用该方法,我们会得到一个完全不同的 bbox:

bbox = label.get_window_extent(plt.gcf().canvas.get_renderer())
print(bbox.extents)

现在我们得到

array([ 578.36666667,  216.66666667,  609.21041667,  226.66666667])

这是在显示坐标中,我们可以像以前一样使用 ax.transData 对其进行转换。所以为了让我们的标签进入边界,我们可以这样做:

x = np.linspace(0,360,101)
y = np.sin(np.radians(x))

line, = plt.plot(x, y)
label = plt.annotate('finish', (360,0),
xytext=(8, 0), textcoords='offset points',
ha='left', va='center')

plt.draw()
bbox = label.get_window_extent()

ax = plt.gca()
bbox_data = bbox.transformed(ax.transData.inverted())
ax.update_datalim(bbox_data.corners())
ax.autoscale_view()

fixed plot

请注意,在绘图绘制一次后,不再需要显式将 plt.gcf().canvas.get_renderer() 传递给 get_window_extent。另外,我直接使用 update_datalim 而不是 xlimylim,这样自动缩放就可以自动将自身调整为一个整数。

我以笔记本格式发布了这个答案 here .

关于python - matplotlib 自动缩放轴以包含注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11545062/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com