Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fill with a different color an area in seaborn.distplot

Is it possible to fill with a color the area outside the two threshold lines (line1 and line2) and limited in Y-axis by the KDE curve drawn by distplot ?(that represents 3-sigmas for my application)

import pylab as pl
import seaborn as sns
#plotting the two lines
p1 = pl.axvline(x=line1,color='#EF9A9A')
p2 = pl.axvline(x=line2,color='#EF9A9A')
#plotting the PDF
sns.distplot(stat, hist=True,color='#388E3C')

result figure

like image 506
azeddine ben omar Avatar asked Oct 11 '17 10:10

azeddine ben omar


People also ask

How do I change the color of my Seaborn Distplot?

We can set different colors to the distplot to add to the visualization of the data using the ' color ' parameter of the seaborn. distplot() function.

What is the difference between Distplot and Displot?

displot() is the new distplot() with better capabilities and distplot() is deprecated starting from this Seaborn version. With the new displot() function in Seaborn, the plotting function hierarchy kind of of looks like this now covering most of the plotting capabilities.

What can I use instead of Distplot in Seaborn?

This function has been deprecated and will be removed in seaborn v0. 14.0. It has been replaced by histplot() and displot() , two functions with a modern API and many more capabilities.

What does bins do in Seaborn?

bins. The bins parameter enables you to control the bins of the histogram (i.e., the number of bars). The most common way to do this is to set the number of bins by providing an integer as the argument to the parameter. For example, if you set bins = 30 , the function will create a histogram with 30 bars (i.e., bins).


1 Answers

You may use fill_between to fill the area underneath a curve. To get access to the KDE curve from the seaborn plot, you can draw that one first, such that ax.lines only has a single element, which is the curve of interest. Its data is obtained via kde_x, kde_y = ax.lines[0].get_data().

Then using ax.fill_between() allows to fill the area under the curve. To restrict this to be outside some given data range, the where keyword argument may be used (and interpolate=True should be set to have the area go up to the points in question).

ax.fill_between(kde_x, kde_y, where=(kde_x<x0) | (kde_x>x1) , 
                interpolate=True, color='#EF9A9A')

Full example:

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

stat=np.random.randn(100)
x0 = -1
x1 = 1

#plotting the PDF (do this before plotting anything else)
ax = sns.distplot(stat, hist=True,color='#388E3C')
kde_x, kde_y = ax.lines[0].get_data()

#plotting the two lines
p1 = plt.axvline(x=x0,color='#EF9A9A')
p2 = plt.axvline(x=x1,color='#EF9A9A')


ax.fill_between(kde_x, kde_y, where=(kde_x<x0) | (kde_x>x1) , 
                interpolate=True, color='#EF9A9A')

plt.show()

Image produced by the above code


Old answer to initial question:

You may use an axvspan, starting at the left x limit and going to the position of the first line and another one starting at the position of the second line and going to the right x limit.

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

stat=np.random.randn(100)
x0 = -1
x1 = 1

#plotting the two lines
p1 = plt.axvline(x=x0,color='#EF9A9A')
p2 = plt.axvline(x=x1,color='#EF9A9A')

#plotting the PDF
ax = sns.distplot(stat, hist=True,color='#388E3C')

xlim = ax.get_xlim()
ax.axvspan(xlim[0], x0, color='#EF9A9A', alpha=0.5)
ax.axvspan(x1, xlim[1], color='#EF9A9A', alpha=0.5)
#reset xlim
ax.set_xlim(xlim)
plt.show()

Image produced by the above code

Here, we need to adjust the xlimits after setting spans; the reason is that with the spans in place the autoscaling would add another 5% padding to both ends of the axes, resulting in white space. Alternatively you could use zero margin for the xaxis, ax.margins(x=0).

like image 110
ImportanceOfBeingErnest Avatar answered Oct 24 '22 09:10

ImportanceOfBeingErnest