Python – Matplotlib (GridSpec) – Subgraph axis labels cut off? Tried ‘tight_layout’

Matplotlib (GridSpec) – Subgraph axis labels cut off? Tried ‘tight_layout’… here is a solution to the problem.

Matplotlib (GridSpec) – Subgraph axis labels cut off? Tried ‘tight_layout’

I’m using GridSpec to organize subgraphs. I share a colorbar for all drawings.

All the online suggestions seem to point to tight_layout() as the solution to the axis label cut-off issue, but that doesn’t seem to work here (unless it comes in another form I don’t know).

I’ve also tried using the rect parameters of tight_layout for fig, plt, and gs

import matplotlib
import matplotlib.pyplot as plt
import numpy as np 
from pylab import *
import matplotlib.gridspec as gridspec
import matplotlib.colors
from mpl_toolkits.mplot3d import Axes3D

gs = gridspec. GridSpec(1,7,hspace=0.05,wspace=0.5, width_ratios=[1,1,1,1,1,1,0.1])
figure(num=None, figsize=(18, 2), dpi=80, facecolor='w', edgecolor='k')

data = np.random.rand(3,6,224,5)

for i in range(6):
    ax = plt.subplot(gs[0, i], projection='3d')
    p = ax.scatter(data[0,i,:,0], data[0,i,:,1], data[0,i,:,2], c=data[0,i,:,4], marker='o')
    title("Case " + str(i+1))
    ax.set_xlabel('Batch Size', linespacing=3)
    ax.set_ylabel('Window Size', linespacing=3)
    ax.set_zlabel('Neurons', linespacing=3)
    ax.xaxis.labelpad=20
    ax.yaxis.labelpad=20
    ax.zaxis.labelpad=10

cbar = plt.subplot(gs[0,6])
colorbar(p, cax=cbar, label='RMSE')

plt.show()

This generates the following image.

enter image description here

Solution

As mentioned in the comment, setting the bottom parameter to a larger value, such as bottom=0.3, will give you more room to hold the shaft decorator.

Also, in order not to shrink the graph too much, it may be useful to make the graph slightly taller, such as 3 inches instead of 2 inches.

import matplotlib.pyplot as plt
import numpy as np 
import matplotlib.gridspec as gridspec
from mpl_toolkits.mplot3d import Axes3D

gs = gridspec. GridSpec(1,7,hspace=0.05,wspace=0.5, bottom=0.3,
                       left=0.02, right=0.95, width_ratios=[1,1,1,1,1,1,0.1])
fig = plt.figure(figsize=(18, 3), dpi=80, facecolor='w', edgecolor='k')

data = np.random.rand(3,6,224,5)

for i in range(6):
    ax = plt.subplot(gs[0, i], projection='3d')
    p = ax.scatter(data[0,i,:,0], data[0,i,:,1], data[0,i,:,2], 
                   c=data[0,i,:,4], marker='o')
    ax.set_title("Case " + str(i+1))
    ax.set_xlabel('Batch Size', linespacing=3)
    ax.set_ylabel('Window Size', linespacing=3)
    ax.set_zlabel('Neurons', linespacing=3)
    ax.xaxis.labelpad=20
    ax.yaxis.labelpad=20
    ax.zaxis.labelpad=10

cbar = plt.subplot(gs[0,6])
fig.colorbar(p, cax=cbar, label='RMSE')

# This is only needed for jupyter
fig.add_axes([0,0,1,1]).axis("off")

plt.show()

enter image description here

Unfortunately, in jupyter, the %matplotlib inline backend always creates its image with the bbox_inches="tight" setting. Therefore, one workaround is to create some elements in the diagram to ensure that the “tight” area is large enough. Here, an option is to use fig.add_axes([0,0,1,1]).axis("off").

Related Problems and Solutions