I'm creating plots using Matplotlib that I save as SVG, export to .pdf + .pdf_tex using Inkscape, and include the .pdf_tex-file in a LaTeX document.
This means that I can input LaTeX-commands in titles, legends etc., giving an image like this
which renders like this when I use it in my LaTeX document. Notice that the font for the numbers on the axes change, and the LaTeX-code in the legend is compiled:
Code for the plot (how to export to SVG not shown here, but can be shown on request):
import numpy as np x = np.linspace(0,1,100) y = x**2 import matplotlib.pyplot as plt plt.plot(x, y, label = '{\\footnotesize \$y = x^2\$}') plt.legend(loc = 'best') plt.show()
The problem is, as you can see, that the alignment and size of the box around the legend is wrong. This is because the size of the text of the label changes when the image is passed through Inkscape + pdflatex (because \footnotesize
etc. disappears, and the font size changes).
I have figured out that I can choose the placement of the label by either
plt.label(loc = 'upper right')
or if I want more control I can use
plt.label(bbox_to_anchor = [0.5, 0.2])
but I haven't found any way of making the box around the label smaller. Is this possible?
An alternative to making the box smaller is to remove the outline of the box using something like
legend = plt.legend() legend.get_frame().set_edgecolor('1.0')
and then moving the label to where I want it. In that case I would like to be able to set the placement of the label by first letting python/matplotlib place it using
plt.label(loc = 'upper right')
and then for example moving it a bit to the right. Is this possible? I have tried using get_bbox_to_anchor()
and set_bbox_to_anchor()
, but can't seem to get it to work.
To place a legend on the figure and to adjust the size of legend box, use borderpad=2 in legend() method. To display the figure, use show() method.
To change the position of a legend in Matplotlib, you can use the plt. legend() function. The default location is “best” – which is where Matplotlib automatically finds a location for the legend based on where it avoids covering any data points.
Select the legend box by clicking once over the legend area. A frame with 8 “handles” appears. Click on any of these handles, then hold and drag to resize the box until all labels are visible.
Click the chart, and then click the Chart Layout tab. To change the position of the legend, under Labels, click Legend, and then click the legend position that you want. To change the format of the legend, under Labels, click Legend, click Legend Options, and then make the format changes that you want.
You can move a legend after automatically placing it by drawing it, and then getting the bbox position. Here's an example:
import matplotlib.pyplot as plt import numpy as np # Plot data x = np.linspace(0,1,100) y = x**2 fig = plt.figure() ax = fig.add_subplot(221) #small subplot to show how the legend has moved. # Create legend plt.plot(x, y, label = '{\\footnotesize \$y = x^2\$}') leg = plt.legend( loc = 'upper right') plt.draw() # Draw the figure so you can find the positon of the legend. # Get the bounding box of the original legend bb = leg.get_bbox_to_anchor().inverse_transformed(ax.transAxes) # Change to location of the legend. xOffset = 1.5 bb.x0 += xOffset bb.x1 += xOffset leg.set_bbox_to_anchor(bb, transform = ax.transAxes) # Update the plot plt.show()
You may use the bbox_to_anchor
and bbox_transform
parameters to help you setting the anchor for your legend:
ax = plt.gca() plt.legend(bbox_to_anchor=(1.1, 1.1), bbox_transform=ax.transAxes)
Note that (1.1, 1.1)
are in the axes coordinates in this example. If you wish to use the data coordinates you have to use bbox_transform=ax.transData
instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With