Adjusting space around figure with subplots

thosphor picture thosphor · Jan 29, 2015 · Viewed 11.7k times · Source

I'm using Matplotlib and struggling to get exactly the right amount of whitespace around a figure I'm plotting that contains a grid of subplots.

Requirements: be able to choose the aspect ratio of all the subplots (they're all the same), define exactly how much whitespace there is between the subplots and the top, bottom and left of the (saved) figure edge. I don't need any extra space on the right.

The code I have so far contains the following:

import matplotlib.pyplot as plt
fig, axes = plt.subplots(ncols=6, nrows=2, sharex=True, 
                         sharey=True, figsize=(16,8))

axes[0,0].plot(x,y)
etc...

plt.subplots_adjust(hspace=1.0, wspace=0.02, bottom=0.17, left=0.075, top=0.18)

plt.savefig('Fig1_matplot.pdf', bbox_inches='tight')

As it is, if I don't specify figsize=() the aspect ratio of the subplots is wrong. If I do, then the aspect ratio changes whenever I change parameters in subplots_adjust(). Apparently left cannot be >= right and bottom cannot be >= top. If I do define top to be anything other than 0 it completely compresses all of the subplots down to a line at the bottom of the figure.

If I specify bbox_inches='tight' then it cuts off my defined whitespace at the bottom and left, but if I don't specify it then I'm left with excess whitespace on the right since I can't get rid of it (right would be <= left).

I'm a bit stuck, any help would be much appreciated.

Cheers.

Answer

juseg picture juseg · Jan 29, 2015

When using subplots_adjust, the values of left, right, bottom and top are to be provided as fractions of the figure width and height. In additions, all values are measured from the left and bottom edges of the figure. This is why right and top can't be lower than left and bottom. A typical set-up is:

plt.subplots_adjust(left=0.1, right=0.9, bottom=0.1, top=0.9)

On the other hand, if you want to provide white space as absolute values in inches, you will have to divide by the figure width and height. For instance in your case, a 1 inch margin around all edges can be achieved with:

plt.subplots_adjust(left=1/16.0, right=1-1/16.0, bottom=1/8.0, top=1-1/8.0)

For more versatility I usually parametrize the width and height of the figure as:

figw, figh = 16.0, 8.0
fig, axes = plt.subplots(ncols=6, nrows=2, sharex=True, sharey=True,
                         figsize=(figw, figh))
plt.subplots_adjust(left=1/figw, right=1-1/figw, bottom=1/figh, top=1-1/figh)

The hspace and wspace are counted as fractions of one panel's axes width and height, so that their absolute value depends on the figure dimensions, the outer margins and the number of subplots, which will require a tiny bit more math for fine-tuning.