I would like to create a colormap that fade linearly through colors defined for specific values. Below here is my Minimal Non Working Example.
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
data = np.random.uniform(0, 10, (10, 10))
values = [0., 0.8, 1., 10.]
colors = ["#ff0000", "#00ff00", "#0000ff", "#cccccc"]
I have the feeling this can be solved by using cmap
and norm
switches when plotting with imshow
but I could not succeed to have a smooth gradient of colors passing by defined colors at values.
cmap = mpl.colors.ListedColormap(colors, name="mycmap")
norm = mpl.colors.BoundaryNorm(values, len(colors))
fig, axe = plt.subplots()
cmap_ = axe.imshow(data, aspect="auto", origin="upper", cmap=cmap, norm=norm)
cbar = fig.colorbar(cmap_, ax=axe)
Also the scale is then non linear.
How can I setup this colormap using the provided values and colors above?
Here is the current solution I have found to solve my problem:
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
def get_colormap(values, colors, name="custom"):
values = np.sort(np.array(values))
values = np.interp(values, (values.min(), values.max()), (0., 1.))
cmap = mpl.colors.LinearSegmentedColormap.from_list(name, list(zip(values, colors)))
return cmap
data = np.random.uniform(0, 10, (10, 10))
values = np.array([0., 0.8, 1., 10.])
colors = ["#ff0000", "#00ff00", "#0000ff", "#cccccc"]
cmap_ = get_colormap(values, colors)
fig, axe = plt.subplots()
cmap = axe.imshow(data, aspect="auto", origin="upper", cmap=cmap_)
cbar = fig.colorbar(cmap, ax=axe)
Not straightforward but functional. I'll keep the question unanswered to leave opportunity to best solution to come.