# Two different results from seaborn and matplotlib for a kde plot. What's the reason?

I'm plotting kde plots for a set of data with seaborn and scipy.stats.gaussian_kde:

My understanding is that under the hood, seaborn uses scipy (see here).

It also seems as though the bandwidth variable is in both cases 'scott' by default, so that doesn't seem to be the cause.

Does anyone have any insight into why the plot are different?

UPDATE

So it appears that the different shape of the seaborn plot is due to the fact that instead of using scipy, seaborn uses the kde of simplestats if that library is available locally.

So the question I have now is why is the curve produced by simplestats so different than the one produced, say, by scipy (and perhaps othe libraries).

Below in the comments it was suggested that the reason has to do with the bandwidth setting, but I played around a bit with that and the differences I saw the curves was no where near as extreme. Here are two seaborn/simpletats kde curves with two different bandwidth settings (scott versus silverman):

Then here, by contrast, are two scipy-produced kde curves with, again scott versus silverman:

One possible explanation may be this note in the seaborn documentation for kdeplot (see here):

Note that the underlying computational libraries have different interperetations for this parameter: statsmodels uses it directly, but scipy treats it as a scaling factor for the standard deviation of the data.

However, I'll need to do a bit more research/learning to understand if that's relevant here. Does anyone else know if this might be the explanation?

• Do you have statsmodel installed? If so, Seaborn will use its KDEUnivariate, instead of stats.gaussian_kde. Also, can you provide the data, so your issue can be reproduced and investigated, and the definition of x in sns.kdeplot(x)? – caxcaxcoatl Oct 10 '19 at 2:33
• @caxcaxcoatl that was it. I finally noticed that it tries statsmodel and then ran their kde and it matched the shape on seaborn's kdeplot. Now I am just wondering why statsmodel's curve is so different than the other libraries. – fraxture Oct 10 '19 at 4:22
• The difference definitely comes from the computed bandwidths. First one is a smoother version of the second one. Check seaborn docs, for bandwidth parameter it states that in some contexts is a factor and for others is used directly – rapaio Oct 10 '19 at 5:14
• @rapaio I am a bit dubious of that because I cycled through all the bandwidths on the other libraries. The curve changed shape slightly but without producing the local minima on the right of the seaborn/simplestats chart. I'll try to update the question with some additional examples. – fraxture Oct 10 '19 at 5:24
• @fraxture, can we have your data, or any data where that behavior can be seen? That would help others trying to figure out what's happening. Please note that scipy.stats.gaussian_kde's documentation has this note: "The estimation works best for a unimodal distribution; bimodal or multi-modal distributions tend to be oversmoothed." Now, why that implementation has that oversmoothing and others not...? That I'm not sure – caxcaxcoatl Oct 11 '19 at 3:20