Tan*_*ngo 5 python axes matplotlib
有没有人知道扩大绘图区域以包含注释的简单方法?我有一个图形,其中一些标签是长和/或多线字符串,而不是将它们剪切到轴,我想扩展轴以包括注释.
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)
Run Code Online (Sandbox Code Playgroud)
小智 9
我也为此苦苦挣扎。关键是 matplotlib 在实际绘制之前不会确定文本的大小。所以你需要显式调用plt.draw(),然后调整你的边界,然后再次绘制它。
根据文档get_window_extent,该方法应该在显示坐标中给出答案,而不是数据坐标。但是如果画布还没有被绘制,它似乎会响应你在关键字参数中指定的任何坐标系。这就是为什么您上面的代码可以使用,而不是.textcoordsannotatetextcoords='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)
Run Code Online (Sandbox Code Playgroud)
array([ 12. , -5. , 42.84375, 5. ])
Run Code Online (Sandbox Code Playgroud)
我们想要更改限制,以便文本标签位于轴内。bbox给定的值没有太大帮助:因为它是相对于标记点的点数:在 x 中偏移 12 点,一个字符串显然会长 30 点多一点,10 点字体(-5 到 5 英寸) y)。弄清楚如何从那里到达一组新的轴边界是很重要的。
但是,如果我们在绘制它之后再次调用该方法,我们会得到一个完全不同的 bbox:
bbox = label.get_window_extent(plt.gcf().canvas.get_renderer())
print(bbox.extents)
Run Code Online (Sandbox Code Playgroud)
现在我们得到
array([ 578.36666667, 216.66666667, 609.21041667, 226.66666667])
Run Code Online (Sandbox Code Playgroud)
这是在显示坐标中,我们可以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()
Run Code Online (Sandbox Code Playgroud)
请注意,在绘制一次绘图后不再需要显式传递plt.gcf().canvas.get_renderer()到get_window_extent。此外,我使用的是update_datalim代替xlim和ylim直接,以便自动缩放可以自动将自身调整为整数。
我贴在笔记本格式这个答案在这里。