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

twinx / twiny inherit autoscale behavior for shared axis#7904

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
NelleV merged 1 commit intomatplotlib:masterfromnaoyak:twin-axes-autoscale
Jan 29, 2017

Conversation

naoyak
Copy link
Contributor

Fixes#6860

Creatingtwinx() ortwiny() should inherit the autoscaling behavior from the parent Axes instance, but only for the shared axis. Previously,twinx() would autoscale on the x-axis regardless of the setting on the original Axes, meaning that plotting on the twin would look incorrect with the (visible) original x-axis.

@naoyaknaoyak closed thisJan 21, 2017
@naoyaknaoyak reopened thisJan 21, 2017
self.yaxis.tick_left()
ax2.xaxis.set_visible(False)
ax2.set
Copy link
Member

Choose a reason for hiding this comment

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

what does this line do?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

oops, made a goof there. removed.

@@ -145,6 +145,24 @@ def test_twinx_cla():
assert ax.yaxis.get_visible()


@cleanup
def test_twin_inherit_autoscale():
Copy link
Member

Choose a reason for hiding this comment

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

As much as I dislike image tests, do you have one of those, or some other inspection of the axis to check that the ticks are acting the way you expect?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

Yeah, I could create something motivated by the example in#6860 (i.e. that the plotted points should reflect that the original (visible) axis and twinned (invisible) axis share the same autoscaling behavior.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

added a simple image comparison.

@story645
Copy link
Member

story645 commentedJan 23, 2017
edited
Loading

Also, how does this intersect with#7528?

@naoyak
Copy link
ContributorAuthor

mm, i have to check out#7528. I think I need to understand a bit better what_make_twin_axes() is doing...

@naoyak
Copy link
ContributorAuthor

I don't think this PR conflicts directly with#7528 in terms of functionality, but maybe testing can be consolidated. Seems like there's some confusion on whether theshared axis should be thesameaxis or a copy (whose attributes can be changed independently), both from the API perspective and in terms of the internals.

@naoyaknaoyak closed thisJan 24, 2017
@naoyaknaoyak reopened thisJan 24, 2017
@naoyaknaoyak changed the titletwinx / twiny inherit autoscale behavior for shared axis[MRG] twinx / twiny inherit autoscale behavior for shared axisJan 25, 2017
@NelleV
Copy link
Member

This looks good to me. I'd just add a bit of documentation on thetwinx andtwiny method to explain this behaviour.

@naoyak
Copy link
ContributorAuthor

@NelleV thanks, added a note about the autoscale setting to the docstrings.

@NelleVNelleV changed the title[MRG] twinx / twiny inherit autoscale behavior for shared axis[MRG+1] twinx / twiny inherit autoscale behavior for shared axisJan 25, 2017
@NelleV
Copy link
Member

Thanks! It looks good to me.

@@ -3902,18 +3902,18 @@ def _make_twin_axes(self, *kl, **kwargs):

def twinx(self):
"""
Create a twin Axes sharing thexaxis
Create a twin Axesinstancesharing thex-axis with self
Copy link
Member

Choose a reason for hiding this comment

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

not clear what self is here? (Basically not sure this is any clearer than the original wording)

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

Addressed

ticks on left and the returned axes will have ticks on the
right. To ensure tick marks of both axis align, see
`~matplotlib.ticker.LinearLocator`
Create a twin Axes instance for generating a plot with a shared
Copy link
Member

Choose a reason for hiding this comment

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

also not sure this is any clearer. docs support images, so maybe that's the way to go here?
https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/axes/_axes.py#L1660

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

An image would be a good idea. These docs feel like they are about implementation rather than the use case - I think what we want to say is "call this method if you want to create a plot with 1 x-axis and 2 y-axes". To me the extra xaxis object is an artifact which is hidden, but apparently there is another use case...

Copy link
Member

Choose a reason for hiding this comment

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

Since these are the dev docs, they kinda have to stay in implementation land. Your string is great, but more appropriate for a gallery example. Honestly, I'd just prefer theoriginal docstring. I think with a small image, they're clear

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

If the docstring is going to focus on implementation, it still needs to be revised to reflect what's actually going on behind the scenes. twinx/twiny doesn't really "share" an axis in the sense of sharing theAxis object, but instead creates a 2nd, invisible one..I can try to encapsulate this aspect and revise.


Notes
------
-----
For those who are 'picking' artists while using twiny, pick
events are only called for the artists in the top-most axes.
Copy link
Member

Choose a reason for hiding this comment

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

top-most relative to what?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

I think this means the "original" Axes.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

Actually I'm not really familiar with the Artist/picker API, I'm not really sure what top-most is in this context..

Copy link
Member

Choose a reason for hiding this comment

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

TheAxes are rendered in some order (determined by the z-order and sorted in theFigure draw method). Which ever one draws last (has highest z-order) is the one that gets the pick event.

Copy link
Contributor

Choose a reason for hiding this comment

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

If I remember correctly, the new axis ends up on top. I remember having some issues with legends getting obscured by gridlines because of this.

@@ -3902,18 +3902,18 @@ def _make_twin_axes(self, *kl, **kwargs):

def twinx(self):
"""
Create a twin Axes sharing thexaxis
Create a twin Axesinstancesharing thex-axis with the parent
Copy link
Member

Choose a reason for hiding this comment

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

with the parent what?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

is it that unclear? maybe "parent" isn't the exact terminology, but after alltwinx() is a method called on an existingAxes. I am going to revert this part of the docstring edit.

self.yaxis.tick_left()
ax2.xaxis.set_visible(False)
ax2.patch.set_visible(False)
return ax2

def twiny(self):
"""
Create a twin Axes sharing theyaxis
Create a twin Axesinstancesharing they-axis with the parent
Copy link
Member

Choose a reason for hiding this comment

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

same as above

@naoyaknaoyakforce-pushed thetwin-axes-autoscale branch 2 times, most recently fromead4817 to1492d30CompareJanuary 26, 2017 21:58
@naoyak
Copy link
ContributorAuthor

naoyak commentedJan 27, 2017
edited
Loading

OK, I've revised thetwinx andtwiny docstrings to reflect the changes in this PR and clarified the wording to the best of my ability.

However this makes me wonder if the implementation is flawed in that the scales of the twinned axis will diverge if autoscale is turned on, since plotting is done on either the originalor the newAxes. Would it make more sense to share the sameAxis object?

`~matplotlib.ticker.LinearLocator`

Returns
-------
Axis
Copy link
Member

Choose a reason for hiding this comment

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

wow, good catch!

@story645
Copy link
Member

This is making my head hurt. I'm wondering, and you likely know better than me at this point, but what I'm getting from you is that one y is hooked into the displayed x and the other is y hooked into the hidden x? if so, I agree that they they should just both be hooked into a single x, but I wonder if that's possible...

@naoyak
Copy link
ContributorAuthor

naoyak commentedJan 27, 2017
edited
Loading

Actually, sorry it seems to work fine with the separate xaxis instances - the autoscaling does stay in sync between the "original" and the "twinned" x-axes. So while the implementation is still confusing to me, I think this will work OK.

importnumpyasnpimportmatplotlib.pyplotaspltfig,ax1=plt.subplots()t=np.arange(0.01,10.0,0.01)s1=np.exp(t)ax1.plot(t,s1,'b-')ax1.set_xlabel('original x-axis')ax1.set_ylabel('exp',color='b')ax1.tick_params('y',colors='b')ax1.tick_params('x',colors='b')ax2=ax1.twinx()ax2.set_ylabel('sin',color='r')ax2.tick_params('y',colors='r')ax2.tick_params('x',colors='r')# Manually set the twinned x-axis visible and shift it downax2.xaxis.set_visible(True)ax2.spines['bottom'].set_position(('axes',-0.2))ax2.set_xlabel('twinned x-axis')t2=np.arange(0.01,20.0,0.01)s2=np.sin(2*np.pi*t2)ax2.plot(t2,s2,'r.')plt.show()

download

@story645
Copy link
Member

Don't apologize! There are loads of moving pieces here and it gets confusing quickly. Ok, then far as I can tell, the goal of#7376 is to treat original and twin x as two semi-independent axis, in that they should have the same min & max but can be labeled individually. And so making a shared x-axis would probably make that functionality impossible.@madphysicist wanna chime in?

@naoyak
Copy link
ContributorAuthor

Yep, making a shared xAxis instance would seem to preclude the functionality in#7376. Fortunately we don't have to go down that road to resolve the relevant issues here 😄

This should be ready now - if it gets merged@madphysicist will have to sort a merge conflict in the docstring, but nothing functionally impactful, I think.

@story645
Copy link
Member

Looks good to me, just waiting on gitter.im for how to deal with the appveyor failure that has nothing to do with your test.

`~matplotlib.ticker.LinearLocator`

Returns
-------
Axis
The newly created axis
Axes
Copy link
Contributor

Choose a reason for hiding this comment

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

I think that this should be lowercase.

x-axis positioned opposite to the original one (i.e. at top). The
y-axis autoscale setting will be inherited from the original Axes.
To ensure that the tick marks of both x-axes align, see
`~matplotlib.ticker.LinearLocator`
Copy link
Contributor

Choose a reason for hiding this comment

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

I am not sure that I understand the last sentence. Specifically, how does looking at the documentation for LinearLocator ensure tick alignment? :)

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

This is the original wording - do you have any suggestions for a better sentence? (or you could incorporate it in your PR since that deals with tickers)

Copy link
Contributor

Choose a reason for hiding this comment

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

I will try to figure out what that sentence means exactly and attempt to improve it.


Returns
-------
Axis
The newly created axis
Axes
Copy link
Contributor

Choose a reason for hiding this comment

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

Lowercase?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

revised

@madphysicist
Copy link
Contributor

@naoyak Until fairly recently, I thought that twinning actually meant sharing the axis. Since that is not the case, yourearlier comment makes me question this whole PR:

However this makes me wonder if the implementation is flawed in that the scales of the twinned axis will diverge if autoscale is turned on, since plotting is done on either the original or the new Axes. Would it make more sense to share the same Axis object?

I don't think that sharing the axis object is an option. I think there may need to be a special provision in autoscaling that sets the widest possible bounds for the entire chain of twinned axes. Inheriting autoscaling is definitely a necessary part of this, but autoscaling itself may need to be redefined to special-case axes with twins. I think that fixing that issue that way will also address the concerns about my PR and autoscaling that@efiring brought up.

@naoyak
Copy link
ContributorAuthor

@madphysicist

I think there may need to be a special provision in autoscaling that sets the widest possible bounds for the entire chain of twinned axes.

I think that's what the current implementation does, actually - I am not sure how this is accomplished under the hood, though. Per discussion above I realized that sharing theAxis object is unnecessary so that is no longer an issue.

At this point this PR only sets the autoscale setting equal for the twinned axis instances and doesn't touch anything else. I think it's safe to merge without messing with your PR, what do you think?

@madphysicist
Copy link
Contributor

I think that you are safe to merge. I am working on some autoscaling tests right now. I am pretty sure there will be no conflict but it will be interesting to see how our PRs play together.

naoyak reacted with thumbs up emoji

@story645story645 changed the title[MRG+1] twinx / twiny inherit autoscale behavior for shared axis[MRG+2] twinx / twiny inherit autoscale behavior for shared axisJan 29, 2017
@NelleVNelleV merged commit85d76be intomatplotlib:masterJan 29, 2017
@naoyaknaoyak deleted the twin-axes-autoscale branchJanuary 29, 2017 04:39
@QuLogicQuLogic changed the title[MRG+2] twinx / twiny inherit autoscale behavior for shared axis\twinx / twiny inherit autoscale behavior for shared axisJan 29, 2017
@QuLogicQuLogic changed the title\twinx / twiny inherit autoscale behavior for shared axistwinx / twiny inherit autoscale behavior for shared axisJan 29, 2017
@QuLogic
Copy link
Member

#6860 wants a backport.

@QuLogicQuLogic added this to thev2.1 milestoneAug 12, 2021
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@tacaswelltacaswelltacaswell left review comments

@madphysicistmadphysicistmadphysicist left review comments

@NelleVNelleVNelleV approved these changes

@story645story645story645 approved these changes

Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
v2.1
Development

Successfully merging this pull request may close these issues.

The original xlim changed by twinx
6 participants
@naoyak@story645@NelleV@madphysicist@QuLogic@tacaswell

[8]ページ先頭

©2009-2025 Movatter.jp