Search code examples
pythonmatplotlibcolorbarcolormap

Spread custom tick labels evenly over colorbar


I'm trying to add a custom colorbar to my heatmap using pyplot. My code looks something like this:

c_map = mpl.colors.ListedColormap(['#c7e9b4','#7fcdbb','#ffffff','#41b6c4','#225ea8','#253494'])
sm = plt.cm.ScalarMappable(cmap=c_map)
cbar = plt.colorbar(sm, ticks=np.arange(6), label='Change in user population')
cbar.ax.set_yticklabels(['<=-6', '<= -1', '0', '<= 3', '<= 6', '7>='])

This currently produces the following colorbar: Wrong colorbar

As can be seen from the image, only two of the six ticklabels are shown, at the bottom and top of the bar. However, following methods used by others, I expect that ticks=np.arange(6) evenly spreads the six labels over the colorbar, before changing the tick labels to the specified string values.

I'm looking for a quick-and-dirty way to fix this, as this is the only visual map I need to make. I've been looking around for hours now without any success in solving this, so please help this beginner programmer.


Solution

  • The axes for the ticks are in a range from 0 (bottom) to 1 (top). Dividing the space evenly into 6 parts will mark the bottom of each color region. Adding half of it will be nicely in the center. Therefore, ticks=np.linspace(0,1,6,endpoint=False) + 1/12. Or, equivalently, ticks=(np.arange(6)+1/2)/6.

    You can remove the tick lines by setting their length to zero: cbar.ax.axes.tick_params(length=0).

    To get proper less than or equal, having the labels in TeX format is an option. As in r'$\leq-6$'.

    Some demonstration code:

    import matplotlib as mpl
    import matplotlib.pyplot as plt
    import numpy as np
    
    c_map = mpl.colors.ListedColormap(['#c7e9b4','#7fcdbb','#ffffff','#41b6c4','#225ea8','#253494'])
    sm = plt.cm.ScalarMappable(cmap=c_map)
    cbar = plt.colorbar(sm, ticks=np.linspace(0, 1, 6, endpoint=False) + 1/12, label='Change in user population')
    cbar.ax.set_yticklabels([r'$\leq-6$', r'$\geq-1$', '$0$', r'$\leq3$', r'$\leq6$', r'$\geq7$'])
    cbar.ax.axes.tick_params(length=0)
    plt.show()
    

    example colorbar