Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display multiple annotations in Seaborn Heatmap cells?

I want seaborn heatmap to display multiple values in each cell of the heatmap. Here is a manual example of what I want to see, just to be clear:

data = np.array([[0.000000,0.000000],[-0.231049,0.000000],[-0.231049,0.000000]])
labels =  np.array([['A\nExtra Stuff','B'],['C','D'],['E','F']])
fig, ax = plt.subplots()
ax = sns.heatmap(data, annot = labels, fmt = '')

enter image description here

Here as an example to get seaborn.heat to display flightsRoundUp values in the cells.

import matplotlib.pyplot as plt
import seaborn as sns
sns.set()

def RoundUp(x):
    return int(np.ceil(x/10)*10)

# Load the example flights dataset and conver to long-form
flights_long = sns.load_dataset("flights")
flights = flights_long.pivot("month", "year", "passengers")
flightsRoundUp =  flights.applymap(RoundUp)

# Draw a heatmap with the numeric values in each cell
f, ax = plt.subplots(figsize=(9, 6))
sns.heatmap(flights, annot=flightsRoundUp, fmt="", linewidths=.5, ax=ax)

What is the best way to display both flightsRoundUp and flights in all cells? Something like the first manual example above, but for all the cells in a vectorized-like way...

like image 961
Rotail Avatar asked Mar 11 '19 18:03

Rotail


Video Answer


1 Answers

Rotail's answer didn't work for me, I got an error when applying that lambda function.

However, I found a solution that exploits the fact that seaborn plots sequential figures on top of each other. All you have to do is use one call to heatmap to establish the figure, and then a subsequent call for each of the annotations. Use the annot_kws arg to make sure the text aren't written over eachother.

X = pd.DataFrame({'a':[1, 2, 3], 'b':[4, 5, 6]})
Y = pd.DataFrame({'A':['A', 'B', 'C'], 'B':['E', 'F', 'G']})
Z = pd.DataFrame({'A':['(Extra Stuff)', '(Extra Stuff)', '(Extra Stuff)'], 'B':['(Extra Stuff)', '(Extra Stuff)', '(Extra Stuff)']})

sns.heatmap(X, annot=False)
sns.heatmap(X, annot=Y, annot_kws={'va':'bottom'}, fmt="", cbar=False)
sns.heatmap(X, annot=Z, annot_kws={'va':'top'}, fmt="", cbar=False)

Code above produces the following figure

like image 190
HaplessEcologist Avatar answered Oct 22 '22 20:10

HaplessEcologist