Major Difference in 2D kernel Density Plots: Seaborn and R
Question: I am trying to plot data using the 2D kernel density plot of Seaborn's
jointplot function (using statsmodels' KDEMultivariate function to calculate a
data-driven bandwidth). I've plotted a 2D kernel density in R using the same
data and the result looks very good (using the 'ks' package), while the
Seaborn plot looks very very different.

I am using the same exact data and the same exact bandwidth for each (taking
the bandwidth given by KDEMultivariant and passing that to the R method).

Here is the input.csv data used:
<https://app.box.com/s/ot7d36t44wrr85pusp5657pc1w2kf5hj>

Below are the code used in each and output images from each.

Python / Seaborn:

    
    
    import matplotlib.pyplot as plt
    import statsmodels.api as sm
    data = pd.read_csv("input.csv", dtype={'x': float, 'y': float}, skiprows=0)
    bw_ml_x = sm.nonparametric.KDEMultivariate(data=data['x'], var_type='c', bw='cv_ml')
    bw_ml_y = sm.nonparametric.KDEMultivariate(data=data['y'], var_type='c', bw='cv_ml')        
    
    g = sns.jointplot(x='x', y='y', data=data, kind="kde", stat_func=None, bw=[bw_ml_x.bw, bw_ml_y.bw])
    
    g.plot_joint(plt.scatter, c="w")
    g.ax_joint.collections[0].set_alpha(0)
    
    sns.plt.show()
    

Img for Seaborn plot:

![](http://i.imgur.com/2Y8e0n0.png)

The bandwidth given by bw_ml_x.bw and bw_ml_y.bw is placed in a 2 x 2 R matrix
H, where H[1,1] = bw_ml_x.bw, H[2,2] = bw_ml.y.bw, and other values set to
zero.

R:

    
    
    library(ks)
    fhat <- kde(x=as.data.frame(data[1], data[2]), H=H)
    plot(fhat, display="filled.contour2", cont=seq(10,90,by=10))
    

Img for R plot:

![](http://i.imgur.com/0Kes8Cz.png)


Answer: Looking at your Seaborn/Python plot, many of the points cluster along the
(0,n) region and the (1,1) region of your space, just as the KDE of the R plot
shows. This indicates that Seaborn and R are looking at the same data; we
simply need to reformulate the call to the `kde` in Seaborn in order to
visualize the KDE gradients.

If you modify your Python call to match the
[documentation](https://stanford.edu/~mwaskom/software/seaborn/tutorial/distributions.html)
for `Kernel Density Estimation` in Seaborn you'll get a proper 2d-kdf out of
Python:

    
    
    import matplotlib.pyplot as plt
    import statsmodels.api as sm
    import pandas as pd
    import seaborn as sns
    
    data = pd.read_csv("input.csv", dtype={'x': float, 'y': float}, skiprows=0)
    bw_ml_x = sm.nonparametric.KDEMultivariate(data=data['x'], var_type='c', bw='cv_ml')
    bw_ml_y = sm.nonparametric.KDEMultivariate(data=data['y'], var_type='c', bw='cv_ml')        
    
    g = sns.jointplot(x='x', y='y', data=data, kind="kde")
    
    g.plot_joint(plt.scatter, c="w")
    g.ax_joint.collections[0].set_alpha(0)
    
    sns.plt.show()
    

[![enter image description
here](http://i.stack.imgur.com/AuNkZ.png)](http://i.stack.imgur.com/AuNkZ.png)

This accords with the R plot (though the kernel estimators seem to be slightly
different, which would account for the variation in gradients between the
plots):

[![enter image description
here](http://i.stack.imgur.com/8nYhn.png)](http://i.stack.imgur.com/8nYhn.png)

