Python:将文本框固定在角落并正确对齐 [英] Python: position text box fixed in corner and correctly aligned
问题描述
我正在尝试模仿 matplotlib.pyplot
中的 legend
方法,其中可以使用 loc='lower right'
来定位图例框固定并正确对齐,无论框的轴和内容如何.
使用 text
已经用完了,因为这需要手动输入坐标,而我需要一些自动的东西.
我尝试使用 )
将matplotlib.pyplot导入为plt导入 matplotlib.offsetbox 作为 offsetbox# 在文本框中定义一些名称和变量.xn, yn, cod = 'r', 'p', 'abc'预 = 5ccl = [546.35642, 6785.35416]ect = [12.5235, 13.643241]无花果= plt.figure()ax = fig.add_subplot(111)ax.axis([-1,10,-1,1])# 生成要写入的文本.text1 = "${}_{{t}} = {:.{p}f} \pm {:.{p}f}\; {c}$".format(xn, ccl[0],ect [0],c = cod,p = prec)text2 ="$ {} _ {{t}} = {:.{p} f} \ pm {:.{p} f} \; {c} $".format(yn,ccl [1],ect [1],c = cod,p = prec)文本 = 文本 1 + '\n' + 文本 2ob = offsetbox.AnchoredText(text,loc = 1)ax.add_artist(ob)plt.show()
一个缺点是,调整结果的字体和框参数有点违反直觉.AnchoredText
接受字体参数字典作为 prop
kwarg.初始化后,可以通过 patch
属性调整该框.举个简单的例子:
ob = offsetbox.AnchoredText(text,loc = 1,prop = dict(color ='white',size = 20))ob.patch.set(boxstyle ='round',color ='blue',alpha = 0.5)ax.add_artist(ob)
I'm trying to mimic the legend
method in matplotlib.pyplot
where one can use loc='lower right'
to position the legend box fixed and properly aligned no matter the axis and the content of the box.
Using text
is out since this requires the manual input of the coordinates and I'm after something automatic.
I've tried using annotate and it gets me half the way there, but it still won't work right.
This is what I have so far:
import matplotlib.pyplot as plt
# Define some names and variables to go in the text box.
xn, yn, cod = 'r', 'p', 'abc'
prec = 2
ccl = [546.35642, 6785.35416]
ect = [12.5235, 13.643241]
fig = plt.figure()
ax = fig.add_subplot(111)
plt.xlim(-1., 10.)
plt.ylim(-1., 1.)
# Generate text to write.
text1 = "${}_{{t}} = {:.{p}f} \pm {:.{p}f}\; {c}$".format(xn, ccl[0],
ect[0], c=cod, p=prec)
text2 = "${}_{{t}} = {:.{p}f} \pm {:.{p}f}\; {c}$".format(yn, ccl[1],
ect[1], c=cod, p=prec)
text = text1 + '\n' + text2
ax.annotate(text, xy=(0.75, 0.9), xycoords='axes fraction', fontsize=10,
bbox=dict(facecolor='white', alpha=0.8),
horizontalalignment='left', verticalalignment='bottom')
plt.savefig('annotate_test.png', dpi=150)
which results in:
This will correctly scale for changing axis limits, but the problem is that: 1- it will fail if the axis are set to ax.set_aspect('equal')
:
and 2- it will fail if the text is too long (here I set prec=5
in the MWE above):
How can I tell matplotlib
to position the text box always in the top right corner and align it properly so it doesn't fall outside of the image (ie: what loc
does in legend
)?
The quick-and-dirty way is to use right and top aligned text and place it at a fixed offset in points from the axes corner:
import matplotlib.pyplot as plt
# Define some names and variables to go in the text box.
xn, yn, cod = 'r', 'p', 'abc'
prec = 2
ccl = [546.35642, 6785.35416]
ect = [12.5235, 13.643241]
fig = plt.figure()
ax = fig.add_subplot(111)
ax.axis([-1, 10, -1, 1])
# Generate text to write.
text1 = "${}_{{t}} = {:.{p}f} \pm {:.{p}f}\; {c}$".format(xn, ccl[0],
ect[0], c=cod, p=prec)
text2 = "${}_{{t}} = {:.{p}f} \pm {:.{p}f}\; {c}$".format(yn, ccl[1],
ect[1], c=cod, p=prec)
text = text1 + '\n' + text2
ax.annotate(text, xy=(1, 1), xytext=(-15, -15), fontsize=10,
xycoords='axes fraction', textcoords='offset points',
bbox=dict(facecolor='white', alpha=0.8),
horizontalalignment='right', verticalalignment='top')
plt.show()
Because we've specified top and right alignment, it works with your two edge cases:
The downside of this is that the text is right-aligned. Ideally, you'd want the text alignment to be separate from the box alignment. The matplotlib.offsetbox
module has a number of methods to handle things like this.
If you want to mimic a legend box (down to the location codes), have a look at matplotlib.offsetbox.AnchoredText
. (Note that you can adjust the padding, etc though the pad
and borderpad
kwargs: http://matplotlib.org/api/offsetbox_api.html#matplotlib.offsetbox.AnchoredOffsetbox )
import matplotlib.pyplot as plt
import matplotlib.offsetbox as offsetbox
# Define some names and variables to go in the text box.
xn, yn, cod = 'r', 'p', 'abc'
prec = 5
ccl = [546.35642, 6785.35416]
ect = [12.5235, 13.643241]
fig = plt.figure()
ax = fig.add_subplot(111)
ax.axis([-1, 10, -1, 1])
# Generate text to write.
text1 = "${}_{{t}} = {:.{p}f} \pm {:.{p}f}\; {c}$".format(xn, ccl[0],
ect[0], c=cod, p=prec)
text2 = "${}_{{t}} = {:.{p}f} \pm {:.{p}f}\; {c}$".format(yn, ccl[1],
ect[1], c=cod, p=prec)
text = text1 + '\n' + text2
ob = offsetbox.AnchoredText(text, loc=1)
ax.add_artist(ob)
plt.show()
One downside to this is that adjusting the font and box parameters for the result is a bit counter-intuitive. AnchoredText
accepts a dictionary of font parameters as the prop
kwarg. The box can be adjusted after initialization through the patch
attribute. As a quick example:
ob = offsetbox.AnchoredText(text, loc=1,
prop=dict(color='white', size=20))
ob.patch.set(boxstyle='round', color='blue', alpha=0.5)
ax.add_artist(ob)
这篇关于Python:将文本框固定在角落并正确对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!