【问题标题】:Unable to read data from kdeplot无法从 kdeplot 读取数据
【发布时间】:2021-02-25 09:34:27
【问题描述】:

我有一个 pandas 数据帧,其中包含两列 A 和 B,在以下代码中命名为 df

我尝试为 B 的每个值绘制一个 kde,如下所示:

import seaborn as sbn, numpy as np, pandas as pd

fig = plt.figure(figsize=(15, 7.5))
sbn.kdeplot(data=df, x="A", hue="B", fill=True)
fig.savefig("test.png")

我阅读了以下命题,但只有那些我使用 statsmodel 或其他模块从头开始计算 kde 的命题才能让我有所了解: Seaborn/Matplotlib: how to access line values in FacetGrid? Get data points from Seaborn distplot

出于好奇,我想知道为什么我无法从以下代码中得到一些东西:

kde = sns.kdeplot(data=df, x="A", hue="B", fill=True)
line = kde.lines[0]
x, y = line.get_data()
print(x, y)

我得到的错误是IndexError: list index out of rangekde.lines 的长度为 0

通过fig.axes[0].lines[0] 访问行也会引发IndexError

总而言之,我想我尝试了之前线程中提出的所有内容(我尝试切换到displot 而不是使用kdeplot,但这是同一个故事,只是我必须以不同的方式访问轴,注意@987654336 @ 而不是distplot,因为它已被弃用),但每次我到达.get_lines()ax.lines,......返回的是一个空列表。所以我无法从中获得任何价值。

编辑:可重现的示例

import pandas as pd, numpy as np, matplotlib.pyplot as plt, seaborn as sbn

# 1. Generate random data
df = pd.DataFrame(columns=["A", "B"])

for i in [1, 2, 3, 5, 7, 8, 10, 12, 15, 17, 20, 40, 50]:
    for _ in range(10):
        df = df.append({"A": np.random.random() * i, "B": i}, ignore_index=True)

# 2. Plot data
fig = plt.figure(figsize=(15, 7.5))
sbn.kdeplot(data=df, x="A", hue="B", fill=True)

# 3. Read data (error)
ax = fig.axes[0]
x, y = ax.lines[0].get_data()
print(x, y)

【问题讨论】:

  • 使用 seaborn 示例之一为我工作。你能创建一个minimal reproducible example吗?
  • 我添加了一个带有随机数据的示例。我自己测试了一下,我得到了与原始数据相同的错误。也许我遗漏了一些东西或没有按我应该的方式进行绘图。
  • fill=True 现在创建一个多边形。一种解决方法是使用fill=False 第二次创建kdeplot(可选择将线条颜色设置为'none')。或者您可以直接拨打scipy.stats.gaussian_kde

标签: python-3.x matplotlib seaborn


【解决方案1】:

这是因为使用 fill=True 会改变 matplotlib 绘制的对象。

当不使用填充时,绘制线条:

fig = plt.figure(figsize=(15, 7.5))
ax = sbn.kdeplot(data=df, x="A", hue="B")
print(ax.lines)
# [<matplotlib.lines.Line2D object at 0x000001F365EF7848>, etc.]

当您使用填充时,它会将它们更改为 PolyCollection 对象

fig = plt.figure(figsize=(15, 7.5))
ax = sbn.kdeplot(data=df, x="A", hue="B", fill=True)
print(ax.collections)
# [<matplotlib.collections.PolyCollection object at 0x0000016EE13F39C8>, etc.]

您可以再次绘制 kdeplot,但使用 fill=False 以便您可以访问线对象

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多