26

I would like to plot a 2D kernel density estimation. I find the seaborn package very useful here. However, after searching for a long time, I couldn't figure out how to make the y-axis and x-axis non-transparent. Also, how to show the values of the density on the contour? I would be very appreciated if someone could help me out. Below please see my code and graph. enter image description here

import numpy as np
import seaborn as sns
import matplotlib.pyplot as pl

Y = np.random.multivariate_normal((0, 0), [[0.8, 0.05], [0.05, 0.7]], 100)
ax = sns.kdeplot(Y, shade = True, cmap = "PuBu")
ax.patch.set_facecolor('white')
ax.collections[0].set_alpha(0)
ax.set_xlabel('$Y_1$', fontsize = 15)
ax.set_ylabel('$Y_0$', fontsize = 15)
pl.xlim(-3, 3)
pl.ylim(-3, 3)
pl.plot([-3, 3], [-3, 3], color = "black", linewidth = 1)
pl.show()
Flabetvibes
  • 3,066
  • 20
  • 32
user3698176
  • 755
  • 2
  • 7
  • 9
  • 1
    I'm not sure what you mean by "make the y-axis and x-axis non transparent"; the line `ax.collections[0].set_alpha(0)` is making the lowest contour transparent; if you don't want that, don't include that line. – mwaskom May 09 '15 at 23:22

2 Answers2

61

Here is a solution using scipy and matplotlib only :

import numpy as np
import matplotlib.pyplot as pl
import scipy.stats as st

data = np.random.multivariate_normal((0, 0), [[0.8, 0.05], [0.05, 0.7]], 100)
x = data[:, 0]
y = data[:, 1]
xmin, xmax = -3, 3
ymin, ymax = -3, 3

# Peform the kernel density estimate
xx, yy = np.mgrid[xmin:xmax:100j, ymin:ymax:100j]
positions = np.vstack([xx.ravel(), yy.ravel()])
values = np.vstack([x, y])
kernel = st.gaussian_kde(values)
f = np.reshape(kernel(positions).T, xx.shape)

fig = pl.figure()
ax = fig.gca()
ax.set_xlim(xmin, xmax)
ax.set_ylim(ymin, ymax)
# Contourf plot
cfset = ax.contourf(xx, yy, f, cmap='Blues')
## Or kernel density estimate plot instead of the contourf plot
#ax.imshow(np.rot90(f), cmap='Blues', extent=[xmin, xmax, ymin, ymax])
# Contour plot
cset = ax.contour(xx, yy, f, colors='k')
# Label plot
ax.clabel(cset, inline=1, fontsize=10)
ax.set_xlabel('Y1')
ax.set_ylabel('Y0')

pl.show()

The previous code gives the following result :

plot_kernel_density.jpg

which has a non-transparent x-axis, a non-transparent y-axis and values of the density on the contour. Is this the expected result ?

Flabetvibes
  • 3,066
  • 20
  • 32
  • 2
    This is so useful! Thanks for the detailed demonstration. I will use what you did here. – user3698176 May 10 '15 at 05:20
  • If I want to plot another dataset on the same plot in order to compare two data, how to do that. I want to have the same level so that we can compare properly @user3698176 – John Singh Dec 18 '20 at 08:30
3

Did you check these examples?

http://matplotlib.org/examples/pylab_examples/contour_demo.html

One example of contour_demo and another one (other options)

http://matplotlib.org/examples/pylab_examples/contourf_demo.html

One example of contourf_demo and 4 plots stacked

Scroll down to see more images.

jcoppens
  • 5,306
  • 6
  • 27
  • 47
  • 2
    I'm up-voting because these are great examples that answer the question, but I would recommend a friendlier description so people don't keep down voting you. – ldmtwo May 11 '18 at 10:32