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

ENH: secondary axis for a x or y scale. · Issue #10976 · matplotlib/matplotlib · GitHub

Repository navigation

ENH: secondary axis for a x or y scale.  #10976

Closed

Description

Enhancement discussion

See #10961 #10960

Often it is desirable to have a second x or y scale on an axes with a different scale than the primary x/y axis; think frequency and period on the xaxis of a power spectrum, or date and datenum for a time series. (just assuming the x-axis for now:) Generally it'd be the same size as the existing xaxis, but would be offset vertically, have its own locator, formatter, and xlabel. it would update as the data is zoomed through, and be slave to the parent xaxis

It appears folks most often do this with twiny (i.e. https://stackoverflow.com/questions/10514315/how-to-add-a-second-x-axis-in-matplotlib) but there is nothing to make the axes continue to have the same x-limits under interactive viewing, and no simple way to have the new axes have a different scale.

The enhancement here would be to add something like:

secaxis = ax.secondary_xaxis(loc='top', convert=5, label='Boo')

where secaxis is either an axis object or an axes. loc would be something like "top", "bottom", "above", "below", float where "above" and "below" means that it goes above or below any existing axis, and the float is a hard-set axes fraction (like the set_position of spine now). convert would be a conversion factor: a float would just be a multiplier, or a function could be passed that converts x to xnew. No doubt there could be a way to make this work with units instead, but...

How to impliment

As discussed in #10961 @efiring thought implimenting as an axes with shrunk and hidden unused dimensions would be good.

I'd advocate an axis object so that the logical organization makes more sense. i.e. this would be a child of the original axes, and would be included as one of the axes decorators. But, I haven't thought through all the implimentation details yet.

Activity

  1. efiring commented on Apr 6, 2018

    Member

    An Axis makes logical sense, but it doesn't fit deep-seated aspects of the way mpl works, which is very Axes-centric. Among other things, spines reside in the Axes, even though each spine is tied to an Axis. That's why I think that a variation on twinning, but with a stripped-down slave Axes rather than a full-fledged twin, is likely to provide the most direct route to the desired result. The slave would be designed solely for the purpose of providing alternative scales (with Locators and Formatters) for labeling the data plotted in the master. It would be added to the Figure just like any other Axes, so the master would not have to know about it, and the Axes class would not be changed.

  2. jklymak commented on Apr 6, 2018

    MemberAuthor

    OK, I hadn't quite realized that axis objects didn't know about the spines.

    The reason I was thinking of it as a spine/xaxis is then it could be included in the bounding box for any tight/constrained_layout behaviour acting on the parent axes. For layout the parent needs to know about the child. I think I can still do that if we go an axes route, the way colorbars are done, but its a bit ugglier.

  3. u55 commented on Apr 7, 2018

    Contributor

    Yes please! I have needed this functionality a few times, and solved it by using a BlendedGenericTransform, see https://stackoverflow.com/a/3165542/4708327 for an example. But this requires a lot of boiler-plate code to create the forward and inverse Transform classes. It would be very nice to be able to do this with a simple one-liner built into matplotlib.

  4. jklymak commented on Apr 7, 2018

    MemberAuthor

    Thanks for the pointer @u55 . It is interesting to think how units fits into all of this. As pointed out by @anntzer its possible to think of units as a Transform, and there is the possibility that the units support will just be moved into a transform-like construct.

  5. added this to the milestone on Apr 7, 2018
  6. jklymak commented on Apr 7, 2018

    MemberAuthor

    Note that this is the functionality provided in ParasiteAxes https://matplotlib.org/gallery/axes_grid1/parasite_simple2.html
    so maybe there is something to be borrowed from in there.

  7. ImportanceOfBeingErnest commented on Apr 7, 2018

    Member

    I wanted to mention here that pandas uses secondary_y to create a twinx axes.

    pandas.Series([1,2,3]).plot()
    pandas.Series([29,28,27]).plot(secondary_y=True)
    

    It could be confusing if now matplotlib uses secondary_yaxis to create a shared axis spine.

  8. u55 commented on Apr 7, 2018

    Contributor

    To simplify the API, instead of creating a new axes method, how about adding another kwarg to SubplotHost.twin, such as:

    from mpl_toolkits.axes_grid.parasite_axes import SubplotHost 
    ax_host = SubplotHost(fig, 1, 1, 1)
    ax_twin = ax_host.twin(convert=(lambda x: 1/(1+x), lambda y: y**2))

    which handles all the boiler-plate code to create the Transform classes for x and y.

    The only problem I see, is that currently, transforms.BlendedGenericTransform, requires both the forward and inverse Transform. For complicated non-analytic functions, an inverse function may not be available easily, and it would be nice if we could lift this requirement.

  9. jklymak commented on Apr 7, 2018

    MemberAuthor

    That’s possible. Axes_grid1 isn’t really part of core, so in my opinion it’d be nice to move this into the main functionality.

  10. modified the milestones: v3.0, v3.1 on Aug 11, 2018
  11. jklymak commented on Mar 14, 2019

    MemberAuthor

    This was done in #11859

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