Reputation: 53
I'm trying to make a heatmap plot but would like to omit the first row from it. So that I have a table where the first row wouldn't have any background colour. Somewhat like this paint example
But I'm not even sure if that is possible. I've tried making a mulitIndex as a column so that the first row would become a part of the column name, but I want the row name, 'fixed' to still be there. Is it even possible?
This is what I'm working with so far. I would appreciate any input!
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
SO = pd.DataFrame(np.random.randint(100,size=(4,5)))
SO.iloc[0] = [5, 10, 15, 10, 5]
SO.index = ['fixed','val1', 'sd2', 'val2']
SO.columns = ['Prod1', 'Prod2', 'Prod3', 'Prod4', 'Prod5']
sns.set(font_scale=1.5)
fig, ax = plt.subplots(figsize=(20,10))
ax = sns.heatmap(SO, annot=True, fmt="", cbar=False, cmap="RdYlGn", vmin=0, vmax=100)
plt.tick_params(axis='both', which='major', labelsize=19, labelbottom = False, bottom=False, top = False, labeltop=True)
Upvotes: 5
Views: 2527
Reputation: 17144
The masking idea of Stupid Wolf is great, but if you are looking for simpler ways you can simply incorporate the first row in the column names and plot the heatmap as usual.
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
SO = pd.DataFrame(np.random.randint(100,size=(4,5)))
SO.iloc[0] = [5, 10, 15, 10, 5]
SO.index = ['fixed','val1', 'sd2', 'val2']
SO.columns = ['Prod1', 'Prod2', 'Prod3', 'Prod4', 'Prod5']
first_row = [str(i) for i in SO.iloc[0]]
labels = [i + '\n' + j for i,j in zip(SO.columns, first_row)]
sns.set(font_scale=1.5)
fig, ax = plt.subplots(figsize=(20,10))
ax = sns.heatmap(SO.iloc[1:], annot=True, fmt="", cbar=False, cmap="RdYlGn",
vmin=0, vmax=100)
ax.set_xticklabels(labels)
plt.tick_params(axis='both', which='major', labelsize=19,
labelbottom = False, bottom=False, top = False, labeltop=True)
Upvotes: 2
Reputation: 46898
A quick solution, is to plot your first row first, masking the rest, then plot over with the inverse:
This is the mask, where the first row is masked:
MASK = SO.apply(lambda x:np.arange(len(x))==0)
Prod1 Prod2 Prod3 Prod4 Prod5
fixed True True True True True
val1 False False False False False
sd2 False False False False False
val2 False False False False False
Set a colour for the first row:
COL = [(0.9690888119953864, 0.9664744329104191, 0.9649365628604383)]
Then we plot:
sns.set(font_scale=1.5)
fig, ax = plt.subplots(figsize=(20,10))
sns.heatmap(SO, annot=True, fmt="", cbar=False, mask=~MASK,cmap=COL,vmin=0, vmax=100,ax=ax)
sns.heatmap(SO, annot=True, fmt="", cbar=False, mask=MASK,cmap="RdYlGn",vmin=0, vmax=100,ax=ax)
plt.tick_params(axis='both', which='major', labelsize=19,
labelbottom = False, bottom=False, top = False, labeltop=True)
Upvotes: 1