Python: position text box fixed in corner and correctly aligned -
i'm trying mimic legend
method in matplotlib.pyplot
1 can use loc='lower right'
position legend box fixed , aligned no matter axis , content of box.
using text
out since requires manual input of coordinates , i'm after automatic.
i've tried using annotate , gets me half way there, still won't work right.
this have far:
import matplotlib.pyplot plt # define names , variables go in 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 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 correctly scale changing axis limits, problem that: 1- fail if axis set ax.set_aspect('equal')
:
and 2- fail if text long (here set prec=5
in mwe above):
how can tell matplotlib
position text box always in top right corner , align properly doesn't fall outside of image (ie: loc
in legend
)?
the quick-and-dirty way use right , top aligned text , place @ fixed offset in points axes corner:
import matplotlib.pyplot plt # define names , variables go in 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 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 , right alignment, works 2 edge cases:
the downside of text right-aligned. ideally, you'd want text alignment separate box alignment. matplotlib.offsetbox
module has number of methods handle things this.
if want mimic legend box (down location codes), have @ matplotlib.offsetbox.anchoredtext
. (note can adjust padding, etc though pad
, borderpad
kwargs: http://matplotlib.org/api/offsetbox_api.html#matplotlib.offsetbox.anchoredoffsetbox )
import matplotlib.pyplot plt import matplotlib.offsetbox offsetbox # define names , variables go in 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 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 adjusting font , box parameters result bit counter-intuitive. anchoredtext
accepts dictionary of font parameters prop
kwarg. box can adjusted after initialization through patch
attribute. 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)
Comments
Post a Comment