Home > Enterprise >  Matplotlib : How to separate the last subplot line and the last subplot column in a figure?
Matplotlib : How to separate the last subplot line and the last subplot column in a figure?

Time:07-22

Using matplotlib, I plotted n x n subplots (n=8 in this example):

fig, ax = plt.subplots(8,8, figsize=(18,10), sharex='col', sharey='row')
fig.subplots_adjust(hspace=0, wspace=0)

enter image description here

And I would like to separate the last line and the last column to obtain something like this :

enter image description here

Must I use Gridspec (as in the answer enter image description here

But, now I have to remove inside axis labels and to keep only the outside ones.

Edit2

It works with this code :

import matplotlib
n=7
m=5
outer_gs = matplotlib.gridspec.GridSpec(2,2, height_ratios=[n,1], width_ratios=[m,1], hspace=0.1, wspace=0.1)
inner_gs = matplotlib.gridspec.GridSpecFromSubplotSpec(n,m, subplot_spec=outer_gs[0,0], hspace=0, wspace=0)
line_gs = matplotlib.gridspec.GridSpecFromSubplotSpec(n,1, subplot_spec=outer_gs[0,1], hspace=0, wspace=0.1)
col_gs = matplotlib.gridspec.GridSpecFromSubplotSpec(1,m, subplot_spec=outer_gs[1,0], hspace=0.1, wspace=0)
ax_11=[]
ax_12=[]
ax_21=[]
ax_22=[]
fig = plt.figure(figsize=(18,10))
for i in range (n):
    ax_11.append([])
    for j in range(m):
        ax_11[i].append(fig.add_subplot(inner_gs[i,j]))
        if not ax_11[i][j].get_subplotspec().is_first_col():
            ax_11[i][j].axes.yaxis.set_visible(False)
        ax_11[i][j].axes.xaxis.set_visible(False)
        
for i in range(n):
        ax_12.append(fig.add_subplot(line_gs[i,0]))
        ax_12[i].axes.yaxis.set_visible(False)
        ax_12[i].axes.xaxis.set_visible(False)
        
for i in range(m):
        ax_21.append(fig.add_subplot(col_gs[0,i]))
        if not ax_21[i].get_subplotspec().is_first_col():
            ax_21[i].axes.yaxis.set_visible(False)

ax_22 = fig.add_subplot(outer_gs[1,1])
ax_22.axes.yaxis.set_visible(False);

enter image description here

But, I wonder if it is the simplest method to obtain such figure. I am discovering matplotlib and I am not sure that this code is good even if it gives the expected result.

CodePudding user response:

Based on this enter image description here

CodePudding user response:

An alternative method would be to continue to use plt.subplots() to create your axes, but add an extra column and row for the gap, which you can remove after creation.

Note this methods means your axes will continue to be shared, and there is no need to turn tick labels on or off for specific axes.

Using the height_ratios and width_ratios options for gridspec_kw, we can control how high and wide those gaps will be. In the example below, I set them to be one fifth of the regular axes dimensions, but that is easy to change to suit your needs.

We can remove the dummy axes using the .remove() method on them. And then so they don't get in the way of our ax array, we can using numpy.delete to remove those slices.

For example:

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(9, 9, figsize=(18, 10), sharex='col', sharey='row',
                       gridspec_kw={
                           'height_ratios': (1, 1, 1, 1, 1, 1, 1, 0.2, 1), 
                           'width_ratios': (1, 1, 1, 1, 1, 1, 1, 0.2, 1),
                           'hspace': 0, 'wspace': 0
                           })

# remove 8th column
for dax in ax[:, 7]:
    dax.remove()
ax = np.delete(ax, 7, 1)

# remove 8th row
for dax in ax[7, :]:
    dax.remove()
ax = np.delete(ax, 7, 0)

plt.show()

enter image description here

  • Related