I would like to merge two colormaps into one, such that I can use one cmap
for negative values and the other one for positive values.
At the moment I do it with masked arrays and plotting one image with one cmap
and the other image with the other, resulting in:
with the following data
dat = np.random.rand(10,10) * 2 - 1
pos = np.ma.masked_array(dat, dat<0)
neg = np.ma.masked_array(dat, dat>=0)
I plotted pos
with gist_heat_r
and neg
with binary
.
I would like to have a single colorbar with the combined cmap
's, so this is not the correct approach for me.
So, how do I take two existing cmaps
's and merge them into one?
EDIT: I admit, this is a duplicate, but the answer that's given is much more clear here. Also the example images make it more clear.
From an open Cmap: You can combine the contents of multiple nested nodes. To combine the contents of multiple nested nodes into one nested node, right-click a selection of nested nodes, then left-click Merge Nodes...
( cmaps.viridis is a matplotlib.colors.ListedColormap ) import matplotlib.pyplot as plt import matplotlib.image as mpimg import numpy as np import colormaps as cmaps img=mpimg.imread('stinkbug.png') lum_img = np.flipud(img[:,:,0]) imgplot = plt.pcolormesh(lum_img, cmap=cmaps.viridis)
Colormap. The new default colormap used by matplotlib. cm. ScalarMappable instances is 'viridis' (aka option D).
Colormaps are basically just interpolation functions which you can call. They map values from the interval [0,1] to colors. So you can just sample colors from both maps and then combine them:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
data = np.random.rand(10,10) * 2 - 1
# sample the colormaps that you want to use. Use 128 from each so we get 256
# colors in total
colors1 = plt.cm.binary(np.linspace(0., 1, 128))
colors2 = plt.cm.gist_heat_r(np.linspace(0, 1, 128))
# combine them and build a new colormap
colors = np.vstack((colors1, colors2))
mymap = mcolors.LinearSegmentedColormap.from_list('my_colormap', colors)
plt.pcolor(data, cmap=mymap)
plt.colorbar()
plt.show()
Result:
NOTE: I understand that you might have specific needs for this, but in my opinion this is not a good approach: How will you distinguish -0.1 from 0.9? -0.9 from 0.1?
One way to prevent this is to sample the maps only from ~0.2 to ~0.8 (e.g.: colors1 = plt.cm.binary(np.linspace(0.2, 0.8, 128))
) so they wont go all the way up to black:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With