I’m working with existing code that creates a matplotlib figure with one axes, and adds a colorbar to it after-the-fact using make_axes_locatable
and append_axes
. It works, but I want to subsequently change the vertical height of the colorbar. I’ve figured out that this is only possible if I call the set_axes_locator(None)
method on the colorbar axis (not 100% sure why) — if I don’t do that, any calls to cax.set_position()
silently do nothing. Here’s the setup; question below:
import numpy as np import matplotlib.pyplot as plt from matplotlib.colorbar import ColorbarBase from mpl_toolkits.axes_grid1 import make_axes_locatable def make_figure(n_levels, shrink=False): data = np.random.randint(n_levels, size=(5, 7)) fig, ax = plt.subplots() ax.imshow(data) divider = make_axes_locatable(ax) cax = divider.append_axes('right', size='5%', pad=0.1) cmap = ax.images[0].get_cmap() cmap = cmap._resample(n_levels) _ = ColorbarBase(cax, cmap=cmap, norm=None, orientation='vertical') if shrink: shrink_colorbar(cax, n_levels) return fig def shrink_colorbar(cax, n_levels): pos = cax.get_position().bounds height = pos[-2] * n_levels new_y = pos[1] + (pos[-1] - height) / 2 newpos = (pos[0], new_y, pos[2], height) cax.set_axes_locator(None) cax.set_position(newpos)
If I do the colorbar resizing inside the function environment where the figure is created, I get the wrong result every time, whether I use regular Python REPL or iPython:
n_levels = 3 make_figure(n_levels, shrink=True)
WRONG RESULT:

If I create the figure first, then shrink the colorbar after the fact, it works how I want it to as long as these lines are run separately (either in regular Python REPL with plt.ion()
, or if each line is in a separate iPython cell):
fig = make_figure(n_levels) cax = fig.axes[-1] shrink_colorbar(cax, n_levels)
CORRECT RESULT:

If those same lines are run as a single iPython cell, or if run with plt.ioff()
in a regular Python REPL and followed by plt.show()
, I get the same bad result as the first example above (with shrink=True
in the outer function).
How can I get the correct result while still doing the colorbar resizing inside the function (instead of in userland)?