IPython's matplotlib inline magic is really magic? Actually it might resets axes bounds...

I’m constructing a multi-plot figure using an IPython notebook (v3) and matplotlib (v1.4.3) inline magic. I was manually setting the axes bounds, and I ended up with something like the following:

···

########

import matplotlib.pyplot as plt

%matplotlib inline

bottom = 0.12

top = 0.9

left = 0.12

axwidth = (1-(left*2))/3

fig = plt.figure(figsize=(10,4))

ax1 = fig.add_axes((left, bottom, axwidth, top))

ax1.set_title(‘Title’)

#ax1.tick_params(labelleft=False)

ax2 = fig.add_axes((left+axwidth, bottom, axwidth, top),

sharex=ax1, sharey=ax1)

ax2.tick_params(labelleft=False)

ax3 = fig.add_axes((left+axwidth*2, bottom, axwidth, top),

sharex=ax1, sharey=ax1)

ax3.tick_params(labelleft=False)

fig.savefig(‘junk.pdf’, format=‘pdf’)

fig.savefig(‘junk2.png’)

#######

Obviously, the bottom+top that I’ve selected is >1, so the axes should go off the top of the figure. (Stupid, I know…) The axes in both the PDF and PNG formatted files are clipped by the top of the figure as you would expect; however, the figure that is displayed in the Notebook looks just fine. In addition, if you add a title to one of the axes, the figure in IPython suddenly creates more space for the text. Maybe it is rearranging the axes information behind the scenes?

I’m curious why this design decision was made. I would say this is a bug. Now that I know about this behavior, I can easily fix it. But new users will be baffled when their saved figure looks nothing like the displayed figure in the notebook.

Ryan

This is due to the fact that by default the inline backend saves the pngs using boundingbox_inches='tight'. The design goal on the mpl side of this kwargs was to trim off extra whitespace, but the way it is implemented works just as effectively to expand to fit artists that fall outside of the figure. I assume the choice to make this the default in inline was to waste as little space as possible.

A possibly more reliable method to get the same effect is to use tight_layout (see http://matplotlib.org/users/tight_layout_guide.html)

There was talk of replacing that implementation with a linear constraint solver, but not much progress has been made in that direction (see https://github.com/matplotlib/matplotlib/issues/1109)

Tom

···

On Fri, Mar 13, 2015 at 3:01 PM Ryan Nelson <rnelsonchem@…1003…7…> wrote:

I’m constructing a multi-plot figure using an IPython notebook (v3) and matplotlib (v1.4.3) inline magic. I was manually setting the axes bounds, and I ended up with something like the following:

########

import matplotlib.pyplot as plt

%matplotlib inline

bottom = 0.12

top = 0.9

left = 0.12

axwidth = (1-(left*2))/3

fig = plt.figure(figsize=(10,4))

ax1 = fig.add_axes((left, bottom, axwidth, top))

ax1.set_title(‘Title’)

#ax1.tick_params(labelleft=False)

ax2 = fig.add_axes((left+axwidth, bottom, axwidth, top),

sharex=ax1, sharey=ax1)

ax2.tick_params(labelleft=False)

ax3 = fig.add_axes((left+axwidth*2, bottom, axwidth, top),

sharex=ax1, sharey=ax1)

ax3.tick_params(labelleft=False)

fig.savefig(‘junk.pdf’, format=‘pdf’)

fig.savefig(‘junk2.png’)

#######

Obviously, the bottom+top that I’ve selected is >1, so the axes should go off the top of the figure. (Stupid, I know…) The axes in both the PDF and PNG formatted files are clipped by the top of the figure as you would expect; however, the figure that is displayed in the Notebook looks just fine. In addition, if you add a title to one of the axes, the figure in IPython suddenly creates more space for the text. Maybe it is rearranging the axes information behind the scenes?

I’m curious why this design decision was made. I would say this is a bug. Now that I know about this behavior, I can easily fix it. But new users will be baffled when their saved figure looks nothing like the displayed figure in the notebook.

Ryan


Dive into the World of Parallel Programming The Go Parallel Website, sponsored

by Intel and developed in partnership with Slashdot Media, is your hub for all

things parallel software development, from weekly thought leadership blogs to

news, videos, case studies, tutorials and more. Take a look and join the

conversation now. http://goparallel.sourceforge.net/_______________________________________________

Matplotlib-users mailing list

Matplotlib-users@…1735…sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Thanks Tom.

Your hint led me to the following page:

https://github.com/ipython/ipython/blob/aab20bf85126f5b1da857193c446aebe6346acec/docs/source/whatsnew/version2.0.rst#other-changes

So it seems that this change is quite old, and I never noticed it before… The suggestion on that page requires some incantation of the %config magic. I tried this:

%config InlineBackend.print_figure_kwargs.bbox_inches = None

Which silently passes, but doesn’t change the behavior.

Your rational for IPython’s use of this kwarg by default is sound, and I understand that there are valid use cases for it in some circumstances. However, I still think this is problematic. I like MPL because you can make a plot to your exact specifications – but setting this kind of behavior by default (without a well documented fix) feels a little “Microsoft Office”-y… That being said, I really don’t care all that much. IPython is a fantastic tool. I’ll just move my plotting code to a separate script and tweak things there. (But then I won’t be able to share the notebook with my fancy plot embedded except as an external image. Can’t have everything.)

I actually don’t want any sort of ‘tight’ layout; however, just for reference, the tight_layout function throws an error in my example.

Ryan

···

On Fri, Mar 13, 2015 at 4:03 PM, Thomas Caswell <tcaswell@…287…> wrote:

This is due to the fact that by default the inline backend saves the pngs using boundingbox_inches='tight'. The design goal on the mpl side of this kwargs was to trim off extra whitespace, but the way it is implemented works just as effectively to expand to fit artists that fall outside of the figure. I assume the choice to make this the default in inline was to waste as little space as possible.

A possibly more reliable method to get the same effect is to use tight_layout (see http://matplotlib.org/users/tight_layout_guide.html)

There was talk of replacing that implementation with a linear constraint solver, but not much progress has been made in that direction (see https://github.com/matplotlib/matplotlib/issues/1109)

Tom

On Fri, Mar 13, 2015 at 3:01 PM Ryan Nelson <rnelsonchem@…287…> wrote:

I’m constructing a multi-plot figure using an IPython notebook (v3) and matplotlib (v1.4.3) inline magic. I was manually setting the axes bounds, and I ended up with something like the following:

########

import matplotlib.pyplot as plt

%matplotlib inline

bottom = 0.12

top = 0.9

left = 0.12

axwidth = (1-(left*2))/3

fig = plt.figure(figsize=(10,4))

ax1 = fig.add_axes((left, bottom, axwidth, top))

ax1.set_title(‘Title’)

#ax1.tick_params(labelleft=False)

ax2 = fig.add_axes((left+axwidth, bottom, axwidth, top),

sharex=ax1, sharey=ax1)

ax2.tick_params(labelleft=False)

ax3 = fig.add_axes((left+axwidth*2, bottom, axwidth, top),

sharex=ax1, sharey=ax1)

ax3.tick_params(labelleft=False)

fig.savefig(‘junk.pdf’, format=‘pdf’)

fig.savefig(‘junk2.png’)

#######

Obviously, the bottom+top that I’ve selected is >1, so the axes should go off the top of the figure. (Stupid, I know…) The axes in both the PDF and PNG formatted files are clipped by the top of the figure as you would expect; however, the figure that is displayed in the Notebook looks just fine. In addition, if you add a title to one of the axes, the figure in IPython suddenly creates more space for the text. Maybe it is rearranging the axes information behind the scenes?

I’m curious why this design decision was made. I would say this is a bug. Now that I know about this behavior, I can easily fix it. But new users will be baffled when their saved figure looks nothing like the displayed figure in the notebook.

Ryan


Dive into the World of Parallel Programming The Go Parallel Website, sponsored

by Intel and developed in partnership with Slashdot Media, is your hub for all

things parallel software development, from weekly thought leadership blogs to

news, videos, case studies, tutorials and more. Take a look and join the

conversation now. http://goparallel.sourceforge.net/_______________________________________________

Matplotlib-users mailing list

Matplotlib-users@…1735…sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-users