-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
legend(bbox_transform) don't work with tight layout in 2.2.x #11041
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
The solution is to use |
Ok, thanks. I guess that is a useful property in most cases but it broke my code spectacularly. I think the following small change solve it for me
And the main part of the extra is to avoid to put a legend on the nolabel lines |
Would it in general be an idea to let artists decide whether they want to take part in geometry management or not? |
Right now all both layout managers do is query the tight_bbox of the axes objects, and other figure-level artists. So if you added such a flag to individual artists, it would affect the tight_bbox of the axes, and other uses of tight_bbox ( I'm not wholesale against this, but its pretty fiddly. I'd rather we were more disciplined in where in the figure hierarchy we place artists. To my mind saying a legend is a member of axes[0] but drawing in in axes[3] is basically asking for automatic layout not to work too well. That it worked before is to my mind an oversight in not including legends in the bbox for the axes. Similarly I'd be mildly against letting people have axes titles that are wildly too wide for the figure. Taking the title out of the bbox is possible, but then the automatic layout would no longer make room for it vertically. Better just to note that automatic layout doesn't work anymore, fix the title, or turn automatic layout off. But we can keep an eye on it. If there are lots of users trying to attach artists to an axis, but have the artist plotted far off on another axis, maybe its worth adding the extra layer of bookkeeping. Finally, another option is to do all your layout, call the layout manager, turn off the layout manager, and add the extra do-hickeys. fig=plt.figure(1)
fig.clf()
ax=[fig.add_subplot(2,2,i+1) for i in range(4)]
for j in range(3):
for i in range(2):
ax[j].plot([0,i])
ax[-1].axis("off")
fig.set_tight_layout(True)
fig.canvas.draw()
fig.set_tight_layout(False)
ax[0].legend(['1','2'],
bbox_to_anchor=(0.1, 1),
bbox_transform=ax[-1].transAxes, loc="upper left")
plt.show() works fine. |
BTW, see #10682 where I propose making this worse 😉 |
Yep I suppose this is the correct thing to do. I was rather wondering if there was an easy option to opt out of this - which may still be useful in certain cases. I guess the main argument here is simply that some automatic layout system cannot guess what you trying to do. So certain cases cannot be handled reasonably by it. E.g. the annotation bbox example - I suppose it's not actually clear what a user expects if calling tight_layout on that one. In such cases it would probably be useful to have the option to get the annotation box included or excluded on a per case basis. |
I think my use case was kind of natural. I have many subplots that should have the same legend, the legend are to large to be nicely be shown in a single subplot. So I used the plot data from one of the subplots and put it in another clear subplot. The workaround is not that difficult but it is definitely more complicated and more error prone than my old code. I doubt that it is that easy to implement but it would be nice if the legend in my use case was handled together with the ax/subplot that it actually exist in and not together with the ax that it got the data from. The problem with turning on and off tight layout are that it doesn't work well when resizing the figure. |
The following example doesn't work as expected
The subplots are to small |
Again the legend over spilling them axismakes the bounding box get larger. That makes the space between subplots smaller. It’s working as designed, the difference is the API change between 2.1 and 2.2. |
Ok, I understand that now. I think that it would be good to have a parameter that sets if a legend (or other artists) should be included in the tight_layout calculation or not. I believe that would be useful when you work with data and want to have reasonable good plots that work with different figure sizes and different legend lengths. It is better to show nice and large plots and a cut legend or overlapping titles instead of a good looking legend and small plots. Tight_layout are good if you want larger plots in many applications and not just to avoid overlaps. |
Note the workaround is easier using lines, labels = ax[0].get_legend_handles_labels()
ax[0].figure.legend(lines, labels,
bbox_to_anchor=(0, 1),
bbox_transform=ax[-1].transAxes, loc="upper left") I am also suggesting in #10682 that we add an |
Uh oh!
There was an error while loading. Please reload this page.
The following code worked as expected in matplotlib 2.1.x but doesn't work in matplotlib 2.2.x
The subplots are in the wrong place and have the wrong size (mostly outside the figure window in my real ploting code ...) and its get even worse if you interact with them.
python 3.6
matplotlib 2.2.0 and 2.2.2 has been tested.
The text was updated successfully, but these errors were encountered: