, and for categorical variables in the marine

The same question as a heatmap- like graph, but for categorical variables , but using Python and seaborn instead of R:

Imagine that I have the following data frame:

df = pd.DataFrame({"John":"No Yes Maybe".split(), "Elly":"Yes Yes Yes".split(), "George":"No Maybe No".split()}, index="Mon Tue Wed".split()) 

Now I would like to build a heat map and color each cell in accordance with its value. That is, "Yes", "No", "Maybe", for example, becomes "Green", "Gray", "Yellow". A legend must have these three colors and corresponding meanings.

I myself solved this problem as follows. It seems that I canโ€™t pass the categorical color map to the heat map of the sea wolf, so instead I replace the entire text with numbers and subsequently recreate the color map used by the seaweed inside the country, i.e.

 import pandas as pd import seaborn as sns import matplotlib.pyplot as plt import numpy as np import matplotlib.patches as mpatches # create dictionary with value to integer mappings value_to_int = {value: i for i, value in enumerate(sorted(pd.unique(df.values.ravel())))} f, ax = plt.subplots() hm = sns.heatmap(df.replace(value_to_int).T, cmap="Pastel2", ax=ax, cbar=False) # add legend box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.7, box.height]) legend_ax = f.add_axes([.7, .5, 1, .1]) legend_ax.axis('off') # reconstruct color map colors = plt.cm.Pastel2(np.linspace(0, 1, len(value_to_int))) # add color map to legend patches = [mpatches.Patch(facecolor=c, edgecolor=c) for c in colors] legend = legend_ax.legend(patches, sorted(value_to_int.keys()), handlelength=0.8, loc='lower left') for t in legend.get_texts(): t.set_ha("left") 

Categorical heatmap in seaborn

My question is: is there a shorter way to compile this heatmap? Otherwise, it may be a function that is worth implementing, in which case I will publish it on the seaborn tracker.

+10
source share
2 answers

You can use a discrete color map and change the color bar instead of a legend.

 value_to_int = {j:i for i,j in enumerate(pd.unique(df.values.ravel()))} # like you did n = len(value_to_int) # discrete colormap (n samples from a given cmap) cmap = sns.color_palette("Pastel2", n) ax = sns.heatmap(df.replace(value_to_int), cmap=cmap) # modify colorbar: colorbar = ax.collections[0].colorbar r = colorbar.vmax - colorbar.vmin colorbar.set_ticks([colorbar.vmin + r / n * (0.5 + i) for i in range(n)]) colorbar.set_ticklabels(list(value_to_int.keys())) plt.show() 

categorical seaborn heatmap

Part of the color scale adapted from this answer

NTN

+1
source

I would probably use bokeh for this purpose as it has built-in templates. Y-axis labels are also written horizontally, which is more readable.

http://bokeh.pydata.org/en/0.11.1/docs/gallery/heatmap_chart.html

0
source

Source: https://habr.com/ru/post/1245788/


All Articles