有谁知道一个简单的方法来扩大绘图区,包括注解? 我有一个数字,其中有些标签很长和/或多个字符串,而非剪裁这些到轴,我想扩大轴,包括注释。
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()
然后调整自己的边界,然后再绘制它。
该get_window_extent
方法应该得到在显示坐标,而不是数据坐标的答案,每文档 。 但是,如果画布还没有被抽的是,它似乎什么坐标系统,你在指定的响应textcoords
关键字参数来annotate
。 这就是为什么你上面的代码工作使用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)
array([ 12. , -5. , 42.84375, 5. ])
我们希望改变的限制使得文本标签是轴内。 值bbox
给出的是没有太大的帮助:因为这是在点相对于标记点:通过在X 12分,一个字符串偏移显然会稍微超过30分长,在10点字体(-5至5在Y)。 这是平凡弄清楚如何从那里得到一组新轴界。
但是,如果我们再现在我们已经绘制它调用该方法,我们得到了一个完全不同的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()
注意它不再需要明确地传递plt.gcf().canvas.get_renderer()
来get_window_extent
情节已经绘一次之后。 另外,我使用update_datalim
代替xlim
和ylim
直接,从而使自动缩放可以自动缺口本身长达一个整数。
我贴在笔记本格式这个答案在这里 。
对我来说tight_layout
通常解决了这个问题,但在某些情况下,我不得不使用“手动”调整与subplots_adjust ,就像这样:
fig = plt.figure()
fig.subplots_adjust(bottom=0.2, top=0.12, left=0.12, right=0.1)
这些数字通常不会发生巨大的变化,这样就可以解决这些问题而不是试图从实际的情节来计算。
BTW,设置XLIM,你在你的例子做只会改变你绘制的数据,而不是周围的所有标签的白色区域的范围。
在matplotlib1.1
的tight_layout
的引入解决了一些布局问题。 有一个很好的教程在这里 。