Python:将文本框固定在角落并正确对齐 [英] Python: position text box fixed in corner and correctly aligned

查看:35
本文介绍了Python:将文本框固定在角落并正确对齐的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试模仿 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆