Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Partial shade of distribution plot using Seaborn

Following simple code:

import numpy as np
import seaborn as sns
dist = np.random.normal(loc=0, scale=1, size=1000)
ax = sns.kdeplot(dist, shade=True);

Yields the following image:

enter image description here

I would like to only shade everything right (or left to some x value). What is the simplest way? I am ready to use something other than Seaborn.

like image 360
Dror Avatar asked Dec 23 '22 09:12

Dror


2 Answers

After calling ax = sns.kdeplot(dist, shade=True), the last line in ax.get_lines() corresponds to the kde density curve:

ax = sns.kdeplot(dist, shade=True)
line = ax.get_lines()[-1]

You can extract the data corresponding to that curve using line.get_data:

x, y = line.get_data()

Once you have the data, you can, for instance, shade the region corresponding to x > 0 by selecting those points and calling ax.fill_between:

mask = x > 0
x, y = x[mask], y[mask]
ax.fill_between(x, y1=y, alpha=0.5, facecolor='red')

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
dist = np.random.normal(loc=0, scale=1, size=1000)
ax = sns.kdeplot(dist, shade=True)
line = ax.get_lines()[-1]
x, y = line.get_data()
mask = x > 0
x, y = x[mask], y[mask]
ax.fill_between(x, y1=y, alpha=0.5, facecolor='red')
plt.show()

enter image description here

like image 80
unutbu Avatar answered Dec 28 '22 10:12

unutbu


Using seaborn is often fine for standard plots, but when some customized requirements come into play, falling back to matplotlib is often easier.

So one may first calculate the kernel density estimate and then plot it in the region of interest.

import scipy.stats as stats
import numpy as np
import matplotlib.pyplot as plt
plt.style.use("seaborn-darkgrid")

dist = np.random.normal(loc=0, scale=1, size=1000)
kde = stats.gaussian_kde(dist)
# plot complete kde curve as line
pos = np.linspace(dist.min(), dist.max(), 101)
plt.plot(pos, kde(pos))
# plot shaded kde only right of x=0.5
shade = np.linspace(0.5,dist.max(), 101)
plt.fill_between(shade,kde(shade), alpha=0.5)

plt.ylim(0,None)
plt.show()

enter image description here

like image 32
ImportanceOfBeingErnest Avatar answered Dec 28 '22 11:12

ImportanceOfBeingErnest