automatically position text box in matplotlib automatically position text box in matplotlib python python

automatically position text box in matplotlib


Just use annotate and specify axis coordinates. For example, "upper left" would be:

plt.annotate('Something', xy=(0.05, 0.95), xycoords='axes fraction')

You could also get fancier and specify a constant offset in points:

plt.annotate('Something', xy=(0, 1), xytext=(12, -12), va='top'             xycoords='axes fraction', textcoords='offset points')

For more explanation see the examples here and the more detailed examples here.


I'm not sure if this was available when I originally posted the question but using the loc parameter can now actually be used. Below is an example:

import numpy as npimport matplotlib.pyplot as pltfrom matplotlib.offsetbox import AnchoredText# make some datax = np.arange(10)y = x# set up figure and axesf, ax = plt.subplots(1,1)# loc works the same as it does with figures (though best doesn't work)# pad=5 will increase the size of padding between the border and text# borderpad=5 will increase the distance between the border and the axes# frameon=False will remove the box around the textanchored_text = AnchoredText("Test", loc=2)ax.plot(x,y)ax.add_artist(anchored_text)plt.show()

enter image description here


The question is quite old but as there is no general solution to the problem till now (2019) according to Add loc=best kwarg to pyplot.text(), I'm using legend() and the following workaround to obtain auto-placement for simple text boxes:

import numpy as npimport matplotlib.pyplot as pltimport matplotlib.patches as mpl_patchesx = np.linspace(-1,1)fig, ax = plt.subplots()ax.plot(x, x*x)# create a list with two empty handles (or more if needed)handles = [mpl_patches.Rectangle((0, 0), 1, 1, fc="white", ec="white",                                  lw=0, alpha=0)] * 2# create the corresponding number of labels (= the text you want to display)labels = []labels.append("pi = {0:.4g}".format(np.pi))labels.append("root(2) = {0:.4g}".format(np.sqrt(2)))# create the legend, supressing the blank space of the empty line symbol and the# padding between symbol and label by setting handlelenght and handletextpadax.legend(handles, labels, loc='best', fontsize='small',           fancybox=True, framealpha=0.7,           handlelength=0, handletextpad=0)plt.show()

The general idea is to create a legend with a blank line symbol and to remove the resulting empty space afterwards. How to adjust the size of matplotlib legend box? helped me with the legend formatting.

Example plot with automatically positioned text box