Share axes in matplotlib for only part of the subplots

I am having a big plot where I initiated with:

import numpy as np
import matplotlib.pyplot as plt

fig, axs = plt.subplots(5, 4)

And I want to do share-x-axis between column 1 and 2; and do the same between column 3 and 4. However, column 1 and 2 does not share the same axis with column 3 and 4.

I was wondering that would there be anyway to do this, and not sharex=True and sharey=True across all figures?

PS: This tutorial does not help too much, because it is only about sharing x/y within each row/column; they cannot do axis sharing between different rows/columns (unless share them across all axes).


I'm not exactly sure what you want to achieve from your question. However, you can specify per subplot which axis it should share with which subplot when adding a subplot to your figure.

This can be done via:

import matplotlib.pylab as plt

fig = plt.figure()

ax1 = fig.add_subplot(5, 4, 1)
ax2 = fig.add_subplot(5, 4, 2, sharex = ax1)
ax3 = fig.add_subplot(5, 4, 3, sharex = ax1, sharey = ax1)

Hope that helps


A slightly limited but much simpler option is available for subplots. The limitation is there for a complete row or column of subplots. For example, if one wants to have common y axis for all the subplots but common x axis only for individual columns in a 3x2 subplot, one could specify it as:

import matplotlib.pyplot as plt
fig, ax = plt.subplots(3, 2, sharey=True, sharex='col')

One can manually manage axes sharing using a Grouper object, which can be accessed via ax._shared_x_axes and ax._shared_y_axes. For example,

import matplotlib.pyplot as plt

def set_share_axes(axs, target=None, sharex=False, sharey=False):
    if target is None:
        target = axs.flat[0]
    # Manage share using grouper objects
    for ax in axs.flat:
        if sharex:
            target._shared_x_axes.join(target, ax)
        if sharey:
            target._shared_y_axes.join(target, ax)
    # Turn off x tick labels and offset text for all but the bottom row
    if sharex and axs.ndim > 1:
        for ax in axs[:-1,:].flat:
            ax.xaxis.set_tick_params(which='both', labelbottom=False, labeltop=False)
            ax.xaxis.offsetText.set_visible(False)
    # Turn off y tick labels and offset text for all but the left most column
    if sharey and axs.ndim > 1:
        for ax in axs[:,1:].flat:
            ax.yaxis.set_tick_params(which='both', labelleft=False, labelright=False)
            ax.yaxis.offsetText.set_visible(False)

fig, axs = plt.subplots(5, 4)
set_share_axes(axs[:,:2], sharex=True)
set_share_axes(axs[:,2:], sharex=True)

To adjust the spacing between subplots in a grouped manner, please refer to this question.