seaborn kdeplot error: "No contour levels were found within the data range"

seaborn kdeplot error: "No contour levels were found within the data range"

我正在使用 seaborn PairGrid 函数。我有两个数据集,我一直试图在同一个 PairGrid 上绘制它们。我的对角线是标准化的 plt.hists,我的下对角线是 sns.scatterplot,我的上对角线是 sns.kdeplot。然而,一些 kdeplots 正在产生这个 user warning:

/home/user_xyz/.local/lib/python3.6/site-packages/seaborn/distributions.py:1184: UserWarning: No contour levels were found within the data range.

我认为这可能是因为分布没有达到峰值,因此不像高斯分布,但这仍然不能解释为什么红色数据分别绘制得很好或者为什么蓝色数据在 PairGrid 上绘制得很好尽管与红色数据具有相同的平坦分布。

有谁知道为什么我无法在同一个 PairGrid 上正确绘制两个数据集的 kdeplots?或者为什么会出现此错误?

谢谢!

编辑:

我在下面添加了我使用的代码,并包含了一些与真实数据非常相似的玩具数据(真实数据是私有的)。它采用 Google sheet 的形式(应提供访问权限),然后可以使用 Pandas 读取。抱歉,如果这给您带来不便 - 我有一个非常大的数据集,它没有存储在数据库中。

代码:

# data variable contains data inside the linked Google sheet
g = sns.PairGrid(data, hue = "Type")

plt.figure()
g.map_diag(plt.hist, alpha = 0.7, density = True, histtype = 'step', range = [-1.05, 1.05], bins = 20, linewidth = 2)
g.map_upper(sns.kdeplot, hue_order = ['Ch', 'Si'])
g.map_lower(sns.scatterplot, hue_order = ['Ch', 'Si'])
g.add_legend()

for i in range(5):
    for j in range(5):
        g.axes[i, j].set_ylim(-1.1, 1.15)
        
for i in range(5):
    g.axes[i, 0].set_xlim(-0.1, 1.0)
    
for i in range(5):
    g.axes[i, 1].set_xlim(0.5, 1.0)
    
for i in range(5):
    g.axes[i, 2].set_xlim(-0.2, 1.1)
    
for i in range(5):
    g.axes[i, 3].set_xlim(-0.2, 1.2)
    
for i in range(5):
    g.axes[i, 4].set_xlim(-1.2, 1.3)

plt.show()

数据:

https://docs.google.com/spreadsheets/d/1KtX8nZU8ghe55xIEfE5e-srhWqWb5ZPS4G02gRVT-o8/edit?usp=sharing

sns.kdeplot 有一个选项 common_norm=,默认为 True。这减少了两个集合相对于它们的元素数量。由于一组比另一组小得多,所以它太小了,不会和另一组一起画。

这两个集合都可以使用 g.map_upper(sns.kdeplot, hue_order=['Ch', 'Si'], common_norm=False) 以“完整”尺寸显示。或者,您可以设置一个较低的阈值:g.map_upper(sns.kdeplot, hue_order=['Ch', 'Si'], thresh=0.02).

请注意,common_norm=False 使具有分离色调的 kdeplot 与不使用色调的 kdeplot 更相似。

这里是 kdeplot 的不同选项之间的比较,使用具有相似集合大小差异的玩具数据:

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

M = 30
N1 = 50
N2 = 2
data = pd.DataFrame({'Variable4': np.concatenate([np.random.randn(M, N1).cumsum(axis=0).ravel() / 2 + 10,
                                                  np.random.randn(M, N2).cumsum(axis=0).ravel() + 20]),
                     'Variable5': np.concatenate([np.random.randn(M, N1).cumsum(axis=0).ravel() / 2 + 20,
                                                  np.random.randn(M, N2).cumsum(axis=0).ravel() + 10]),
                     'Type': np.repeat(['Ch', 'Si'], [M * N1, M * N2])})

fig, (ax1, ax2, ax3, ax4) = plt.subplots(ncols=4, figsize=(18, 4))
sns.kdeplot(data=data, x='Variable4', y='Variable5', ax=ax1)
ax1.set_title('Not using hue')
sns.kdeplot(data=data, x='Variable4', y='Variable5', hue='Type', ax=ax2)
ax2.set_title('Default with hue')
sns.kdeplot(data=data, x='Variable4', y='Variable5', hue='Type', common_norm=False, ax=ax3)
ax3.set_title('hue, common_norm=False')
sns.kdeplot(data=data, x='Variable4', y='Variable5', hue='Type', thresh=0.02, ax=ax4)
ax4.set_title('hue, thresh=0.02')
plt.tight_layout()
plt.show()