2

I am using Matplotlib 1.5.3 in Python 3. I have a 3x3 subplot structure, or more generically an unspecified subplot structure that I'm trying to add a color bar to. As per this thread, an apparently good way to do this is to distort the subplots with subplots_adjust(), and add the colorbar as a new axes. Except, I have tight_layout() enabled, and that totally messes with things. Here is the function that, based on what I have read about subplots_adjust(), should work:

import matplotlib.pyplot as plt

def add_colorbar(last_im):
    SPACE   = 0.2  # portion of final width reserved for colorbar and its padding
    PADDING = 0.5  # portion of reserved space reserved for padding
    fig = plt.gcf()

    # expand image to make room for colorbar
    w,h = fig.get_size_inches()
    fig.set_size_inches((w/(1-SPACE), h))

    # shrink right side of subplot to create empty space on
    # right hand side
    fig.subplots_adjust(right=0.9*(1-SPACE)) # 0.9 being the original value

    # create colorbar axes, place in empty space with padding
    cbax = fig.add_axes([1-SPACE*(1-PADDING/2), 0.15,
                         SPACE*(1-PADDING),     0.7])
    fig.colorbar(last_im, cax=cbax)

But the subplot configuration is kept centered, so this creates basically no space, and the color bar is drawn straight over the subplots. I have also tried using plt.tight_layout(rect=[0, 0, 1-SPACE, 1]) instead of subplots_adjust(), but this seems to do even less than the subplots_adjust() statement, and messes with basically just the sizes of the individual subplots. It seems neither of these functions work as advertised for me. What am I missing? Faulty plot shown below, with plot titles censored to be on the safe side.

faulty plot

Alternatively, I'd be fine with a solution for adding a colorbar that will generically work for a figure with any subplot configuration, but I'd prefer to understand the baffling behavior of subplots_adjust() and the tight_layout() rect.

EDIT: Problem ended up being that I made tight_layout() calls erroneously after running add_colorbar(). Correct behavior is observed now that I have removed the calls.

mszegedy
  • 185
  • 1
  • 9
  • 1
    This function seems to be working for me in matplotlib 2.1.0. Could you show how you are calling this function? i.e. a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve). – DavidG Nov 10 '17 at 09:02
  • The short answer is: `tight_layout()` overwrites any setting that has been done via `subplots_adjust()`. So don't call `tight_layout()` after `subplots_adjust()`. Did you look at other answers in that question you link to? An alternative would be to make the colorbar part of the subplots grid. – ImportanceOfBeingErnest Nov 10 '17 at 09:54
  • Also, the rect parameter used is wrong. You can try `plt.tight_layout(rect=[0, 0.8, 0, 1])`. – ImportanceOfBeingErnest Nov 10 '17 at 10:24
  • I feel dumb now. In producing the minimal example, I discovered I couldn't reproduce the error, and eventually found out that in my original code, tight_layout() was getting called after add_colorbar(). Thanks. – mszegedy Nov 10 '17 at 14:35
  • You'd probably want to update to matplotlib 2.1, its default settings give you much prettier output than the older versions. – Andras Deak -- Слава Україні Nov 17 '17 at 11:45

0 Answers0