7

I have a figure that contains two subplots in two rows and one column like so:

fig, (ax1, ax2) = subplots(
    nrows=2,
    ncols=1,
)

The two subplots are pie charts, therefore I want their axes to be square. After browsing the API, the following should be the correct way to adjust the axes of each subplot:

ax1.axis([0, 8, 0, 8])
ax2.axis([0, 8, 0, 8])

Then I adjust the size of the entire figure. Since the width of each subplot is 8 inches, I set the width of the figure to 8 inches as well and the height of the figure to 2*8=16 inches:

fig.set_size_inches(8, 16)

These settings result in nicely formatted pie charts. However, a label for one of the wedges of a pie is cut off at the right edge of the figure when I save the figure to a PDF file. The figure is more narrow in the saved file than in the preview window. That's why I want to widen the figure along the x axis but by retaining the axes of the subplots. If I just try to widen the figure by doing:

fig.set_size_inches(12, 16)

The figure gets wider now but, unfortunately, the two pie charts as well. From my understanding, the axis() calls should retain the dimensions of the subplots but they don't. After reading and trying out a lot about autoscale, xlim, ylim etc., I'm even more confused and nothing works.

I simply want to widen the figure by retaining the dimensions of the subplots so that there is more whitespace along the x axis and the labels can be displayed without cutting them off. How do I do that?

Ionică Bizău
  • 109,027
  • 88
  • 289
  • 474
pemistahl
  • 9,304
  • 8
  • 45
  • 75

1 Answers1

11

I would suggest using fig.tight_layout. You have roughly two paths, either tweak pad

fig.tight_layout(pad=2)

which while move all of your edges in from the edge of the figure or

fig.tight_layout(rect=[0,0,.8,1]) 

which will adjust the size of the box (in units of fraction of the figure) that the sub-plots are squeezed into. This only works in newer (1.2 or later) versions.

You can also create you sub-plots by hand (which is super annoying, but gives you complete control) or use gridspec. Layout out sub-plots seems to be a problem matplotlib has a large number of ways to solve.

The annoying way do to this is

fig = plt.figure()


top_offset = .07
left_offset = .15
right_offset = .2
bottom_offset = .13
hgap = .1
ax_width = 1-left_offset - right_offset
ax_height = (1-top_offset - bottom_offset - hgap)/2

ax1 = fig.add_axes([left_offset, bottom_offset + ax_height + hgap, ax_width, ax_height])
ax2 = fig.add_axes([left_offset, bottom_offset, ax_width, ax_height])

with the 5 parameters tweaked to be what ever makes your figures look good.

Alex
  • 778
  • 2
  • 12
  • 16
tacaswell
  • 84,579
  • 22
  • 210
  • 199
  • I was actually using `tight_layout()` already but adjusting its arguments hasn't come to my mind so far. By tweaking `pad`, everything inside the figure gets smaller. This way, the label fits completely into the figure at some point but the subplots become very (=too) small. When I try to adjust `rect` as in your second example, I get `TypeError: tight_layout() got an unexpected keyword argument 'rect'`. – pemistahl Jan 13 '13 at 19:38
  • @PeterStahl what version of matplotlib are you using? – tacaswell Jan 13 '13 at 19:51
  • I'm using version 1.1.1 on OSX 10.8.2. – pemistahl Jan 13 '13 at 19:56
  • http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.tight_layout give me a second to dig back and see when they added the `rect` keyword.... – tacaswell Jan 13 '13 at 19:58
  • @PeterStahl yeah, that keyword got added sometime after 1.1.1 – tacaswell Jan 13 '13 at 20:03
  • Ah, good to know. I'd even like to use 1.2.0 but it doesn't work on my platform. (See this question on SO: http://stackoverflow.com/questions/14259185/matplotlib-runtimeerror-no-sfnt-name-table). Does the `rect` argument actually widen the figure or does it make the plots just smaller as the `pad` option? – pemistahl Jan 13 '13 at 20:12
  • @PeterStahl see edit. `rect` changes the bounding box that it tries to shove the the subplots into. It basically does what I do in the latest edit, but automagically. – tacaswell Jan 13 '13 at 20:22
  • Okay, I see. By changing the right offset in your code snippet, the subplots get squeezed horizontally. Now the label fits completely into the figure, but the pie charts are not square anymore. I don't understand why I simply can't make the figure wider and leave the plots as they are. Matplotlib has some severe limitations as it seems. I'll probably have to shorten the label or change the order of the wedges. Anyway, thanks a lot for your effort, +1 from me. :) – pemistahl Jan 13 '13 at 20:50
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/22678/discussion-between-tcaswell-and-peter-stahl) – tacaswell Jan 13 '13 at 20:52