我有一个 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:列表索引超出范围
。 kde.lines
的长度为 0
。
通过 fig.axes[0].lines[0]
访问线条也会引发 IndexError
。
总而言之,我想我尝试了之前线程中提出的所有内容(我尝试切换到 displot
而不是使用 kdeplot
但这是同一个故事,只是我必须以不同的方式访问轴,请注意 displot
而不是 distplot
因为它已被弃用),但每次我到达 .get_lines()
时, ax.lines
, ...返回的是一个空列表。所以我无法从中获得任何值(value)。
编辑:可重现的示例
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)
最佳答案
发生这种情况是因为使用 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.]
当您使用 fill 时,会将它们更改为 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
以便您可以访问线条对象
关于python-3.x - 无法从 kdeplot 读取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66365883/