Skip to content

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 16 additions & 14 deletions lib/matplotlib/axes/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3904,16 +3904,16 @@ def twinx(self):
"""
Create a twin Axes sharing the xaxis

Create a twin of Axes for generating a plot with a shared
x-axis but independent y-axis. The y-axis of self will have
ticks on left and the returned axes will have ticks on the
right. To ensure tick marks of both axis align, see
Create a new Axes instance with an invisible x-axis and an independent
y-axis positioned opposite to the original one (i.e. at right). The
x-axis autoscale setting will be inherited from the original Axes.
To ensure that the tick marks of both y-axes align, see
`~matplotlib.ticker.LinearLocator`

Returns
-------
Axis
The newly created axis
ax_twin : Axes
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!

The newly created Axes instance

Notes
-----
Expand All @@ -3924,6 +3924,7 @@ def twinx(self):
ax2.yaxis.tick_right()
ax2.yaxis.set_label_position('right')
ax2.yaxis.set_offset_position('right')
ax2.set_autoscalex_on(self.get_autoscalex_on())
self.yaxis.tick_left()
ax2.xaxis.set_visible(False)
ax2.patch.set_visible(False)
Expand All @@ -3933,25 +3934,26 @@ def twiny(self):
"""
Create a twin Axes sharing the yaxis

Create a twin of Axes for generating a plot with a shared
y-axis but independent x-axis. The x-axis of self will have
ticks on bottom and the returned axes will have ticks on the
top.
Create a new Axes instance with an invisible y-axis and an independent
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
Contributor Author

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
ax_twin : Axes
The newly created Axes instance

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
Contributor Author

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
Contributor Author

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.

The Axes are rendered in some order (determined by the z-order and sorted in the Figure 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.

"""

ax2 = self._make_twin_axes(sharey=self)
ax2.xaxis.tick_top()
ax2.xaxis.set_label_position('top')
ax2.set_autoscaley_on(self.get_autoscaley_on())
self.xaxis.tick_bottom()
ax2.yaxis.set_visible(False)
ax2.patch.set_visible(False)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
36 changes: 36 additions & 0 deletions lib/matplotlib/tests/test_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,42 @@ def test_twinx_cla():
assert ax.yaxis.get_visible()


@image_comparison(baseline_images=['twin_autoscale'], extensions=['png'])
def test_twinx_axis_scales():
x = np.array([0, 0.5, 1])
y = 0.5 * x
x2 = np.array([0, 1, 2])
y2 = 2 * x2

fig = plt.figure()
ax = fig.add_axes((0, 0, 1, 1), autoscalex_on=False, autoscaley_on=False)
ax.plot(x, y, color='blue', lw=10)

ax2 = plt.twinx(ax)
ax2.plot(x2, y2, 'r--', lw=5)

ax.margins(0, 0)
ax2.margins(0, 0)


@cleanup
def test_twin_inherit_autoscale_setting():
fig, ax = plt.subplots()
ax_x_on = ax.twinx()
ax.set_autoscalex_on(False)
ax_x_off = ax.twinx()

assert ax_x_on.get_autoscalex_on()
assert not ax_x_off.get_autoscalex_on()

ax_y_on = ax.twiny()
ax.set_autoscaley_on(False)
ax_y_off = ax.twiny()

assert ax_y_on.get_autoscaley_on()
assert not ax_y_off.get_autoscaley_on()


@image_comparison(baseline_images=["minorticks_on_rcParams_both"], extensions=['png'])
def test_minorticks_on_rcParams_both():
fig = plt.figure()
Expand Down