77

I found tight_layout function for pyplot and want to use it. In my application I embed matplotlib plots into Qt GUI and use figure and not pyplot. Is there any way I can apply tight_layout there? Would it also work if I have several axes in one figure?

Zephyr
  • 10,450
  • 29
  • 41
  • 68
Ekaterina Mishina
  • 1,453
  • 5
  • 18
  • 22

1 Answers1

118

Just call fig.tight_layout() as you normally would. (pyplot is just a convenience wrapper. In most cases, you only use it to quickly generate figure and axes objects and then call their methods directly.)

There shouldn't be a difference between the QtAgg backend and the default backend (or if there is, it's a bug).

E.g.

import matplotlib.pyplot as plt

#-- In your case, you'd do something more like:
# from matplotlib.figure import Figure
# fig = Figure()
#-- ...but we want to use it interactive for a quick example, so 
#--    we'll do it this way
fig, axes = plt.subplots(nrows=4, ncols=4)

for i, ax in enumerate(axes.flat, start=1):
    ax.set_title('Test Axes {}'.format(i))
    ax.set_xlabel('X axis')
    ax.set_ylabel('Y axis')

plt.show()

Before Tight Layout

enter image description here

After Tight Layout

import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=4, ncols=4)

for i, ax in enumerate(axes.flat, start=1):
    ax.set_title('Test Axes {}'.format(i))
    ax.set_xlabel('X axis')
    ax.set_ylabel('Y axis')

fig.tight_layout()

plt.show()

enter image description here

Joe Kington
  • 258,645
  • 67
  • 583
  • 455
  • Perfect, so simple! Thank you, it works now. The only case when not everything goes right is when using scientific formating - 1e5 (or similar) is partially invisible for x axis. I rotate lables with some angle. – Ekaterina Mishina Mar 07 '12 at 19:31
  • 1
    I have tryed this and I'm getting `ValueError: max() arg is an empty sequence` when attempting to use this with an `mpl_toolkits.basmap` set to a `pyplot.figure()` `ax` object. Is this a bug, or a limitation with using this and `basemap` together? – ryanjdillon Mar 27 '14 at 13:15
  • @shootingstars - Can you give a more complete example? It should work fine with basemap. (Though you should have a look at `cartopy` for a more modern matplotlib mapping toolkit.) – Joe Kington Mar 27 '14 at 14:00
  • I have created `fig=plt.figure()` and `ax=fig.add_axes([0.1,0.1,0.8,0.8])` objects which I reference in my map definition (i.e. `m = basemap(..., ax=ax)`, just before `plt.show()` I call `fig.tight_layout()` which yields the above error. – ryanjdillon Mar 27 '14 at 16:42
  • 4
    @shootingstars - That's probably because you're making an axes that's not a subplot. All `tight_layout` does is calculate parameters for `subplots_adjust`, so `tight_layout` only works with subplots. Use `fig, ax = plt.subplots()` or `ax = fig.add_subplot(1,1,1)` instead of specifying the extent of the axes manually and it should work fine. (Newer versions of matplotlib give a more informative error in this case, by the way.) – Joe Kington Mar 28 '14 at 12:32
  • Excellent. Thank you Joe. I did just update my `matplotlib` and `basemap` due to various issues I've been having, and this is just another reason to have done so. – ryanjdillon Mar 28 '14 at 12:36
  • 1
    your `fig = Figure()` suggestion will cause `tight_layout` to raise `ValueError` unless axes are instantiated some other way. `subplots` is the right way to create both axes and figure instances. – hobs Mar 15 '16 at 19:14
  • What i'm finding is that if I follow-up that code with a plt.savefig(path_to_pdf), the formatting from plt.tight_layout() doesn't really translate to the PDF? Is there a way to do this? – user487588 Jun 21 '17 at 08:52