Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

ENH have ax.get_tightbbox have a bbox around all artists attached to axes.#10682

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
jklymak merged 1 commit intomatplotlib:masterfromjklymak:enh-ax-get-tightbbox
Jul 9, 2018

Conversation

jklymak
Copy link
Member

@jklymakjklymak commentedMar 5, 2018
edited
Loading

PR Summary

This PR takes the code that was inbackend_bases.py insavefig for determining a figure bounding box, and puts it inax.get_tightbbox andfig.get_tightbbox, via a refactoring intoArtists.get_tightbbox.

Supercedes#10678 and extends already merged#9164

In previous PRs I was piecemeal adding new types of artists, but noted thatfig.savefig(bbox_inches='tight') was actually doing the correct thing and putting the bbox around all the artists.

To get the old behaviour back, a new kwarg has been added:

ax.get_tightbbox(bbox_extra_artists=[])

So now the following code

importmatplotlib.pyplotaspltfig,ax=plt.subplots(figsize=(5,2))ax.set_xlim([0,1])ax.text(1,0.5,'This is a long overflow')print('before',ax.get_tightbbox(fig.canvas.get_renderer(),bbox_extra_artists=[]))print('now   ',ax.get_tightbbox(fig.canvas.get_renderer()))

returns:

before Bbox(x0=61.2, y0=-3.4, x1=922.125, y1=363.0)now    Bbox(x0=61.2, y0=-3.4, x1=1210.25, y1=363.0)

Thisis a breaking change, in that anyone who was expecting the bbox to not include artists, but just the axes axis elements and labels, will now get a different behaviour. They can get the old behaviour as above (specifying the emptybbox_extra_artists kwarg. OTOH, willing be told this is too big an API change. (it of course still needs an API change note, and likely a test or two somewhere).

UPDATE 28 April:

This adds the artist propertyartist.set/get_in_layout (as discussed w/@efiring et al on the weekly call) which specifies if an artist should be included in the tight_bbox calculation. This allows toggling artists in the tight layout or constrained layout calculations.

So, now we can also do:

fig,ax=plt.subplots(figsize=(5,2))ax.set_xlim([0,1])t=ax.text(1,0.5,'This is a long overflow')t.inbbox=True# defaultprint('inbbox true',ax.get_tightbbox(fig.canvas.get_renderer()))t.set_in_layout(False)print('inbbox false ',ax.get_tightbbox(fig.canvas.get_renderer()))t.set_in_layout(True)print('inbbox true ',ax.get_tightbbox(fig.canvas.get_renderer()))

and get

in_layout  true  Bbox(x0=61.18055555555556, y0=-3.4444444444444535, x1=1210.25, y1=363.0)in_layout false  Bbox(x0=61.18055555555556, y0=-3.4444444444444535, x1=922.125, y1=363.0)in_layout  true  Bbox(x0=61.18055555555556, y0=-3.4444444444444535, x1=1210.25, y1=363.0)

Note that this also works for legends, which often get put outside axes and hence may not want to be part of the tight_layout machinery.

Discussion: Should artists that did not get included in the oldtight_layout be set toFalse by default? I'm somewhat against this because it means users have to guess or query what state the attribute is in...

PR Checklist

  • Has Pytest style unit tests
  • Code is PEP 8 compliant
  • Documentation is sphinx and numpydoc compliant
  • Documented in doc/api/api_changes.rst if API changed in a backward-incompatible way

@jklymakjklymak added topic: geometry managerLayoutEngine, Constrained layout, Tight layout API: consistency API: changes labelsMar 5, 2018
@jklymakjklymakforce-pushed theenh-ax-get-tightbbox branch 2 times, most recently fromec57567 toc53836cCompareMarch 5, 2018 15:42
@jklymakjklymak added this to thev2.2.1 milestoneMar 5, 2018
@jklymakjklymakforce-pushed theenh-ax-get-tightbbox branch 2 times, most recently fromf93b291 to650f378CompareMarch 5, 2018 20:02
@tacaswelltacaswell modified the milestones:v2.2.1,v3.0Mar 5, 2018
@jklymakjklymakforce-pushed theenh-ax-get-tightbbox branch 4 times, most recently from2660b18 to30edb1fCompareMarch 6, 2018 05:06
@ImportanceOfBeingErnest
Copy link
Member

Is this meant to be used bytight_layout, such that one could callfig.tight_layout(bbox_extra_artists=[])?

@jklymak
Copy link
MemberAuthor

I think thats possible, though this PR doesn't do that. Not quite sure what happens if you specify an artist that isn't in the axes (tight layout would have to accept all the artists for each axes).

@jklymak
Copy link
MemberAuthor

See update above: rebased and addedartist.inbbox to determine if an artist is in a bbox calculation or not.

@jklymakjklymakforce-pushed theenh-ax-get-tightbbox branch 2 times, most recently from41727bd tofd918caCompareApril 29, 2018 15:38
@tacaswell
Copy link
Member

I am happy with this in principle, but we probably need to add theget_* andset_* methods to keep the API guessable.

We need a better name thaninbbox as bbox is a bit arcane andinbbox reads to be as a question not an instruction.


def get_tightbbox(self, renderer, call_axes_locator=True):
def get_tightbbox(self, renderer, call_axes_locator=True,
bbox_extra_artists=None):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

please do not add this extra kwarg.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Sorry, I screwed up the PR during a rebase... The reason for this is so that the artist logic that was inbackend_bases.print_figure could be refactored out and reused. So this needs to be here to make that
function work. Could make a private kwarg (is there such a thing?)

@jklymak
Copy link
MemberAuthor

added setters and getters, and changed name toartist.set/get_in_layout and madeartist._in_layout private.

@jklymakjklymakforce-pushed theenh-ax-get-tightbbox branch from5bada26 to6e60ecfCompareJuly 5, 2018 21:30
@jklymak
Copy link
MemberAuthor

@efiring Thanks for the review. Outstanding questions for others:

  1. should this be aartist.set/get_in_layout or should it just be a property (artist.in_layout)?
  2. Am I referring to the co-oridnate system of the bounding boxes correctly?get_tightbbox returns bounding boxes in pixels relative to the 0, 0 as the bottom left of the figure viewport. I'm referring to this as:
bbox : `.BboxBase`            containing the bounding box (in figure pixel co-ordinates).

I don't think this was ever properly specified before this PR. Probably becauseget_tightbbox andget_window_extents verge on private methods.

@timhoffm
Copy link
Member

timhoffm commentedJul 5, 2018
edited
Loading

re 1. From the pythonic point of view this would just be an attributeartist.in_layout. A property does not make sense here. Properties are basically there to attach code to reading or writing an attribute without changing the signature. You can just use the attribute and turn it into a property later if needed.

The only argument for set/get would be that it's widely used within matplotlib. However there are also a few counter-examplesartist.axes,artist.stale.

It's up to one of the more senior devs to decide which way to go. Personally, I'd have a slight preference for the attribute solution.

@jklymak
Copy link
MemberAuthor

From the pythonic point of view this would just be an attribute artist.in_layout.

Sorry, meant "attribute".

OTOH I think the issue is documentation - how does the user discover this attribute in the docs?

@jklymakjklymakforce-pushed theenh-ax-get-tightbbox branch from6e60ecf to0ef8d7aCompareJuly 5, 2018 22:10
@efiring
Copy link
Member

An attribute can have a docstring, and sphinx can include the documentation either by listing the attribute along with other explicit members, or via the autoattribute directive:

http://www.sphinx-doc.org/en/stable/ext/autodoc.html

I think@tacaswell really doesn't want to start doing this (using bare attributes) until the massive traitification is done, however. But maybe he will change his mind for cases like this.

@jklymakjklymakforce-pushed theenh-ax-get-tightbbox branch 5 times, most recently from25c45b2 tob31f829CompareJuly 7, 2018 23:00
@jklymak
Copy link
MemberAuthor

I’d be all for either form, with slight preference for the attribute.@tacaswell?

@jklymakjklymakforce-pushed theenh-ax-get-tightbbox branch fromb31f829 tob18d16cCompareJuly 9, 2018 19:20
@efiring
Copy link
Member

I accept@tacaswell's argument that keeping the machinery provided by the setters and getters is worthwhile for this, so ignore my suggestion to reduce it to a bare attribute.

Copy link
Member

@tacaswelltacaswell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

conditional on CI

@jklymak
Copy link
MemberAuthor

self merging as reviewed and passed CI

@jklymakjklymak merged commit632305e intomatplotlib:masterJul 9, 2018
@jklymakjklymak deleted the enh-ax-get-tightbbox branchJuly 9, 2018 20:09
@jklymak
Copy link
MemberAuthor

Grrrrr. This has a funny interaction w/ zooming. If I zoom, then the clip path of an artist is not set properly until after a draw. But all the automatic layout depends on being able to get a sensible tighbbox during draw... Darn race conditions....

@breedlun
Copy link
Contributor

I just spent several hours tracking down why my annotations were getting placed incorrectly after updating from Matplotlib v2.2.3 to Matplotlib v3.3.1. The problem turned out to beax.get_tightbbox() was not returning the same result as it did under Matplotlib v2.2.3. I am, however, pleased that I can get the old behavior withax.get_tightbbox(bbox_extra_artists=[]). Thanks for keeping some degree of backwards compatibility.

@jklymak
Copy link
MemberAuthor

You can also twiddle manually:artist.set_in_layout(False)...

breedlun pushed a commit to breedlun/clearplot that referenced this pull requestOct 20, 2020
…udes tick marks and tick mark labels, but not the axes lables, axes title, or other annotations. As of matplotlib 3.0, however, mpl_ax.get_tightbbox() returns the bounding box that includes the axes labels, axes title, and other annotations (seematplotlib/matplotlib#10682).  This new behavior was messing up my axis label placement.  Fortunately, one can still get the original behavior via mpl_ax.get_tightbbox(bbox_extra_artists = []), so the axes.tight_bbox property was updated to use this new kwarg.
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@efiringefiringefiring approved these changes

@tacaswelltacaswelltacaswell approved these changes

Assignees

@tacaswelltacaswell

Labels
API: changesAPI: consistencyRelease criticalFor bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.topic: geometry managerLayoutEngine, Constrained layout, Tight layout
Projects
None yet
Milestone
v3.0.0
Development

Successfully merging this pull request may close these issues.

6 participants
@jklymak@ImportanceOfBeingErnest@tacaswell@timhoffm@efiring@breedlun

[8]ページ先頭

©2009-2025 Movatter.jp