Skip to content

Improve(?) implementation of secondary_axis. #14463

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
13 changes: 4 additions & 9 deletions examples/axisartist/demo_axisline_style.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,19 @@
example.
"""

from mpl_toolkits.axisartist.axislines import SubplotZero
from mpl_toolkits.axisartist.axislines import Subplot
import matplotlib.pyplot as plt
import numpy as np


fig = plt.figure()
ax = SubplotZero(fig, 111)
ax = Subplot(fig, 111)
fig.add_subplot(ax)

for direction in ["xzero", "yzero"]:
# adds arrows at the ends of each axis
for direction in ["bottom", "left"]: # Add arrows for bottom and left axes.
ax.axis[direction].set_axisline_style("-|>")

# adds X and Y-axis from the origin
ax.axis[direction].set_visible(True)

for direction in ["left", "right", "bottom", "top"]:
# hides borders
for direction in ["top", "right"]: # Hide top and right axes.
ax.axis[direction].set_visible(False)

x = np.linspace(-0.5, 1., 100)
Expand Down
9 changes: 6 additions & 3 deletions examples/axisartist/simple_axisartist1.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
"""
==================
Simple Axisartist1
==================
========================================
Using axisartist to place an axis at y=0
========================================

Note that the following example can also be implemented without mpl_toolkits;
see :doc:`/gallery/ticks_and_spines/spine_placement_demo`.
"""

import matplotlib.pyplot as plt
from mpl_toolkits import axisartist

Expand Down
21 changes: 21 additions & 0 deletions examples/axisartist/simple_axisline.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,25 @@
ax.axis["right2"].label.set_text("Label Y2")

ax.plot([-2, 3, 2])

###############################################################################
# Or, without axisartist, one can use secondary axes to add the additional
# axes:

fig, ax = plt.subplots()
fig.subplots_adjust(right=0.85)

ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)

ax1 = ax.secondary_xaxis(0)
ax1.spines["bottom"].set_position(("data", 0))
ax1.set_xlabel("Axis Zero")

ax2 = ax.secondary_yaxis(1)
ax2.spines["right"].set_position(("outward", 20))
ax2.set_ylabel("Label Y2")

ax.plot([-2, 3, 2])

Copy link
Member

Choose a reason for hiding this comment

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

OK, this is nice. Can this be added as an example in the main spines section as well? Or moved there, with a link to it here? Putting this second in this section makes it look like this is a deprecated way to do it, whereas I think the goal is for it to be the canonical way.

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 removed the additions to simple_axisline2 and simple_axisartist1 and just linked them https://matplotlib.org/devdocs/gallery/ticks_and_spines/spine_placement_demo.html#sphx-glr-gallery-ticks-and-spines-spine-placement-demo-py instead.

I think I'll leave the multi-axes example as it is right now because there's no completely equivalent example elsewhere and I don't want to bother about proper explanations for now, but we can always move it there later (e.g. when we kill SubplotZero...).

plt.show()
11 changes: 7 additions & 4 deletions examples/axisartist/simple_axisline2.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
"""
================
Simple Axisline2
================
===================
SubplotZero example
===================

Note that the following example can also be implemented without mpl_toolkits;
see :doc:`/gallery/ticks_and_spines/spine_placement_demo`.
"""

import matplotlib.pyplot as plt
from mpl_toolkits.axisartist.axislines import SubplotZero
import numpy as np

fig = plt.figure(figsize=(4, 3))
fig = plt.figure()

# a subplot with two additional axis, "xzero" and "yzero". "xzero" is
# y=0 line, and "yzero" is x=0 line.
Expand Down
28 changes: 10 additions & 18 deletions lib/matplotlib/axes/_secondary_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ def __init__(self, parent, orientation, location, functions, **kwargs):
self._layoutbox = None
self._poslayoutbox = None

# Make this axes always follow the parent axes' position.
self.set_axes_locator(
_axes._InsetLocator([0, 0, 1, 1], self._parent.transAxes))

self.set_location(location)
self.set_functions(functions)

Expand All @@ -52,6 +56,7 @@ def __init__(self, parent, orientation, location, functions, **kwargs):
otheraxis.set_major_locator(mticker.NullLocator())
otheraxis.set_ticks_position('none')

self.patch.set_visible(False)
for st in self._otherstrings:
self.spines[st].set_visible(False)
for st in self._locstrings:
Expand Down Expand Up @@ -95,8 +100,7 @@ def set_location(self, location):
parent axes to put the new axes, 0.0 being the bottom (or left)
and 1.0 being the top (or right).
"""

# This puts the rectangle into figure-relative coordinates.
# Put the spine into axes-relative coordinates.
if isinstance(location, str):
if location in ['top', 'right']:
self._pos = 1.
Expand All @@ -108,22 +112,8 @@ def set_location(self, location):
f"{self._locstrings[1]!r}, or a float, not {location!r}")
else:
self._pos = location
self._loc = location

if self._orientation == 'x':
# An x-secondary axes is like an inset axes from x = 0 to x = 1 and
# from y = pos to y = pos + eps, in the parent's transAxes coords.
bounds = [0, self._pos, 1., 1e-10]
else:
bounds = [self._pos, 0, 1e-10, 1]

secondary_locator = _axes._InsetLocator(bounds, self._parent.transAxes)

# this locator lets the axes move in the parent axes coordinates.
# so it never needs to know where the parent is explicitly in
# figure coordinates.
# it gets called in `ax.apply_aspect() (of all places)
self.set_axes_locator(secondary_locator)
for loc in self._locstrings:
self.spines[loc].set_position(('axes', self._pos))

def apply_aspect(self, position=None):
# docstring inherited.
Expand Down Expand Up @@ -235,9 +225,11 @@ def _set_lims(self):
if self._orientation == 'x':
lims = self._parent.get_xlim()
set_lim = self.set_xlim
self.set_ylim(self._parent.get_ylim())
if self._orientation == 'y':
lims = self._parent.get_ylim()
set_lim = self.set_ylim
self.set_xlim(self._parent.get_xlim())
order = lims[0] < lims[1]
lims = self._functions[0](np.array(lims))
neworder = lims[0] < lims[1]
Expand Down