By pottigopi

2011-01-15 16:10:03 8 Comments

I have a series of 20 plots (not subplots) to be made in a single figure. I want the legend to be outside of the box. At the same time, I do not want to change the axes, as the size of the figure gets reduced. Kindly help me for the following queries:

  1. I want to keep the legend box outside the plot area. (I want the legend to be outside at the right side of the plot area).
  2. Is there anyway that I reduce the font size of the text inside the legend box, so that the size of the legend box will be small.


@Navi 2011-01-15 16:21:37

import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties

fontP = FontProperties()

p1, = plt.plot([1, 2, 3], label='Line 1')
p2, = plt.plot([3, 2, 1], label='Line 2')
plt.legend(handles=[p1, p2], title='title', bbox_to_anchor=(1.05, 1), loc='upper left', prop=fontP)

enter image description here

  • As noted by Mateen Ulhaq, fontsize='xx-small' also works, without importing FontProperties.
plt.legend(handles=[p1, p2], title='title', bbox_to_anchor=(1.05, 1), loc='upper left', fontsize='xx-small')

@Joe Kington 2011-01-15 18:12:27

There are a number of ways to do what you want. To add to what @inalis and @Navi already said, you can use the bbox_to_anchor keyword argument to place the legend partially outside the axes and/or decrease the font size.

Before you consider decreasing the font size (which can make things awfully hard to read), try playing around with placing the legend in different places:

So, let's start with a generic example:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$' % i)


alt text

If we do the same thing, but use the bbox_to_anchor keyword argument we can shift the legend slightly outside the axes boundaries:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$' % i)
ax.legend(bbox_to_anchor=(1.1, 1.05))

alt text

Similarly, you can make the legend more horizontal and/or put it at the top of the figure (I'm also turning on rounded corners and a simple drop shadow):

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    line, = ax.plot(x, i * x, label='$y = %ix$'%i)

ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.05),
          ncol=3, fancybox=True, shadow=True)

alt text

Alternatively, you can shrink the current plot's width, and put the legend entirely outside the axis of the figure (note: if you use tight_layout(), then leave out ax.set_position():

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$'%i)

# Shrink current axis by 20%
box = ax.get_position()
ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])

# Put a legend to the right of the current axis
ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))

alt text

And in a similar manner, you can shrink the plot vertically, and put the a horizontal legend at the bottom:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    line, = ax.plot(x, i * x, label='$y = %ix$'%i)

# Shrink current axis's height by 10% on the bottom
box = ax.get_position()
ax.set_position([box.x0, box.y0 + box.height * 0.1,
                 box.width, box.height * 0.9])

# Put a legend below current axis
ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.05),
          fancybox=True, shadow=True, ncol=5)

alt text

Have a look at the matplotlib legend guide. You might also take a look at plt.figlegend().

@Matthew G. 2013-02-19 23:50:28

If anyone is having issues with this, note that tight_layout() will cause issues!

@meduz 2013-10-23 09:01:34

great answer! the correct link to the doc is

@meduz 2013-10-23 09:03:22

as completeness, you could say that in general (summed up from the doc) " bbox_to_anchor is a tuple of 4 floats (x, y, width, height of the bbox), or a tuple of 2 floats (x, y) in normalized axes coordinates. "

@KT. 2017-07-18 16:15:52

I must admit this is probably my most visited SO answer ever. I just can't help coming back to it over and over because there is no way a reasonable person can remember this logic without looking it up here.

@coldfix 2017-10-05 17:30:02

Note that if you want to save the figure to a file, you should probably store the object returned, i.e. legend = ax.legend() and later fig.savefig(bbox_extra_artists=(legend,))

@Curtis 2017-11-27 16:58:06

However when I try this for individual subplots, I can't make it work! I tried all combinations, there must be something wrong I am doing fundamentally. Could you advise please? here is a snippet of my code: figure = plt.figure(1)\n figure, axisArr = plt.subplots(4, 1, figsize=(8.27, 11.70), sharex=True)\n box = axisArr[0].get_position()\n axisArr[0].set_position([box.x0, box.y0, box.width * 0.5, box.height])\n axisArr[0].legend(loc="center right", bbox_to_anchor=(1, 0.5), prop={'size': 6})

@Trevor Boyd Smith 2018-04-17 17:43:52

FYI the key thing i found in the example code is Shrink current axis by. the reason i say key is because the example documentation code DOES show something similar... but hides the whole shrink part by doing a plt.subplot(223) which effectively shrinks the plot by 50%.

@Trevor Boyd Smith 2018-04-17 17:47:48

FYI #2 - you can use plt: you can do lots of the manipulations with the usual plt but then then shrink axes part of the code you can get the current axis by doing ax = plt.gca().

@jimh 2020-05-11 10:50:00

you can just use plt.savefig(bbox_inches='tight') instead of plt.tight_layout()

@ImportanceOfBeingErnest 2017-04-16 16:04:28

##Placing the legend (bbox_to_anchor) A legend is positioned inside the bounding box of the axes using the loc argument to plt.legend.
E.g. loc="upper right" places the legend in the upper right corner of the bounding box, which by default extents from (0,0) to (1,1) in axes coordinates (or in bounding box notation (x0,y0, width, height)=(0,0,1,1)).

To place the legend outside of the axes bounding box, one may specify a tuple (x0,y0) of axes coordinates of the lower left corner of the legend.


However, a more versatile approach would be to manually specify the bounding box into which the legend should be placed, using the bbox_to_anchor argument. One can restrict oneself to supply only the (x0,y0) part of the bbox. This creates a zero span box, out of which the legend will expand in the direction given by the loc argument. E.g.

plt.legend(bbox_to_anchor=(1.04,1), loc="upper left")

places the legend outside the axes, such that the upper left corner of the legend is at position (1.04,1) in axes coordinates.

Further examples are given below, where additionally the interplay between different arguments like mode and ncols are shown.

enter image description here

l1 = plt.legend(bbox_to_anchor=(1.04,1), borderaxespad=0)
l2 = plt.legend(bbox_to_anchor=(1.04,0), loc="lower left", borderaxespad=0)
l3 = plt.legend(bbox_to_anchor=(1.04,0.5), loc="center left", borderaxespad=0)
l4 = plt.legend(bbox_to_anchor=(0,1.02,1,0.2), loc="lower left",
                mode="expand", borderaxespad=0, ncol=3)
l5 = plt.legend(bbox_to_anchor=(1,0), loc="lower right", 
                bbox_transform=fig.transFigure, ncol=3)
l6 = plt.legend(bbox_to_anchor=(0.4,0.8), loc="upper right")

Details about how to interpret the 4-tuple argument to bbox_to_anchor, as in l4, can be found in this question. The mode="expand" expands the legend horizontally inside the bounding box given by the 4-tuple. For a vertically expanded legend, see this question.

Sometimes it may be useful to specify the bounding box in figure coordinates instead of axes coordinates. This is shown in the example l5 from above, where the bbox_transform argument is used to put the legend in the lower left corner of the figure.


Having placed the legend outside the axes often leads to the undesired situation that it is completely or partially outside the figure canvas.

Solutions to this problem are:

  • Adjust the subplot parameters
    One can adjust the subplot parameters such, that the axes take less space inside the figure (and thereby leave more space to the legend) by using plt.subplots_adjust. E.g.


leaves 30% space on the right-hand side of the figure, where one could place the legend.

  • Tight layout
    Using plt.tight_layout Allows to automatically adjust the subplot parameters such that the elements in the figure sit tight against the figure edges. Unfortunately, the legend is not taken into account in this automatism, but we can supply a rectangle box that the whole subplots area (including labels) will fit into.

  • Saving the figure with bbox_inches = "tight"
    The argument bbox_inches = "tight" to plt.savefig can be used to save the figure such that all artist on the canvas (including the legend) are fit into the saved area. If needed, the figure size is automatically adjusted.

      plt.savefig("output.png", bbox_inches="tight")
  • automatically adjusting the subplot params
    A way to automatically adjust the subplot position such that the legend fits inside the canvas without changing the figure size can be found in this answer: Creating figure with exact size and no padding (and legend outside the axes)

Comparison between the cases discussed above:

enter image description here

##Alternatives A figure legend
One may use a legend to the figure instead of the axes, matplotlib.figure.Figure.legend. This has become especially useful for matplotlib version >=2.1, where no special arguments are needed


to create a legend for all artists in the different axes of the figure. The legend is placed using the loc argument, similar to how it is placed inside an axes, but in reference to the whole figure - hence it will be outside the axes somewhat automatically. What remains is to adjust the subplots such that there is no overlap between the legend and the axes. Here the point "Adjust the subplot parameters" from above will be helpful. An example:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0,2*np.pi)
colors=["#7aa0c4","#ca82e1" ,"#8bcd50","#e18882"]
fig, axes = plt.subplots(ncols=2)
for i in range(4):
    axes[i//2].plot(x,np.sin(x+i), color=colors[i],label="y=sin(x+{})".format(i))


enter image description here

Legend inside dedicated subplot axes
An alternative to using bbox_to_anchor would be to place the legend in its dedicated subplot axes (lax). Since the legend subplot should be smaller than the plot, we may use gridspec_kw={"width_ratios":[4,1]} at axes creation. We can hide the axes lax.axis("off") but still put a legend in. The legend handles and labels need to obtained from the real plot via h,l = ax.get_legend_handles_labels(), and can then be supplied to the legend in the lax subplot, lax.legend(h,l). A complete example is below.

import matplotlib.pyplot as plt
plt.rcParams["figure.figsize"] = 6,2

fig, (ax,lax) = plt.subplots(ncols=2, gridspec_kw={"width_ratios":[4,1]})
ax.plot(x,y, label="y=sin(x)")

h,l = ax.get_legend_handles_labels()
lax.legend(h,l, borderaxespad=0)


This produces a plot, which is visually pretty similar to the plot from above:

enter image description here

We could also use the first axes to place the legend, but use the bbox_transform of the legend axes,

ax.legend(bbox_to_anchor=(0,0,1,1), bbox_transform=lax.transAxes)

In this approach, we do not need to obtain the legend handles externally, but we need to specify the bbox_to_anchor argument.

###Further reading and notes:

  • Consider the matplotlib legend guide with some examples of other stuff you want to do with legends.
  • Some example code for placing legends for pie charts may directly be found in answer to this question: Python - Legend overlaps with the pie chart
  • The loc argument can take numbers instead of strings, which make calls shorter, however, they are not very intuitively mapped to each other. Here is the mapping for reference:

enter image description here

@travc 2019-06-14 20:32:02

Putting the legend in a dedicated subplot axis synergies very nicely with fig.tight_layout. If you are using plt.subplots to create the axes, just give it something like gridspec_kw={'height_ratios': [100, 1]} (or width_ratios) so the legend's axes is tiny... Then fig.tight_layout() will expand it to fit. At least for matplotlib 3.0.3.

@Ziuccia 2017-03-15 09:31:50

don't know if you already sorted out your issue...probably yes, but... I simply used the string 'outside' for the location, like in matlab. I imported pylab from matplotlib. see the code as follow:

from matplotlib as plt
from matplotlib.font_manager import FontProperties
t = A[:,0]
sensors = A[:,index_lst]

for i in range(sensors.shape[1]):

lgd = plt.legend(loc='center left', bbox_to_anchor=(1, 0.5),fancybox = True, shadow = True)

enter image description here

@jxmorris12 2020-06-11 18:12:20

This worked well for me after I removed the rogue b argument.

@JiK 2020-07-01 12:16:04

I don't understand. The code doesn't contain outside anywhere.

@luc 2020-04-05 22:16:21

It's worth refreshing this question, as newer versions of Matplotlib have made it much easier to position the legend outside the plot. I produced this example with Matplotlib version 3.1.1.

Users can pass a 2-tuple of coordinates to the loc parameter to position the legend anywhere in the bounding box. The only gotcha is you need to run plt.tight_layout() to get matplotlib to recompute the plot dimensions so the legend is visible:

import matplotlib.pyplot as plt

plt.plot([0, 1], [0, 1], label="Label 1")
plt.plot([0, 1], [0, 2], label='Label 2')

plt.legend(loc=(1.05, 0.5))

This leads to the following plot:

plot with legend outside


@dotancohen 2014-12-08 09:46:40

In addition to all the excellent answers here, newer versions of matplotlib and pylab can automatically determine where to put the legend without interfering with the plots, if possible.


This will automatically place the legend away from the data if possible! Compare the use of loc='best'

However, if there is no place to put the legend without overlapping the data, then you'll want to try one of the other answers; using loc="best" will never put the legend outside of the plot.

@Edgar H 2015-08-23 10:37:08

Thank you for pointing this out! I looked for this a few years back and didn't find it, and it something that really makes my live easier.

@Tommy 2015-09-09 12:01:46

this option is helpful but does not answer the question so i downvoted. as far as i can tell, best never puts the legend outside of the plot

@dotancohen 2015-09-09 13:19:53

@Tommy: In the OP's comments (which seems to be gone now) it was explicitly clarified that the OP wanted the legend to not cover the graph data, and he thought that outside the plot was the only way to do that. You can see this in the answers from mefathy, Mateo Sanchez, Bastiaan, and radtek. The OP asked for X, but he wanted Y.

@durbachit 2016-08-30 03:09:59

Actually, not. He/she specifically asked for the legend to be outside the plot. It's in the name of the question ;) "How to put the legend out of the plot".

@adam.r 2018-02-08 16:34:04

This does not guarantee that the legend does not obscure the data. Just make a very dense plot -- there is no place to put the legend. For example, try this... from numpy import arange, sin, pi import matplotlib.pyplot as plt t = arange(0.0, 100.0, 0.01) fig = plt.figure(1) ax1 = fig.add_subplot(211) ax1.scatter(t, sin(2*pi*t),label='test') ax1.grid(True) # ax1.set_ylim((-2, 2)) ax1.set_ylabel('1 Hz') ax1.set_title('A sine wave or two') for label in ax1.get_xticklabels(): label.set_color('r') plt.legend(loc='best')

@Christian Alis 2011-01-15 16:41:50

To place the legend outside the plot area, use loc and bbox_to_anchor keywords of legend(). For example, the following code will place the legend to the right of the plot area:

legend(loc="upper left", bbox_to_anchor=(1,1))

For more info, see the legend guide

@astromax 2015-07-05 15:28:23

Okay - I like the implementation, but when I go to save the figure (without manually resizing it in the window, which I don't want to do every time), the legend is getting chopped off. Any ideas about how I might fix that?

@Christian Alis 2015-07-05 19:07:49

@astromax I'm not sure but perhaps try calling plt.tight_layout()?

@Shital Shah 2014-07-03 02:43:20

Just call legend() call after the plot() call like this:

# matplotlib
plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))

# Pandas
df.myCol.plot().legend(loc='center left', bbox_to_anchor=(1, 0.5))

Results would look something like this:

enter image description here

@kidmose 2016-10-25 09:54:15

works when passing the same parameters to matplotlib.pyplot.legend as well

@user1717828 2019-01-25 03:01:02

Does this cut off the words in the legend for anyone else?

@ivirshup 2017-01-27 08:03:11

Here's another solution, similar to adding bbox_extra_artists and bbox_inches, where you don't have to have your extra artists in the scope of your savefig call. I came up with this since I generate most of my plot inside functions.

Instead of adding all your additions to the bounding box when you want to write it out, you can add them ahead of time to the Figure's artists. Using something similar to Franck Dernoncourt's answer above:

import matplotlib.pyplot as plt

# data 
all_x = [10,20,30]
all_y = [[1,3], [1.5,2.9],[3,2]]

# plotting function
def gen_plot(x, y):
    fig = plt.figure(1)
    ax = fig.add_subplot(111)
    ax.plot(all_x, all_y)
    lgd = ax.legend( [ "Lag " + str(lag) for lag in all_x], loc="center right", bbox_to_anchor=(1.3, 0.5))
    fig.artists.append(lgd) # Here's the change
    ax.set_xlabel("x label")
    ax.set_ylabel("y label")
    return fig

# plotting
fig = gen_plot(all_x, all_y)

# No need for `bbox_extra_artists`
fig.savefig("image_output.png", dpi=300, format="png", bbox_inches="tight")

Here's the generated plot.

@Crystal 2016-08-28 17:04:15

The solution that worked for me when I had huge legend was to use extra empty image layout. In following example I made 4 rows and at the bottom I plot image with offset for legend (bbox_to_anchor) at the top it does not get cut.

f = plt.figure()
ax = f.add_subplot(414)
lgd = ax.legend(loc='upper left', bbox_to_anchor=(0, 4), mode="expand", borderaxespad=0.3)
plt.savefig(fig_name, format='svg', dpi=1200, bbox_extra_artists=(lgd,), bbox_inches='tight')

@mefathy 2013-02-20 19:41:10

Short Answer: Invoke draggable on the legend and interactively move it wherever you want:


Long Answer: If you rather prefer to place the legend interactively/manually rather than programmatically, you can toggle the draggable mode of the legend so that you can drag it to wherever you want. Check the example below:

import matplotlib.pylab as plt
import numpy as np
#define the figure and get an axes instance
fig = plt.figure()
ax = fig.add_subplot(111)
#plot the data
x = np.arange(-5, 6)
ax.plot(x, x*x, label='y = x^2')
ax.plot(x, x*x*x, label='y = x^3')

@sb2020 2019-12-25 20:52:25

Not sure I understand this fully. How do I "drag" the legend to wherever I want with this? I am using Python 3.6 and Jupyter Notebook

@Franck Dernoncourt 2014-08-16 22:49:37

Short answer: you can use bbox_to_anchor + bbox_extra_artists + bbox_inches='tight'.

Longer answer: You can use bbox_to_anchor to manually specify the location of the legend box, as some other people have pointed out in the answers.

However, the usual issue is that the legend box is cropped, e.g.:

import matplotlib.pyplot as plt

# data 
all_x = [10,20,30]
all_y = [[1,3], [1.5,2.9],[3,2]]

# Plot
fig = plt.figure(1)
ax = fig.add_subplot(111)
ax.plot(all_x, all_y)

# Add legend, title and axis labels
lgd = ax.legend( [ 'Lag ' + str(lag) for lag in all_x], loc='center right', bbox_to_anchor=(1.3, 0.5))
ax.set_xlabel('x label')
ax.set_ylabel('y label')

fig.savefig('image_output.png', dpi=300, format='png')

enter image description here

In order to prevent the legend box from getting cropped, when you save the figure you can use the parameters bbox_extra_artists and bbox_inches to ask savefig to include cropped elements in the saved image:

fig.savefig('image_output.png', bbox_extra_artists=(lgd,), bbox_inches='tight')

Example (I only changed the last line to add 2 parameters to fig.savefig()):

import matplotlib.pyplot as plt

# data 
all_x = [10,20,30]
all_y = [[1,3], [1.5,2.9],[3,2]]

# Plot
fig = plt.figure(1)
ax = fig.add_subplot(111)
ax.plot(all_x, all_y)

# Add legend, title and axis labels
lgd = ax.legend( [ 'Lag ' + str(lag) for lag in all_x], loc='center right', bbox_to_anchor=(1.3, 0.5))
ax.set_xlabel('x label')
ax.set_ylabel('y label')    

fig.savefig('image_output.png', dpi=300, format='png', bbox_extra_artists=(lgd,), bbox_inches='tight')

enter image description here

I wish that matplotlib would natively allow outside location for the legend box as Matlab does:

x = 0:.2:12;
hleg = legend('First','Second','Third',...
% Make the text of the legend italic and color it brown

enter image description here

@Demitrian 2014-08-31 14:04:56

Thank you so much! The "bbox_to_anchor", "bbox_extra_artist" and ""bbox_inches='tight" parameters were exactly what I needed to make it work correctly. Awesome!

@avtomaton 2016-11-08 05:16:35

Thank you, but actually bbox_inches='tight' works perfectly for me even without bbox_extra_artist

@Franck Dernoncourt 2016-11-08 17:28:24

@avtomaton Thanks, good to know, which version of matplotlib do you use?

@avtomaton 2016-11-09 04:49:03

@FranckDernoncourt python3, matplotlib version 1.5.3

@radtek 2014-06-10 17:13:05

Here is an example from the matplotlib tutorial found here. This is one of the more simpler examples but I added transparency to the legend and added so you can paste this into the interactive shell and get a result:

import matplotlib.pyplot as plt
p1, = plt.plot([1, 2, 3])
p2, = plt.plot([3, 2, 1])
p3, = plt.plot([2, 3, 1])
plt.legend([p2, p1, p3], ["line 1", "line 2", "line 3"]).get_frame().set_alpha(0.5)

@Bastiaan 2014-04-17 17:27:24

Not exactly what you asked for, but I found it's an alternative for the same problem. Make the legend semi-transparant, like so: matplotlib plot with semi transparent legend and semitransparent text box

Do this with:

fig = pylab.figure()
ax = fig.add_subplot(111)
# Make the legend transparent:
# Make a transparent text box
ax.text(0.02,0.02,yourstring, verticalalignment='bottom',
                     bbox={'facecolor':'white', 'alpha':0.6, 'pad':10},

@Mateo Sanchez 2014-02-09 13:55:14

As noted, you could also place the legend in the plot, or slightly off it to the edge as well. Here is an example using the Plotly Python API, made with an IPython Notebook. I'm on the team.

To begin, you'll want to install the necessary packages:

import plotly
import math
import random
import numpy as np

Then, install Plotly:

py = plotly.plotly(username=un, key=k)

def sin(x,n):
sine = 0
for i in range(n):
    sign = (-1)**i
    sine = sine + ((x**(2.0*i+1))/math.factorial(2*i+1))*sign
return sine

x = np.arange(-12,12,0.1)

anno = {
'text': '$\\sum_{k=0}^{\\infty} \\frac {(-1)^k x^{1+2k}}{(1 + 2k)!}$',
'x': 0.3, 'y': 0.6,'xref': "paper", 'yref': "paper",'showarrow': False,

l = {
'annotations': [anno], 
'title': 'Taylor series of sine',

py.iplot([{'x':x, 'y':sin(x,1), 'line':{'color':'#e377c2'}, 'name':'$x\\\\$'},\
      {'x':x, 'y':sin(x,2), 'line':{'color':'#7f7f7f'},'name':'$ x-\\frac{x^3}{6}$'},\
      {'x':x, 'y':sin(x,3), 'line':{'color':'#bcbd22'},'name':'$ x-\\frac{x^3}{6}+\\frac{x^5}{120}$'},\
      {'x':x, 'y':sin(x,4), 'line':{'color':'#17becf'},'name':'$ x-\\frac{x^5}{120}$'}], layout=l)

This creates your graph, and allows you a chance to keep the legend within the plot itself. The default for the legend if it is not set is to place it in the plot, as shown here.

enter image description here

For an alternative placement, you can closely align the edge of the graph and border of the legend, and remove border lines for a closer fit.

enter image description here

You can move and re-style the legend and graph with code, or with the GUI. To shift the legend, you have the following options to position the legend inside the graph by assigning x and y values of <= 1. E.g :

  • {"x" : 0,"y" : 0} -- Bottom Left
  • {"x" : 1, "y" : 0} -- Bottom Right
  • {"x" : 1, "y" : 1} -- Top Right
  • {"x" : 0, "y" : 1} -- Top Left
  • {"x" :.5, "y" : 0} -- Bottom Center
  • {"x": .5, "y" : 1} -- Top Center

In this case, we choose the upper right, legendstyle = {"x" : 1, "y" : 1}, also described in the documentation:

enter image description here

@Mateen Ulhaq 2020-06-11 05:39:01

Oooh... pretty colors (in the first plot).

@Martin 2013-12-21 00:38:27

Something along these lines worked for me. Starting with a bit of code taken from Joe, this method modifies the window width to automatically fit a legend to the right of the figure.

import matplotlib.pyplot as plt
import numpy as np


x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$'%i)

# Put a legend to the right of the current axis
leg = ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))


# Get the ax dimensions.
box = ax.get_position()
xlocs = (box.x0,box.x1)
ylocs = (box.y0,box.y1)

# Get the figure size in inches and the dpi.
w, h = fig.get_size_inches()
dpi = fig.get_dpi()

# Get the legend size, calculate new window width and change the figure size.
legWidth = leg.get_window_extent().width
winWidthNew = w*dpi+legWidth

# Adjust the window size to fit the figure.
mgr = plt.get_current_fig_manager()

# Rescale the ax to keep its original size.
factor = w*dpi/winWidthNew
x0 = xlocs[0]*factor
x1 = xlocs[1]*factor
width = box.width*factor


@Ezekiel Kruglick 2014-02-18 21:21:20

I found this quite useful and it worked for me. Note that if you're in the wx backend (e.g. using windows), replace mgr.window.wm_geometry("%ix%i"%(winWidthNew,mgr.window.winfo‌​_height())) with mgr.window.SetClientSizeWH(winWidthNew,winHeightNew) or the like

@Filip S. 2014-04-30 06:47:01

If you're using the Qt4Agg backend (which is default on my Linux installation of matplotlib), then replace the line mgr.window.wm_geometry(...) with mgr.window.setFixedWidth(winWidthNew).

@Filip S. 2014-04-30 06:55:07

And, as I just discovered, if you're using a backend that doesn't show any windows, that are meant for saving straight to a file (like the SVG and AGG backends), just skip the window resizing altogether. fig.set_size_inches(...) takes care of the resizing you need.

@Uri Laserson 2011-01-17 07:06:56

You can also try figlegend. It is possible to create a legend independent of any Axes object. However, you may need to create some "dummy" Paths to make sure the formatting for the objects gets passed on correctly.

Related Questions

Sponsored Content

27 Answered Questions

[SOLVED] How do I check if a list is empty?

  • 2008-09-10 06:20:11
  • Ray
  • 3087491 View
  • 3233 Score
  • 27 Answer
  • Tags:   python list

42 Answered Questions

[SOLVED] How to make a flat list out of list of lists?

39 Answered Questions

[SOLVED] How do I check whether a file exists without exceptions?

26 Answered Questions

[SOLVED] How can I safely create a nested directory?

44 Answered Questions

20 Answered Questions

[SOLVED] Save plot to image file instead of displaying it using Matplotlib

  • 2012-03-08 17:38:10
  • Homunculus Reticulli
  • 1721163 View
  • 1211 Score
  • 20 Answer
  • Tags:   python matplotlib plot

17 Answered Questions

[SOLVED] How do you change the size of figures drawn with matplotlib?

22 Answered Questions

[SOLVED] Peak detection in a 2D array

10 Answered Questions

[SOLVED] Matplotlib 2 Subplots, 1 Colorbar

21 Answered Questions

[SOLVED] How do I list all files of a directory?

  • 2010-07-08 19:31:22
  • duhhunjonn
  • 4694958 View
  • 3470 Score
  • 21 Answer
  • Tags:   python directory

Sponsored Content