2

The inspiration for this question comes from breaks in pheatmap in R. The question is if I can define how "rough", how continuous/discrete my colouring and binning is in seaborn's heatmap. I have found a way how to do it using cmap and the number of colours used (eg. Discrete legend in seaborn heatmap plot). However, I have no idea how the assignment to those colour groups is done.


So the questions are, how are the data binned if I use cmap and force seaborn to use only a discrete set of colours=bins? How can I set it manually? Eg. in the case of R, I can set the breaks to be from 0 to 800 by step of 100 and pass it to the "breaks" argument.

breaksList = seq(0, 800, by = 100)

It is quite simple to use cmap and number of colours if my scale is linear but if I would like to have my bins=colorbar logarithmic or just not equally spaced, how would I do that?


To give a concrete example, let me present the example of flights data set. On the left is the original default plot, on the right, I choose 5 colours to have 5 bins. So how are defined the edges of those bins? Can I reset them so that I have eg. bins 0-200, 200-300, 300-400, 400-600, above 600? (I'm intentionally using unequal bins to show what I mean.)

# choose 5 colours to create 5 bins
cmap = sns.color_palette('rocket', n_colors=5)

# run this without the cmap argument to get the first image
flights = sns.load_dataset("flights")
flights = flights.pivot("month", "year", "passengers")
ax = sns.heatmap(flights, cmap = cmap)

Original heatmap WITHOUT using cmap. Heatmap with 5 discrete sections created using cmap and choosing 5 colours.

Thanks.

My Work
  • 2,143
  • 2
  • 19
  • 47

1 Answers1

5

It seems there is a bug in seaborn that prevents the below idea from working correctly, so falling back to pure matplotlib:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
import seaborn as sns
# choose 5 colours to create 5 bins
colors = sns.color_palette('rocket', 5)
levels = [0, 200, 300, 400, 600]
cmap, norm = matplotlib.colors.from_levels_and_colors(levels, colors, extend="max")

flights = sns.load_dataset("flights")
flights = flights.pivot("month", "year", "passengers")

fig, ax = plt.subplots()
im = ax.imshow(flights.values, cmap = cmap, norm=norm)
ax.set(xticks=range(flights.shape[1]), yticks=range(flights.shape[0]),
       xticklabels=flights.columns, yticklabels=flights.index)
ax.tick_params(axis="x", rotation=90)
fig.colorbar(im, ax=ax, spacing="propotional")

plt.show()

enter image description here

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712