3

The previous answer from tcaswell on how to create shared axis for plots which are not on the same figure was perfect :) But I'm now wondering how to disable the shared axis and reenable them without having to redraw or destroy anything ? (I have multiple graphs and I want to add a button that the user can click to disable/enable those shared axes) I found a way :

import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(111)
fig2 = plt.figure()
ax2 = fig2.add_subplot(111, sharex=ax1)

to create the shared axis and then

fig2.delaxes(ax2)
ax2 = fig2.add_subplot(111)

but this require to redraw everything and can take some times. I didnt find a simple function to disable the link. Is there a lighter way than what I did ?

Thanks !

Community
  • 1
  • 1
Jdawleer
  • 165
  • 3
  • 9
  • adding link to the current (Feb 2018) WIP attempts to implement this: https://github.com/matplotlib/matplotlib/pull/9923 – drammock Feb 23 '18 at 21:56

3 Answers3

12

You can do:

ax2.get_shared_x_axes().remove(ax1)

References:

NotAGenie
  • 474
  • 5
  • 18
EEE
  • 501
  • 6
  • 13
  • 1
    Also, when creating a subplot using the `sharex` and/or `sharey` options e.g. `fig, axes = plt.subplots(nrows=3, ncols=3, sharex=True, sharey=True)`, `ax2.get_shared_x_axes()` contains the list of *all* axes. Hence one would need to do `ax12.get_shared_x_axes().remove(axis)` for each axis. Or better `[ax12.get_shared_x_axes().remove(axis) for axis in axes.ravel()]`. I am sharing this because it took me more than one try: `ax12.get_shared_x_axes()` is actually not a list but a `Grouper` object + `axes` is a multidimensional numpy array. You might consider adding that to your answer @EEE ;) – Gael Lorieul Jan 10 '20 at 21:15
  • 2
    This is now deprecated in matplotlib 3.6. What's the current intended approach? – Puff Jan 03 '23 at 19:06
  • ax2._shared_axes['x'].remove(ax2) worked for me – D.Thomas Aug 04 '23 at 08:59
4

There is no existing easy way to do this, however I think it can be done (it will just take a bit of digging into the matplotlib internals). The way that the axes are linked underneath is by simply using the same locator and formatter objects for both axis. To link/unlink you will have to copy/make new all of those objects, as well as update some ancillary structures (_shared_x_axes, _shared_y_axes). Look at the implementation of matplotlib.axes.Axes.cla() for some idea of what you need to do.

There is a pull request against the repo that adds this functionality and the associated feature request. If you are comfortable a) installing from source b) using master and c) applying this patch I think the developers would appreciate you testing this.

tacaswell
  • 84,579
  • 22
  • 210
  • 199
  • Thanks tcaswell ! I'll see what i can do. But I'm not really comfortable with your a) b) and c) since I'm still a beginner with python. But I'll already tried to digg a bit into the module to modify the navigation toolbar so I'll guess I'll digg again ! :) – Jdawleer Jan 31 '13 at 09:20
2

You can change the Grouper object that defines which plots are sharing their axes. The Grouper object for x axes can be found in ax1._shared_x_axes as well as in ax2._shared_x_axes, since it's the same object.

To stop sharing the x axis of the both plots, you can do ax2._shared_x_axes.remove(ax2).

In order to joining them again, do ax2._shared_x_axes.join(ax1,ax2).

If you want to understand better, you can check the documentation here. ax1._shared_x_axes is a Grouper object, in which ax1 and ax2 are the joint elements.

With the ax2.get_shared_x_axes() method you just can read it, but not change it. For aplying modifications, you need to access this object directly with ax2._shared_x_axes.

E. B.
  • 21
  • 1