Home > Enterprise >  How to add a color bar for vspans created with variable alpha
How to add a color bar for vspans created with variable alpha

Time:12-21

I would like to use varying degrees of red color to represent the different importance of each time element and fill in that region.

The example code is shown below.

import matplotlib.pyplot as plt
X_example = np.random.rand(400)
importance_values = np.random.rand(400)
plt.figure(figsize=(13,7))
plt.plot(X_example)
for j in range(len(X_example)):
    plt.axvspan(xmin=j, xmax=j 1,facecolor="r",alpha=importance_values[j])

It generates a graph like:

generated graph

Now I would like to add a colormap in this figure to show that, e.g. the light red means low importance and the dark red means high importance, just like this:

desired colormap

How could I achieve that in my case?

CodePudding user response:

One solution would be to create a LinearSegmentedColormap which takes a list of colors and turns it into a matplotlib colorbar object. Then you can set the "alpha channel":

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LinearSegmentedColormap, ListedColormap
from matplotlib.colorbar import ColorbarBase

X_example = np.random.rand(400)
importance_values = np.random.rand(400)

fig, (ax, cax) = plt.subplots(ncols=2, figsize=(8,5), gridspec_kw={'width_ratios': [1, 0.05]})
ax.plot(X_example, color='b')
for j in range(len(X_example)):
    ax.axvspan(xmin=j, xmax=j 1,facecolor="r",alpha=importance_values[j])
    
N = 20  # the number of colors/alpha-values in the colorbar
cmap = LinearSegmentedColormap.from_list(None, ['r' for i in range(N)], N=N)
alpha_cmap = cmap(np.arange(N))
alpha_cmap[:,-1] = np.linspace(0, 1, N)
alpha_cmap = ListedColormap(alpha_cmap, N=N)

cbar = ColorbarBase(cax, cmap=alpha_cmap, ticks=[0., 1],)
cbar.ax.set_yticklabels(["low importance", "high importance"])

This gives the following plot, where the two colors of the colorbar have custom labels:

enter image description here

CodePudding user response:

You could create a colormap mixing the red color with a range of alpha values:

import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap, to_rgba
from matplotlib.cm import ScalarMappable
import numpy as np

X_example = np.random.rand(400)
importance_values = np.random.rand(400)

fig, ax = plt.subplots(figsize=(12, 5))
ax.plot(X_example)
for j in range(len(X_example)):
    ax.axvspan(xmin=j, xmax=j   1, facecolor="r", alpha=importance_values[j])
ax.margins(x=0)

cmap = LinearSegmentedColormap.from_list(None, [to_rgba('r', 0), 'r'])
cbar = plt.colorbar(ScalarMappable(cmap=cmap), ticks=[0, 1], pad=0.02)
cbar.ax.set_yticklabels(["low", "high"], fontsize=20)
cbar.ax.set_ylabel("importance", labelpad=-30, fontsize=20)
plt.tight_layout()
plt.show()

colorbar containing range of alpha values

An example of a horizontal colorbar:

cbar = plt.colorbar(ScalarMappable(cmap=cmap), ticks=[0, 1], orientation='horizontal')
cbar.ax.set_xticklabels(["low", "high"], fontsize=20)
cbar.ax.set_xlabel("importance", labelpad=-15, fontsize=20)

horizontal colorbar

  • Related