在 seaborn kdeplot 中为背景着色 (python)

Colour the background in seaborn kdeplot (python)

我正在使用 seaborn 核密度估计来绘制概率密度等高线,如下所示:

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()

结果是:

我制作了很多这样的东西,所以为了比较它们,我想固定情节限制。如您所见,我的问题是当我更改绘图的限制时,seaborn 不会填充背景。

代码最后一行中的变量 colour 包含我想要填充背景的内容。我需要帮助弄清楚如何这样做。我试过了

ax.set_facecolor(colour.reshape(4))

这当然需要努力才能达到我想要的效果:

这个问题与 this 6 年前的问题本质上是一样的,后者建议只移除最后一个轮廓下方的填充。我相信必须有一种方法来获得所需的行为。非常感谢任何帮助!

作为奖励:sns.kdeplot() 的 linewidths 参数什么都不做。如何更改轮廓线的线宽?

正如@mwaskom 在评论中所建议的那样,您可以使用 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:

我通过反复试验获得了正确的 cut 值,即 12。请参阅下面的代码以获取更多详细信息。

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()

输出图像: