FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

axes has no method to return new position after box is adjusted due to aspect ratio... · Issue #9207 · matplotlib/matplotlib · GitHub

Repository navigation

axes has no method to return new position after box is adjusted due to aspect ratio... #9207

Closed

Description

Bug report

Bug summary

axes has no method to return new position after box is adjusted due to aspect ratio...

Code for reproduction

fig, ax = plt.subplots(figsize=(2,4))
print(ax.get_position())
ax.set_aspect(1.)
print(ax.get_position(original=False))

Actual outcome

Bbox(x0=0.125, y0=0.10999999999999999, x1=0.9, y1=0.88)
Bbox(x0=0.125, y0=0.10999999999999999, x1=0.9, y1=0.88)

Expected/Desired outcome

Bbox(x0=0.125, y0=0.10999999999999999, x1=0.9, y1=0.88)
Bbox(x0=0.125, y0=0.30125, x1=0.9, y1=0.68875)

Source of issue

axes.get_position() is pretty simple, but always returns the frozen version of the axes position...

    def get_position(self, original=False):
        'Return the a copy of the axes rectangle as a Bbox'
        if original:
            return self._originalPosition.frozen()
        else:
            return self._position.frozen()

However, in axes.apply_aspect() this code is executed that changes the box size:

        figW, figH = self.get_figure().get_size_inches()
        fig_aspect = figH / figW
        if self._adjustable in ['box', 'box-forced']:
            if aspect_scale_mode == "log":
                box_aspect = A * self.get_data_ratio_log()
            else:
                box_aspect = A * self.get_data_ratio()
            pb = position.frozen()
            pb1 = pb.shrunk_to_aspect(box_aspect, pb, fig_aspect)
            self.set_position(pb1.anchored(self.get_anchor(), pb), 'active')
            return

It would be nice if we could somehow get at the new bbox:

    pb1 = pb.shrunk_to_aspect(box_aspect, pb, fig_aspect)
    pb1 = pb1.anchored(self.get_anchor(), pb)

I don't understand why in both cases the frozen position is returned in ax.get_position() rather than the current position. But maybe a new method get_adjusted_position() would work if we don't want to change get_position()?

Activity

  1. jklymak commented on Sep 20, 2017

    MemberAuthor

    .. and interestingly ax.apply_aspect isn't called when ax.set_aspect is called. I actually think that is a bug/overshight: we already know everything about the figure when ax.set_aspect is called that apply_aspect needs. Of course the figure can change size, so it should be called again at draw time, but it is useful to know the position of the axes at the initial draw.

  2. efiring commented on Sep 20, 2017

    Member

    It is not an oversight; you don't necessarily know everything you need to know until draw time. In a situation where the necessary information is available, the user is free to trigger a draw, or to call ax.apply_aspect manually, before calling get_position(). Aspect ratio handling is a complicated and costly operation, so I don't favor triggering it within set_aspect, which can be long before the necessary information is available.

  3. jklymak commented on Sep 20, 2017

    MemberAuthor

    @efiring

    Ah, OK, of course ax.apply_aspect() is a public method. Thats great!

    fig, ax = plt.subplots(figsize=(2,4))
    print(ax.get_position())
    ax.set_aspect(1.)
    ax.apply_aspect()
    print(ax.get_position(original=False))

    yields as you say:

    Bbox(x0=0.125, y0=0.10999999999999999, x1=0.9, y1=0.88)
    Bbox(x0=0.125, y0=0.30125, x1=0.9, y1=0.68875)
    

    I agree that things can change after, particularly if sharex or sharey are used, but it is a little mysterious to not know what the new positions is without calling ax.apply_aspect(). If it makes sense, I think I'll make a little PR that notes this in the doc-string:

    The position of the axes that has had its aspect ratio changed is not set until draw time,
     or after a manual call to ax.apply_aspect() has been made.  
    
  4. efiring commented on Sep 20, 2017

    Member

    The documentation change is a good idea.
    It might make sense to track whether a call to apply_aspect is needed, and call it if needed, within get_position(original=False), but I haven't investigated that.

  5. jklymak commented on Sep 20, 2017

    MemberAuthor

    Thats an interesting idea. I'm also not sure why apply_aspect() would be considered expenisve that we would need to keep track of whether it was called or not. But I don't have any experience optimizing the project...

  6. efiring commented on Sep 20, 2017

    Member

    Agreed, I don't know how expensive it is, and maybe it is negligible; but it's a monstrosity, so I guess I just don't like the idea of calling it unnecessarily.

  7. added this to the milestone on Apr 10, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL