I plot the below heatmap. I would like to use four colors to visualize the values associated to each cell.
I have defined the vmin and vmax parameters in the heatmap() function. It appears that the colors are spread uniformly when maps values between vmin and vmax. However, the length of the intervals for which color is applied changes from color to color.
The code is as follow:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
import seaborn as sns
X=np.array([
[ 81.31, 99.91, 99.91, 81.31, 99.91],
[ 99.91, 99.91, 99.91, 99.91, 99.91],
[ 99.87, 99.87, 99.87, 99.87, 99.87],
[ 99.98, 99.98, 99.98, 99.98, 99.98],
[ 75.64, 75.64, 75.64, 75.62, 75.64],
[100. , 100. , 100. , 100. , 100. ],
[ 98.01, 98.01, 98.01, 97.98, 98.01],
[100. , 100. , 100. , 100. , 100. ],
[ 93.75, 99.98, 99.98, 93.75, 99.98],
[ 93.64, 93.64, 93.64, 73.64, 73.64],
[ 99.98, 79.98, 79.98, 99.98, 99.98],
[ 99.91, 99.91, 99.91, 99.91, 99.91],
[100. , 100. , 100. , 100. , 100. ],
[100. , 100. , 100. , 100. , 100. ],
[ 99.96, 99.96, 69.96, 69.96, 99.96],
[ 99.98, 99.98, 49.98, 49.98, 99.98],
[ 99.98, 99.98, 99.98, 99.98, 99.98],
[100. , 100. , 100. , 100. , 100. ],
[100. , 100. , 100. , 100. , 100. ],
[ 99.89, 99.89, 99.89, 99.89, 99.89],
[100. , 100. , 100. , 100. , 100. ],
[ 99.87, 99.87, 99.87, 99.87, 99.87]
])
index=['Test{:02d}'.format(i) for i in range(22)]
cols=['Day{}'.format(i) for i in range(1,6)]
X=pd.DataFrame(X,index=index,columns=cols)
fig, ax= plt.subplots(figsize=(12,12))
# colors: red=[0,50], yellow=[50,75], orange=[75,90], green=[90,100]
sns.heatmap(
data=X,
ax=ax,
vmax=100, vmin=0,
cmap=sns.color_palette(['red', 'yellow', 'orange', 'green']),
linewidths=.5, linecolor='lightgray',
annot=True, fmt=".1f",
cbar_kws={'pad': .02, 'ticks': [0, 50, 75, 90, 100]},
)
ax.set_yticklabels(ax.get_yticklabels(), rotation=0);
I expect all cells with values between
- 100 and 90 to be colored in green;
- 90 and 75 to be colored in orange;
- 75 and 50 to be colored in yellow;
- 50 and 0 to be colored in red.
Update: 2019-11-02
In case if someone else may face similar problem, this is the solution I have come up with using directions from @ImportanceOfBeingErnest:
import the libraries
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.colors as colors
import seaborn as sns
create the customized map
# define 100 colors using an existing color map
newcolors = plt.get_cmap('viridis',100).colors
# assign new colors of interest
newcolors[ : 50, :] = colors.to_rgba('red')
newcolors[50: 75, :] = colors.to_rgba('yellow')
newcolors[75: 90, :] = colors.to_rgba('orange')
newcolors[90:100, :] = colors.to_rgba('green')
# create the customized color map
mycmap = colors.ListedColormap(newcolors)
generate sample data
X = np.array([
[ 81.31, 99.91, 99.91, 81.31, 99.91],
[ 99.91, 99.91, 99.91, 99.91, 99.91],
[ 99.87, 99.87, 99.87, 99.87, 99.87],
[ 99.98, 99.98, 99.98, 99.98, 99.98],
[ 75.64, 75.64, 75.64, 75.62, 75.64],
[100. , 100. , 100. , 100. , 100. ],
[ 98.01, 98.01, 98.01, 97.98, 98.01],
[100. , 100. , 100. , 100. , 100. ],
[ 93.75, 99.98, 99.98, 93.75, 99.98],
[ 93.64, 93.64, 93.64, 73.64, 73.64],
[ 99.98, 79.98, 79.98, 99.98, 99.98],
[ 99.91, 99.91, 99.91, 99.91, 99.91],
[100. , 100. , 100. , 100. , 100. ],
[100. , 100. , 100. , 100. , 100. ],
[ 99.96, 99.96, 69.96, 69.96, 99.96],
[ 99.98, 99.98, 49.98, 49.98, 99.98],
[ 99.98, 99.98, 99.98, 99.98, 99.98],
[100. , 100. , 100. , 100. , 100. ],
[100. , 100. , 100. , 100. , 100. ],
[ 99.89, 99.89, 99.89, 99.89, 99.89],
[100. , 100. , 100. , 100. , 100. ],
[ 99.87, 99.87, 99.87, 99.87, 99.87]
])
index = ['Test{:02d}'.format(i) for i in range(22)]
cols = ['Day{}'.format(i) for i in range(1,6)]
X = pd.DataFrame(X,index=index,columns=cols)
produce the plot
# use the new color map
fig, ax = plt.subplots(figsize=(12,12))
sns.heatmap(
data=X,
ax=ax,
vmax=100, vmin=0,
cmap=mycmap,
linewidths=.5,
linecolor='lightgray',
annot=True,
fmt=".1f",
cbar_kws={
'pad': .02,
'ticks': [0, 50, 75, 90, 100],
},
)
ax.set_yticklabels(ax.get_yticklabels(), rotation=0);
