Search code examples
matplotlibcolorbar

How can I get rid of this dummy mappable object and still draw my colorbar in Matplotlib?


I have the code below to plot circles add them to an ax.

I color the circles with respect to a colorbar.

However, to add the colorbar to my plot, I'm using sc=plot.scatter(...) and putting the colorbar using this dummy sc. Because plt.colorbar(sc,...) requires a mappable argument. How can I get rid of this dummy sc and still draw my colorbar?

import matplotlib
import numpy as np
import os
import matplotlib as mpl
from matplotlib.colors import Normalize
import matplotlib.cm as matplotlib_cm
from matplotlib import pyplot as plt

print(matplotlib.__version__)

row_list=['row1', 'row2', 'row3']
column_list=[2]
maxProcessiveGroupLength=2
index = column_list.index(maxProcessiveGroupLength)

plot1,panel1 = plt.subplots(figsize=(20+1.5*len(column_list), 10+1.5*len(row_list)))
plt.rc('axes', edgecolor='lightgray')

#make aspect ratio square
panel1.set_aspect(1.0)
panel1.text(0.1, 1.2, 'DEBUG', horizontalalignment='center', verticalalignment='top', fontsize=60, fontweight='bold', fontname='Arial',transform=panel1.transAxes)

if (len(column_list) > 1):
    panel1.set_xlim([1, index + 1])
    panel1.set_xticks(np.arange(0, index + 2, 1))
else:
    panel1.set_xlim([0, len(column_list)])
    panel1.set_xticks(np.arange(0, len(column_list)+1, 1))

if (len(row_list) > 1):
    panel1.set_ylim([1, len(row_list)])
else:
    panel1.set_ylim([0, len(row_list)])

panel1.set_yticks(np.arange(0, len(row_list) + 1, 1))

panel1.set_facecolor('white')
panel1.grid(color='black')

for edge, spine in panel1.spines.items():
    spine.set_visible(True)
    spine.set_color('black')

xlabels = None
if (index is not None):
    xlabels = column_list[0:index + 1]
ylabels = row_list

cmap = matplotlib_cm.get_cmap('Blues')  # Looks better
v_min = 2
v_max = 20
norm = Normalize(v_min, v_max)
bounds = np.arange(v_min, v_max+1, 2)

# Plot the circles with color
for row_index, row in enumerate(row_list):
    for column_index, processive_group_length in enumerate(column_list):
        radius=0.35
        color=10+column_index*3+row_index*3
        circle = plt.Circle((column_index + 0.5, row_index + 0.5), radius,color=cmap(norm(color)), fill=True)
        panel1.add_patch(circle)

# Used for scatter plot
x = []
y = []
c = []

for row_index, processiveGroupLength in enumerate(row_list):
    x.append(row_index)
    y.append(row_index)
    c.append(0.5)

# This code defines the ticks on the color bar
# plot the scatter plot
sc = plt.scatter(x, y, s=0, c=c, cmap=cmap, vmin=v_min, vmax=v_max, edgecolors='black')

# colorbar to the bottom
cb = plt.colorbar(sc ,orientation='horizontal')  # this works because of the scatter
cb.ax.set_xlabel("colorbar label", fontsize=50, labelpad=25)

# common for horizontal colorbar and vertical colorbar
cbax = cb.ax
cbax.tick_params(labelsize=40)
text_x = cbax.xaxis.label
text_y = cbax.yaxis.label
font = mpl.font_manager.FontProperties(size=40)
text_x.set_font_properties(font)
text_y.set_font_properties(font)

# CODE GOES HERE TO CENTER X-AXIS LABELS...
panel1.set_xticklabels([])
mticks = panel1.get_xticks()
panel1.set_xticks((mticks[:-1] + mticks[1:]) / 2, minor=True)
panel1.tick_params(axis='x', which='minor', length=0, labelsize=50)

if xlabels is not None:
    panel1.set_xticklabels(xlabels,minor=True)

panel1.xaxis.set_ticks_position('top')

plt.tick_params(
    axis='x',  # changes apply to the x-axis
    which='major',  # both major and minor ticks are affected
    bottom=False,  # ticks along the bottom edge are off
    top=False)  # labels along the bottom edge are off

# CODE GOES HERE TO CENTER Y-AXIS LABELS...
panel1.set_yticklabels([])
mticks = panel1.get_yticks()
panel1.set_yticks((mticks[:-1] + mticks[1:]) / 2, minor=True)
panel1.tick_params(axis='y', which='minor', length=0, labelsize=50)
panel1.set_yticklabels(ylabels, minor=True)  # fontsize

plt.tick_params(
    axis='y',  # changes apply to the x-axis
    which='major',  # both major and minor ticks are affected
    left=False)  # labels along the bottom edge are off

plt.show()

enter image description here


Solution

  • From the documentation of colorbar:

    Note that one can create a ScalarMappable "on-the-fly" to generate colorbars not attached to a previously drawn artist

    In your example, the following allows for creating the same colorbar without the scatter plot:

    cb = plt.colorbar(mpl.cm.ScalarMappable(norm=norm, cmap=cmap), orientation='horizontal')