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

Commitcfcd9a7

Browse files
committed
Improve(?) implementation of secondary_axis.
Currently, secondary_xaxis is implemented by adding a child axes with aphysical height set to zero and y position set accordingly relative toits parent axes (using the axes_locator mechanism).This patch changes it so that the child axes' extents actually*matches* the parent axes, and instead positioning the spines usingSpine.set_position. It also makes sure that the secondary axes patch isinvisible and that the bounds of the "orthogonal" axis (the one that isnot shown) matches the parent bounds.By doing so, it becomes possible to plot data directly on the secondaryaxis as well; e.g. the following now works:```from matplotlib import pyplot as pltfrom matplotlib.axes import Axesfig, ax0 = plt.subplots()ax1 = ax0.secondary_xaxis( "top", functions=(lambda x: x**3, lambda x: x**(1/3)))Axes.plot(ax1, [.25, .5, .75], [.25, .5, .75], ".-")plt.show()```(We have to use Axes.plot here instead of ax1.plot just becauseSecondaryAxes inherits from _AxesBase, not from Axes, but that doesn'treally matter.)Another advantage is that one can now use secondary_axis as areplacement for SubplotZero, a relatively obscure feature ofmpl_toolkits that is only showcased in 3 examples:https://matplotlib.org/gallery/axisartist/simple_axisline.htmlhttps://matplotlib.org/gallery/axisartist/simple_axisline2.htmlhttps://matplotlib.org/gallery/axisartist/demo_axisline_style.htmlwhose goal is just to draw a spine at x=0 or y=0.simple_axisline2 just moves its main spine to y=0, so we can implementthat directly with Spine.set_position (see also simple_axisartist1).simple_axisline adds additional spines, and I added an equivalentimplementation using secondary_axis, which is fairly transparent.(This example, as well as test_secondary_xy, show why the axes patchmust be made invisible: otherwise, the patch of later secondary axeswould be drawn over other secondary axes.)demo_axisline_style doesn't showcase anything that's specificallyrelated to SubplotZero so I just rewrote it without SubplotZero.If we agree that secondary_axis is a suitable replacement, SubplotZerocould ultimately be deprecated (in a later PR).Minor points:Also delete `SecondaryAxis._loc`, which is set in a single place andnever used.
1 parentdb2193c commitcfcd9a7

File tree

5 files changed

+50
-58
lines changed

5 files changed

+50
-58
lines changed

‎examples/axisartist/demo_axisline_style.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,19 @@
66
This example shows some configurations for axis style.
77
"""
88

9-
frommpl_toolkits.axisartist.axislinesimportSubplotZero
9+
frommpl_toolkits.axisartist.axislinesimportSubplot
1010
importmatplotlib.pyplotasplt
1111
importnumpyasnp
1212

1313

1414
fig=plt.figure()
15-
ax=SubplotZero(fig,111)
15+
ax=Subplot(fig,111)
1616
fig.add_subplot(ax)
1717

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

22-
# adds X and Y-axis from the origin
23-
ax.axis[direction].set_visible(True)
24-
25-
fordirectionin ["left","right","bottom","top"]:
26-
# hides borders
21+
fordirectionin ["top","right"]:# Hide top and right axes.
2722
ax.axis[direction].set_visible(False)
2823

2924
x=np.linspace(-0.5,1.,100)

‎examples/axisartist/simple_axisartist1.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
"""
2-
==================
3-
Simple Axisartist1
4-
==================
2+
========================================
3+
Using axisartist to place an axis at y=0
4+
========================================
55
6+
Note that the following example can also be implemented without mpl_toolkits;
7+
see :doc:`/gallery/ticks_and_spines/spine_placement_demo`.
68
"""
9+
710
importmatplotlib.pyplotasplt
811
importmpl_toolkits.axisartistasAA
912

‎examples/axisartist/simple_axisline.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,25 @@
3737
ax.axis["right2"].label.set_text("Label Y2")
3838

3939
ax.plot([-2,3,2])
40+
41+
###############################################################################
42+
# Or, without axisartist, one can use secondary axes to add the additional
43+
# axes:
44+
45+
fig,ax=plt.subplots()
46+
fig.subplots_adjust(right=0.85)
47+
48+
ax.spines["top"].set_visible(False)
49+
ax.spines["right"].set_visible(False)
50+
51+
ax1=ax.secondary_xaxis(0)
52+
ax1.spines["bottom"].set_position(("data",0))
53+
ax1.set_xlabel("Axis Zero")
54+
55+
ax2=ax.secondary_yaxis(1)
56+
ax2.spines["right"].set_position(("outward",20))
57+
ax2.set_ylabel("Label Y2")
58+
59+
ax.plot([-2,3,2])
60+
4061
plt.show()

‎examples/axisartist/simple_axisline2.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
"""
2-
================
3-
Simple Axisline2
4-
================
2+
===================
3+
SubplotZero example
4+
===================
55
6+
Note that the following example can also be implemented without mpl_toolkits;
7+
see :doc:`/gallery/ticks_and_spines/spine_placement_demo`.
68
"""
9+
710
importmatplotlib.pyplotasplt
811
frommpl_toolkits.axisartist.axislinesimportSubplotZero
912
importnumpyasnp
1013

11-
fig=plt.figure(figsize=(4,3))
14+
fig=plt.figure()
1215

1316
# a subplot with two additional axis, "xzero" and "yzero". "xzero" is
1417
# y=0 line, and "yzero" is x=0 line.

‎lib/matplotlib/axes/_secondary_axes.py

Lines changed: 12 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -27,33 +27,6 @@
2727
frommatplotlib.scaleimportLog10Transform
2828

2929

30-
def_make_secondary_locator(rect,parent):
31-
"""
32-
Helper function to locate the secondary axes.
33-
34-
A locator gets used in `Axes.set_aspect` to override the default
35-
locations... It is a function that takes an axes object and
36-
a renderer and tells `set_aspect` where it is to be placed.
37-
38-
This locator make the transform be in axes-relative co-coordinates
39-
because that is how we specify the "location" of the secondary axes.
40-
41-
Here *rect* is a rectangle [l, b, w, h] that specifies the
42-
location for the axes in the transform given by *trans* on the
43-
*parent*.
44-
"""
45-
_rect=mtransforms.Bbox.from_bounds(*rect)
46-
defsecondary_locator(ax,renderer):
47-
# delay evaluating transform until draw time because the
48-
# parent transform may have changed (i.e. if window reesized)
49-
bb=mtransforms.TransformedBbox(_rect,parent.transAxes)
50-
tr=parent.figure.transFigure.inverted()
51-
bb=mtransforms.TransformedBbox(bb,tr)
52-
returnbb
53-
54-
returnsecondary_locator
55-
56-
5730
classSecondaryAxis(_AxesBase):
5831
"""
5932
General class to hold a Secondary_X/Yaxis.
@@ -86,6 +59,12 @@ def __init__(self, parent, orientation,
8659
self._layoutbox=None
8760
self._poslayoutbox=None
8861

62+
# Make this axes always follow the parent axes' position.
63+
self.set_axes_locator(
64+
lambdaax,renderer:
65+
self.figure.transFigure.inverted()
66+
.transform_bbox(self._parent.bbox))
67+
8968
self.set_location(location)
9069
self.set_functions(functions)
9170

@@ -98,6 +77,7 @@ def __init__(self, parent, orientation,
9877
otheraxis.set_major_locator(mticker.NullLocator())
9978
otheraxis.set_ticks_position('none')
10079

80+
self.patch.set_visible(False)
10181
forstinself._otherstrings:
10282
self.spines[st].set_visible(False)
10383
forstinself._locstrings:
@@ -161,20 +141,8 @@ def set_location(self, location):
161141
self._locstrings[0],self._locstrings[1]))
162142
else:
163143
self._pos=location
164-
self._loc=location
165-
166-
ifself._orientation=='x':
167-
bounds= [0,self._pos,1.,1e-10]
168-
else:
169-
bounds= [self._pos,0,1e-10,1]
170-
171-
secondary_locator=_make_secondary_locator(bounds,self._parent)
172-
173-
# this locator lets the axes move in the parent axes coordinates.
174-
# so it never needs to know where the parent is explicitly in
175-
# figure co-ordinates.
176-
# it gets called in `ax.apply_aspect() (of all places)
177-
self.set_axes_locator(secondary_locator)
144+
forlocinself._locstrings:
145+
self.spines[loc].set_position(('axes',self._pos))
178146

179147
defapply_aspect(self,position=None):
180148
self._set_lims()
@@ -290,14 +258,16 @@ def _set_scale(self):
290258
def_set_lims(self):
291259
"""
292260
Set the limits based on parent limits and the convert method
293-
between the parent and this secondary axes
261+
between the parent and this secondary axes.
294262
"""
295263
ifself._orientation=='x':
296264
lims=self._parent.get_xlim()
297265
set_lim=self.set_xlim
266+
self.set_ylim(self._parent.get_ylim())
298267
ifself._orientation=='y':
299268
lims=self._parent.get_ylim()
300269
set_lim=self.set_ylim
270+
self.set_xlim(self._parent.get_xlim())
301271
order=lims[0]<lims[1]
302272
lims=self._functions[0](np.array(lims))
303273
neworder=lims[0]<lims[1]

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp