4

I want to create a Kernel-Density-Estimation with seaborn.kdeplot with a colorbar on the side.

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np; np.random.seed(10)
import seaborn as sns; sns.set(color_codes=True)

mean, cov = [0, 2], [(1, .5), (.5, 1)]
x, y = np.random.multivariate_normal(mean, cov, size=50).T
sns.kdeplot(x, y ,shade=True)
plt.show()

While the Kernel-Density-Estimation is created, I do not have a clue how to create the colorbar. I tried using plt.colorbar() without success.

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
Panzerritter
  • 43
  • 1
  • 3

2 Answers2

9

Now it's implemented! parameter cbar=True.

You can also use shade_lowest=False to not shade the first level.

import seaborn as sns
import numpy as np
import matplotlib.pylab as plt

x, y = np.random.randn(2, 300)
sns.kdeplot(x=x, y=y, zorder=0, n_levels=6, shade=True, 
    cbar=True, shade_lowest=False, cmap='viridis')

enter image description here

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
imbr
  • 6,226
  • 4
  • 53
  • 65
7

You'll have to call the scipy KDE and matplotlib contour function directly, but it's just a bit of extra code:

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np; np.random.seed(10)
import seaborn as sns; sns.set(color_codes=True)
from scipy import stats

mean, cov = [0, 2], [(1, .5), (.5, 1)]
data = np.random.multivariate_normal(mean, cov, size=50).T

kde = stats.gaussian_kde(data)
xx, yy = np.mgrid[-3:3:.01, -1:4:.01]
density = kde(np.c_[xx.flat, yy.flat].T).reshape(xx.shape)

f, ax = plt.subplots()
cset = ax.contourf(xx, yy, density, cmap="viridis")
f.colorbar(cset)

enter image description here

mwaskom
  • 46,693
  • 16
  • 125
  • 127
  • out of curiosity, how difficult would it be for `sns.kdeplot` to return `cset` along with the `Axes` instance? – tmdavison Sep 05 '16 at 14:05
  • 1
    Not technically difficult to implement but it would violate the expected behavior of all axes level seaborn functions and would break any existing code that uses the return value. It would be preferable imo if matplotlib added the `cset` to the axes object like it does with other plot objects (lines, collections, etc.) – mwaskom Sep 05 '16 at 14:46