user1054158
user1054158

Reputation:

Matplotlib - Same padding as the one used by a `colorbar`

Is there a way to keep the same padding as the one used by a colorbar without seeing any colobar ?

Why ? Indeed, this will allow me to do one visual effect when passing from one plot without the color shading informations to the one using the colobar.

Here is one starting code coming from this post.

from matplotlib.pylab import *
import matplotlib.cm as cm

min_val = 0
max_val = 1

# See : http://www.scipy.org/Cookbook/Matplotlib/Show_colormaps
my_cmap = cm.get_cmap('jet') # or any other one
norm = matplotlib.colors.Normalize(min_val, max_val) # the color maps work for [0, 1]

cmmapable = cm.ScalarMappable(norm, my_cmap)
cmmapable.set_array(range(min_val, max_val))

figure()
ax = gca()

cbar = colorbar(cmmapable, ticks=[0, 1])
cbar.ax.set_yticklabels(['Min', 'Max'])

show()

Upvotes: 0

Views: 693

Answers (1)

Robbert
Robbert

Reputation: 2724

What I understand is that you want to make a presentation or so with two slides, one with a plot without color bar and the next slide with the same plot with the color bar. The plots in the two slides should have the same sizes so that when you change the slides the plot does not jump or resize.

Setting the colormap will resize the original Axes instance. You can use ax.get_position() to get the bounding box of the resized Axes. It returns a bounding box: Bbox(array([[ 0.125, 0.1 ], [ 0.745, 0.9 ]])) It gives left, bottom, right and top edge. I find it easier to cheat a bit and use ax._position.bounds, which gives a rect (left edge, bottom edge, width, height) that you can directly use to make a new axes, as shown below.

import matplotlib 
import matplotlib.pyplot as plt

min_val = 0
max_val = 1

my_cmap = matplotlib.cm.get_cmap('jet') 
norm = matplotlib.colors.Normalize(min_val, max_val) 

cmmapable = matplotlib.cm.ScalarMappable(norm, my_cmap)
cmmapable.set_array(range(min_val, max_val))

fig1 = plt.figure()
ax1 = fig1.add_subplot(111)

cbar = plt.colorbar(cmmapable, ax = ax1, ticks=[0, 1])
cbar.ax.set_yticklabels(['Min', 'Max'])

# gives bounding box with left, right, bottom, top
print(ax1.get_position())
# gives rectangle with left, bottom, width, height
print(ax1._position.bounds)

fig2 = plt.figure()
ax2 = fig2.add_axes(ax1._position.bounds)

plt.show()

UPDATE: In the above solution there is no color bar, in the solution below there is a color bar, but you make it white and you remove the labels and the spines. If the background color of the figure is non-white, you'll see a white rectangle where the color bar is supposed to be.

import matplotlib 
import matplotlib.pyplot as plt

min_val = 0
max_val = 1

my_cmap = matplotlib.cm.get_cmap('jet') 
norm = matplotlib.colors.Normalize(min_val, max_val) 

cmmapable = matplotlib.cm.ScalarMappable(norm, my_cmap)
cmmapable.set_array(range(min_val, max_val))

fig1 = plt.figure()
ax1 = fig1.add_subplot(111)

# set opacity to 0
cbar = plt.colorbar(cmmapable, ax = ax1, ticks=[0, 1], alpha = 0)

# remove the tick labels
cbar.ax.set_yticklabels(['', ''])
# set the tick length to 0
cbar.ax.tick_params(axis = 'y', which = "both", length = 0)

# set everything that has a linewidth to 0
for a in cbar.ax.get_children():
    try:
        a.set_linewidth(0)
    except:
        pass

plt.show()   

Upvotes: 1

Related Questions