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

Appearance settings

Commit 9085810

Browse filesBrowse files
authored
Merge pull request #15287 from anntzer/lateshare
Allow sharex/y after axes creation.
2 parents ce42e8e + 83c2d7b commit 9085810
Copy full SHA for 9085810

File tree

Expand file treeCollapse file tree

4 files changed

+80
-31
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+80
-31
lines changed

‎doc/api/axes_api.rst

Copy file name to clipboardExpand all lines: doc/api/axes_api.rst
+5-2Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -447,8 +447,8 @@ Adding Artists
447447
Axes.add_table
448448

449449

450-
Twinning
451-
========
450+
Twinning and sharing
451+
====================
452452

453453
.. autosummary::
454454
:toctree: _as_gen
@@ -458,6 +458,9 @@ Twinning
458458
Axes.twinx
459459
Axes.twiny
460460

461+
Axes.sharex
462+
Axes.sharey
463+
461464
Axes.get_shared_x_axes
462465
Axes.get_shared_y_axes
463466

+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
`.Axes.sharex`, `.Axes.sharey`
2+
------------------------------
3+
These new methods allow sharing axes *immediately* after creating them. For
4+
example, they can be used to selectively link some axes created all together
5+
using `~.Figure.subplots`.
6+
7+
Note that they may *not* be used to share axes after any operation (e.g.,
8+
drawing) has occurred on them.

‎examples/subplots_axes_and_figures/subplots_demo.py

Copy file name to clipboardExpand all lines: examples/subplots_axes_and_figures/subplots_demo.py
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,23 @@
176176
for ax in axs.flat:
177177
ax.label_outer()
178178

179+
###############################################################################
180+
# If you want a more complex sharing structure, you can first create the
181+
# grid of axes with no sharing, and then call `.axes.Axes.sharex` or
182+
# `.axes.Axes.sharey` to add sharing info a posteriori.
183+
184+
fig, axs = plt.subplots(2, 2)
185+
axs[0, 0].plot(x, y)
186+
axs[0, 0].set_title("main")
187+
axs[1, 0].plot(x, y**2)
188+
axs[1, 0].set_title("shares x with main")
189+
axs[1, 0].sharex(axs[0, 0])
190+
axs[0, 1].plot(x + 1, y + 1)
191+
axs[0, 1].set_title("unrelated")
192+
axs[1, 1].plot(x + 2, y + 2)
193+
axs[1, 1].set_title("also unrelated")
194+
fig.tight_layout()
195+
179196
###############################################################################
180197
# Polar axes
181198
# """"""""""

‎lib/matplotlib/axes/_base.py

Copy file name to clipboardExpand all lines: lib/matplotlib/axes/_base.py
+50-29Lines changed: 50 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -487,16 +487,8 @@ def __init__(self, fig, rect,
487487
self._anchor = 'C'
488488
self._stale_viewlim_x = False
489489
self._stale_viewlim_y = False
490-
self._sharex = sharex
491-
self._sharey = sharey
492-
if sharex is not None:
493-
if not isinstance(sharex, _AxesBase):
494-
raise TypeError('sharex must be an axes, not a bool')
495-
self._shared_x_axes.join(self, sharex)
496-
if sharey is not None:
497-
if not isinstance(sharey, _AxesBase):
498-
raise TypeError('sharey must be an axes, not a bool')
499-
self._shared_y_axes.join(self, sharey)
490+
self._sharex = None
491+
self._sharey = None
500492
self.set_label(label)
501493
self.set_figure(fig)
502494
self.set_box_aspect(box_aspect)
@@ -515,6 +507,11 @@ def __init__(self, fig, rect,
515507
self._rasterization_zorder = None
516508
self.cla()
517509

510+
if sharex is not None:
511+
self.sharex(sharex)
512+
if sharey is not None:
513+
self.sharey(sharey)
514+
518515
# funcs used to format x and y - fall back on major formatters
519516
self.fmt_xdata = None
520517
self.fmt_ydata = None
@@ -1008,6 +1005,44 @@ def _gen_axes_spines(self, locations=None, offset=0.0, units='inches'):
10081005
return OrderedDict((side, mspines.Spine.linear_spine(self, side))
10091006
for side in ['left', 'right', 'bottom', 'top'])
10101007

1008+
def sharex(self, other):
1009+
"""
1010+
Share the x-axis with *other*.
1011+
1012+
This is equivalent to passing ``sharex=other`` when constructing the
1013+
axes, and cannot be used if the x-axis is already being shared with
1014+
another axes.
1015+
"""
1016+
cbook._check_isinstance(_AxesBase, other=other)
1017+
if self._sharex is not None and other is not self._sharex:
1018+
raise ValueError("x-axis is already shared")
1019+
self._shared_x_axes.join(self, other)
1020+
self._sharex = other
1021+
self.xaxis.major = other.xaxis.major # Ticker instances holding
1022+
self.xaxis.minor = other.xaxis.minor # locator and formatter.
1023+
x0, x1 = other.get_xlim()
1024+
self.set_xlim(x0, x1, emit=False, auto=other.get_autoscalex_on())
1025+
self.xaxis._scale = other.xaxis._scale
1026+
1027+
def sharey(self, other):
1028+
"""
1029+
Share the y-axis with *other*.
1030+
1031+
This is equivalent to passing ``sharey=other`` when constructing the
1032+
axes, and cannot be used if the y-axis is already being shared with
1033+
another axes.
1034+
"""
1035+
cbook._check_isinstance(_AxesBase, other=other)
1036+
if self._sharey is not None and other is not self._sharey:
1037+
raise ValueError("y-axis is already shared")
1038+
self._shared_y_axes.join(self, other)
1039+
self._sharey = other
1040+
self.yaxis.major = other.yaxis.major # Ticker instances holding
1041+
self.yaxis.minor = other.yaxis.minor # locator and formatter.
1042+
y0, y1 = other.get_ylim()
1043+
self.set_ylim(y0, y1, emit=False, auto=other.get_autoscaley_on())
1044+
self.yaxis._scale = other.yaxis._scale
1045+
10111046
def cla(self):
10121047
"""Clear the current axes."""
10131048
# Note: this is called by Axes.__init__()
@@ -1031,38 +1066,25 @@ def cla(self):
10311066
self.callbacks = cbook.CallbackRegistry()
10321067

10331068
if self._sharex is not None:
1034-
# major and minor are axis.Ticker class instances with
1035-
# locator and formatter attributes
1036-
self.xaxis.major = self._sharex.xaxis.major
1037-
self.xaxis.minor = self._sharex.xaxis.minor
1038-
x0, x1 = self._sharex.get_xlim()
1039-
self.set_xlim(x0, x1, emit=False,
1040-
auto=self._sharex.get_autoscalex_on())
1041-
self.xaxis._scale = self._sharex.xaxis._scale
1069+
self.sharex(self._sharex)
10421070
else:
10431071
self.xaxis._set_scale('linear')
10441072
try:
10451073
self.set_xlim(0, 1)
10461074
except TypeError:
10471075
pass
1048-
10491076
if self._sharey is not None:
1050-
self.yaxis.major = self._sharey.yaxis.major
1051-
self.yaxis.minor = self._sharey.yaxis.minor
1052-
y0, y1 = self._sharey.get_ylim()
1053-
self.set_ylim(y0, y1, emit=False,
1054-
auto=self._sharey.get_autoscaley_on())
1055-
self.yaxis._scale = self._sharey.yaxis._scale
1077+
self.sharey(self._sharey)
10561078
else:
10571079
self.yaxis._set_scale('linear')
10581080
try:
10591081
self.set_ylim(0, 1)
10601082
except TypeError:
10611083
pass
1084+
10621085
# update the minor locator for x and y axis based on rcParams
10631086
if mpl.rcParams['xtick.minor.visible']:
10641087
self.xaxis.set_minor_locator(mticker.AutoMinorLocator())
1065-
10661088
if mpl.rcParams['ytick.minor.visible']:
10671089
self.yaxis.set_minor_locator(mticker.AutoMinorLocator())
10681090

@@ -1144,11 +1166,10 @@ def cla(self):
11441166

11451167
self._shared_x_axes.clean()
11461168
self._shared_y_axes.clean()
1147-
if self._sharex:
1169+
if self._sharex is not None:
11481170
self.xaxis.set_visible(xaxis_visible)
11491171
self.patch.set_visible(patch_visible)
1150-
1151-
if self._sharey:
1172+
if self._sharey is not None:
11521173
self.yaxis.set_visible(yaxis_visible)
11531174
self.patch.set_visible(patch_visible)
11541175

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.