Color the background in a kdeplot

Question:

I am using seaborn kernel density estimation to plot probability density contours like so:

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable

x = np.random.normal(0, 3, 100)
y = np.random.normal(0, 1, 100)

fig, ax = plt.subplots()

ax.scatter(x,y, marker='.')

ax.set_aspect('equal')
ax.set(xlim=(-13,13))
ax.set(ylim=(-8,8))


divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)

sns.kdeplot(x,y, fill=True, shade_lowest=True, alpha=0.7, linewidths=3, 
            cmap='coolwarm', ax=ax, cbar=True, cbar_ax = cax)

colour = ax.collections[1].get_facecolor()

The result is:
enter image description here

I am producing many of these so to compare them I would like to have the plot limits fixed. As you can see, my issue is that when I change the limits of the plot, seaborn does not fill the background.

The variable colour in the last line of my code contains what I would like to fill the background with. I need help figuring out how to do so. I tried

ax.set_facecolor(colour.reshape(4))

which of course needs work to get to what I want:
enter image description here

This questions is essentially the same as this 6-year old question, which proposed to instead just remove the filling below the last contour. I am convinced there must be a way to get the desired behaviour though. I would really appreciate any help!

As a bonus: the linewidths argument of sns.kdeplot() does nothing. How can I change the linewidth of the contour lines?

Asked By: Luismi98

||

Answers:

As suggested in the comment by @mwaskom, you can use cut parameter.

This can be partially avoided with the cut parameter, which specifies
how far the curve should extend beyond the extreme datapoints. But
this influences only where the curve is drawn; the density estimate
will still smooth over the range where no data can exist, causing it
to be artifically low at the extremes of the distribution:

I used trial and error to get the correct value for cut which is 12. Refer below code for more details.

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable

x = np.random.normal(0, 3, 100)
y = np.random.normal(0, 1, 100)

fig, ax = plt.subplots()

ax.scatter(x,y, marker='.')

ax.set_aspect('equal')
ax.set(xlim=(-13,13))
ax.set(ylim=(-8,8))


divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)

sns.kdeplot(x,y, fill=True, thresh=0, alpha=0.7, cmap='coolwarm', ax=ax, cbar=True, cbar_ax = cax, cut=12) # `shade_lowest` is now deprecated in favor of `thresh`
colour = ax.collections[1].get_facecolor()

Output Image:

enter image description here

Answered By: Jay Patel