How to adjust columns widths with gridspec?

Question:

How can I fix this plot?

I want:

  1. both color bars not overlap.
  2. make their height equal to the plot.

Here is my code:

combined = (...) # some irrelevant to question data praparation - this variable contain square matrix with RGBA chanels

plt.figure(dpi=300, figsize=(2.1,1.9))
gs = gridspec.GridSpec(1, 3, width_ratios=[20,1,1])
ax1 = plt.subplot(gs[0])
ax2 = plt.subplot(gs[1])
ax3 = plt.subplot(gs[2])

cax = ax1.imshow(combined, interpolation="None")
mpl.colorbar.ColorbarBase(ax2, cmap=cmap_top, norm=norm_top)
mpl.colorbar.ColorbarBase(ax3, cmap=cmap_top, norm=norm_top)

I’m using python 3.6 and matplotlib 2.0.

broken plot

Asked By: user31027

||

Answers:

A suggestion would be not to use gridspec in this case. You can create new colorbar axes by using the make_axes_locatable class from the mpl_toolkits.axes_grid1.

You would then need to find some fitting parameters for the padding of the divider, as well as for the figure margins (using subplots_adjust).

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import matplotlib.colorbar
import numpy as np; np.random.seed(1)

a = -np.log10(np.random.rand(25,25))

fig, ax = plt.subplots(dpi=300, figsize=(2.1,1.9))
fig.subplots_adjust(left=0.15,right=.78)

cmap=plt.cm.terrain
norm = matplotlib.colors.LogNorm(1e-3, 4)

im = ax.imshow(a, interpolation="None", cmap=cmap, norm=norm)

divider = make_axes_locatable(ax)
cax = divider.new_horizontal(size="5%", pad=0.05)
cax2 = divider.new_horizontal(size="5%", pad=0.45)

fig.add_axes(cax)
fig.add_axes(cax2)

plt.colorbar(im, cax=cax)
plt.colorbar(im, cax=cax2)

plt.show()

enter image description here

Making enough space such that the colorbar ticklabels don’t overlap takes in this case almost half the figure width, but I suppose this is how you want it.

I would consider two possibilities for problem number 1:
a. Modify the wspace parameter that controls horizontal space between figures i.e. :

gs = gridspec.GridSpec(1, 3, width_ratios=[20,1,1])
gs.update(wspace=0.05)

b. Add an extra column between the first and second colorbar that acts as some void space:

gs = gridspec.GridSpec(1, 4, width_ratios=[20,1,0.15,1])

As for problem number 2, I would write it differently:

ax2=plt.subplot(gs[0,1]  )
cb1 = matplotlib.colorbar.ColorbarBase(ax2, cmap="RdBu_r")

Hope it helps!

Answered By: Sergio Cobo
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.