erik
erik

Reputation: 659

Matplotlibs: avoid annotations to resize figure

I would like to have the tight_layout() function in matplotlib ignore annotations. As an example, this is a plot with tight_layout:

fig = plt.figure()
fig.patch.set_facecolor('grey')

ax1 = plt.subplot(221)
ax2 = plt.subplot(223)
ax3 = plt.subplot(122)

def example_plot(ax, fontsize=12):
     ax.plot([1, 2])
     ax.locator_params(nbins=3)
     ax.set_xlabel('x-label', fontsize=fontsize)
     ax.set_ylabel('y-label', fontsize=fontsize)
     ax.set_title('Title', fontsize=fontsize)

example_plot(ax1)
example_plot(ax2)
example_plot(ax3)

plt.tight_layout()

plt.annotate('a)', xy=(0, 1), xycoords='figure fraction', ha='left', va='top')
plt.annotate('b)', xy=(0, 0.5), xycoords='figure fraction', ha='left', va='top')
plt.annotate('c)', xy=(0.5, 1), xycoords='figure fraction', ha='left', va='top')

enter image description here

enter image description here

The figure seems to be increased in size (to the left and top) to make space for the annotations (the ylabels don't go all the way to the edge). However, I would like the annotations to be added on top of the figure without any rearrangement. Can I somehow make tight_layout ignore these annotations?


Edit: It is actually not a problem of tight_layout it turns out. Even without calling tight_layout this resizing of the plot happens:

enter image description here

enter image description here

However, if I try the same on a different computer, the expected behavior (no resizing) happens. Both systems run matplotlib 2.0.0 and ipython.

Upvotes: 0

Views: 1075

Answers (2)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339120

I think you're looking at this from the wrong direction. First of all, there is no "issue". Everything is working as expected.

tight_layout does not change the figure size. All it does is rearanging the elements inside the figure, to better use the available space.

What you see is an effect of the saved figure being cropped because of the setting bbox_inches="tight". This happens because the %matplotlib inline backend shows a saved version of the figure. The image is cut from the original figure such that the saved image contains all elements in the canvas.
The image shown is therefore usually smaller than the original one.

In case however that you put some labels close to the figure edge, the figure cannot be cropped, as this would cut the labels. This may appear as if the figure has grown compared to the case without labels. However, as explained, in reality the figure is just not cropped.

A solution, if needed, is of course to position the labels further away from the figure edge, such that the bbox_inches="tight" algorithm can crop more of the figure.

Upvotes: 1

erik
erik

Reputation: 659

Apparently this is a specific issue if %matplotlib inline is used. If I switch to %matplotlib notebook instead everything is fine.

Upvotes: 0

Related Questions