Share axes in matplotlib for only part of the subplots

PythonMatplotlibScipy

Python Problem Overview


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).

Python Solutions


Solution 1 - Python

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

Solution 2 - Python

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')

Solution 3 - Python

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionYuxiang WangView Question on Stackoverflow
Solution 1 - PythonThe DudeView Answer on Stackoverflow
Solution 2 - PythonVinod KumarView Answer on Stackoverflow
Solution 3 - Pythonherrlich10View Answer on Stackoverflow