diff --git a/doc/api/axes_api.rst b/doc/api/axes_api.rst index 84817c6d6bba..4e7e4174ffd3 100644 --- a/doc/api/axes_api.rst +++ b/doc/api/axes_api.rst @@ -447,8 +447,8 @@ Adding Artists Axes.add_table -Twinning -======== +Twinning and sharing +==================== .. autosummary:: :toctree: _as_gen @@ -458,6 +458,9 @@ Twinning Axes.twinx Axes.twiny + Axes.sharex + Axes.sharey + Axes.get_shared_x_axes Axes.get_shared_y_axes diff --git a/doc/users/next_whats_new/2020-01-24-lateshare.rst b/doc/users/next_whats_new/2020-01-24-lateshare.rst new file mode 100644 index 000000000000..fdb17c85a01a --- /dev/null +++ b/doc/users/next_whats_new/2020-01-24-lateshare.rst @@ -0,0 +1,8 @@ +`.Axes.sharex`, `.Axes.sharey` +------------------------------ +These new methods allow sharing axes *immediately* after creating them. For +example, they can be used to selectively link some axes created all together +using `~.Figure.subplots`. + +Note that they may *not* be used to share axes after any operation (e.g., +drawing) has occurred on them. diff --git a/examples/subplots_axes_and_figures/subplots_demo.py b/examples/subplots_axes_and_figures/subplots_demo.py index e4434808864c..e0bf7fe68521 100644 --- a/examples/subplots_axes_and_figures/subplots_demo.py +++ b/examples/subplots_axes_and_figures/subplots_demo.py @@ -176,6 +176,23 @@ for ax in axs.flat: ax.label_outer() +############################################################################### +# If you want a more complex sharing structure, you can first create the +# grid of axes with no sharing, and then call `.axes.Axes.sharex` or +# `.axes.Axes.sharey` to add sharing info a posteriori. + +fig, axs = plt.subplots(2, 2) +axs[0, 0].plot(x, y) +axs[0, 0].set_title("main") +axs[1, 0].plot(x, y**2) +axs[1, 0].set_title("shares x with main") +axs[1, 0].sharex(axs[0, 0]) +axs[0, 1].plot(x + 1, y + 1) +axs[0, 1].set_title("unrelated") +axs[1, 1].plot(x + 2, y + 2) +axs[1, 1].set_title("also unrelated") +fig.tight_layout() + ############################################################################### # Polar axes # """""""""" diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index 6d8eb4f8ebc6..23222d885298 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -487,16 +487,8 @@ def __init__(self, fig, rect, self._anchor = 'C' self._stale_viewlim_x = False self._stale_viewlim_y = False - self._sharex = sharex - self._sharey = sharey - if sharex is not None: - if not isinstance(sharex, _AxesBase): - raise TypeError('sharex must be an axes, not a bool') - self._shared_x_axes.join(self, sharex) - if sharey is not None: - if not isinstance(sharey, _AxesBase): - raise TypeError('sharey must be an axes, not a bool') - self._shared_y_axes.join(self, sharey) + self._sharex = None + self._sharey = None self.set_label(label) self.set_figure(fig) self.set_box_aspect(box_aspect) @@ -515,6 +507,11 @@ def __init__(self, fig, rect, self._rasterization_zorder = None self.cla() + if sharex is not None: + self.sharex(sharex) + if sharey is not None: + self.sharey(sharey) + # funcs used to format x and y - fall back on major formatters self.fmt_xdata = None self.fmt_ydata = None @@ -1008,6 +1005,44 @@ def _gen_axes_spines(self, locations=None, offset=0.0, units='inches'): return OrderedDict((side, mspines.Spine.linear_spine(self, side)) for side in ['left', 'right', 'bottom', 'top']) + def sharex(self, other): + """ + Share the x-axis with *other*. + + This is equivalent to passing ``sharex=other`` when constructing the + axes, and cannot be used if the x-axis is already being shared with + another axes. + """ + cbook._check_isinstance(_AxesBase, other=other) + if self._sharex is not None and other is not self._sharex: + raise ValueError("x-axis is already shared") + self._shared_x_axes.join(self, other) + self._sharex = other + self.xaxis.major = other.xaxis.major # Ticker instances holding + self.xaxis.minor = other.xaxis.minor # locator and formatter. + x0, x1 = other.get_xlim() + self.set_xlim(x0, x1, emit=False, auto=other.get_autoscalex_on()) + self.xaxis._scale = other.xaxis._scale + + def sharey(self, other): + """ + Share the y-axis with *other*. + + This is equivalent to passing ``sharey=other`` when constructing the + axes, and cannot be used if the y-axis is already being shared with + another axes. + """ + cbook._check_isinstance(_AxesBase, other=other) + if self._sharey is not None and other is not self._sharey: + raise ValueError("y-axis is already shared") + self._shared_y_axes.join(self, other) + self._sharey = other + self.yaxis.major = other.yaxis.major # Ticker instances holding + self.yaxis.minor = other.yaxis.minor # locator and formatter. + y0, y1 = other.get_ylim() + self.set_ylim(y0, y1, emit=False, auto=other.get_autoscaley_on()) + self.yaxis._scale = other.yaxis._scale + def cla(self): """Clear the current axes.""" # Note: this is called by Axes.__init__() @@ -1031,38 +1066,25 @@ def cla(self): self.callbacks = cbook.CallbackRegistry() if self._sharex is not None: - # major and minor are axis.Ticker class instances with - # locator and formatter attributes - self.xaxis.major = self._sharex.xaxis.major - self.xaxis.minor = self._sharex.xaxis.minor - x0, x1 = self._sharex.get_xlim() - self.set_xlim(x0, x1, emit=False, - auto=self._sharex.get_autoscalex_on()) - self.xaxis._scale = self._sharex.xaxis._scale + self.sharex(self._sharex) else: self.xaxis._set_scale('linear') try: self.set_xlim(0, 1) except TypeError: pass - if self._sharey is not None: - self.yaxis.major = self._sharey.yaxis.major - self.yaxis.minor = self._sharey.yaxis.minor - y0, y1 = self._sharey.get_ylim() - self.set_ylim(y0, y1, emit=False, - auto=self._sharey.get_autoscaley_on()) - self.yaxis._scale = self._sharey.yaxis._scale + self.sharey(self._sharey) else: self.yaxis._set_scale('linear') try: self.set_ylim(0, 1) except TypeError: pass + # update the minor locator for x and y axis based on rcParams if mpl.rcParams['xtick.minor.visible']: self.xaxis.set_minor_locator(mticker.AutoMinorLocator()) - if mpl.rcParams['ytick.minor.visible']: self.yaxis.set_minor_locator(mticker.AutoMinorLocator()) @@ -1144,11 +1166,10 @@ def cla(self): self._shared_x_axes.clean() self._shared_y_axes.clean() - if self._sharex: + if self._sharex is not None: self.xaxis.set_visible(xaxis_visible) self.patch.set_visible(patch_visible) - - if self._sharey: + if self._sharey is not None: self.yaxis.set_visible(yaxis_visible) self.patch.set_visible(patch_visible) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy