有没有人知道一个简单的方法来扩展绘图区域以包括注解?我有一个图,其中一些标签是长的和/或多行字符串,而不是将这些裁剪到轴上,我想扩展轴以包括注解。
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)
4条答案
按热度按时间gev0vcfq1#
我也很纠结这个问题,关键是matplotlib在实际绘制文本之前不会确定文本的大小,所以你需要显式调用
plt.draw()
,然后调整边界,然后再绘制一次。根据文档,
get_window_extent
方法应该给予显示坐标的答案,而不是数据坐标。但是如果画布还没有绘制,它似乎会在annotate
的textcoords
关键字参数中指定的任何坐标系中响应。这就是为什么上面的代码使用textcoords='data'
而不是'offset points'
工作。下面是一个示例:
我们想改变限制,使文本标签在轴内。
bbox
的值没有多大帮助:因为它是相对于标记点的点:在x轴上偏移12个点,一个长度明显超过30个点的字符串,用10磅字体(y中的-5到5)。弄清楚如何从那里得到一组新的轴边界是很重要的。然而,如果我们在绘制完这个方法后再次调用它,我们会得到一个完全不同的bbox:
现在我们得到
这是在显示坐标中,我们可以像以前一样用
ax.transData
转换。所以为了让我们的标签进入边界,我们可以这样做:请注意,在绘制一次图之后,不再需要显式地将
plt.gcf().canvas.get_renderer()
传递给get_window_extent
。此外,我使用update_datalim
而不是直接使用xlim
和ylim
,以便自动缩放可以自动将其本身标记为一个整数。我以笔记本格式here发布了这个答案。
q0qdq0h22#
对我来说,
tight_layout
通常可以解决这个问题,但在某些情况下,我不得不使用subplots_adjust进行“手动”调整,如下所示:这些数字通常不会发生显著变化,因此您可以修复它们,而不是尝试从实际图中计算。
顺便说一句,像您在示例中所做的那样设置xlim只会更改您绘制的数据范围,而不会更改所有标签周围的白色区域。
wi3ka0sx3#
在
matplotlib1.1
中引入tight_layout
来解决一些布局问题。这里有一个很好的教程。2w3kk1z54#
matplotlib不把annotation / text当作数据。所以默认的
autoscale
不能正常工作。我的快速解决方案可以手动设置边距。ax.margin(0.2)
可以增加用于注解的边距空间。