使用 Pandas 在同一图中绘制分组数据
Posted
技术标签:
【中文标题】使用 Pandas 在同一图中绘制分组数据【英文标题】:Plotting grouped data in same plot using Pandas 【发布时间】:2015-04-02 07:14:11 【问题描述】:在 Pandas 中,我正在做:
bp = p_df.groupby('class').plot(kind='kde')
p_df
是一个dataframe
对象。
但是,这会产生两个图,每个类别一个。 如何在同一个情节中强制一个情节与两个类?
【问题讨论】:
【参考方案1】:版本 1:
您可以创建轴,然后使用 DataFrameGroupBy.plot
的 ax
关键字将所有内容添加到这些轴:
import matplotlib.pyplot as plt
p_df = pd.DataFrame("class": [1,1,2,2,1], "a": [2,3,2,3,2])
fig, ax = plt.subplots(figsize=(8,6))
bp = p_df.groupby('class').plot(kind='kde', ax=ax)
这是结果:
不幸的是,传说的标签在这里没有太多意义。
版本 2:
另一种方法是遍历组并手动绘制曲线:
classes = ["class 1"] * 5 + ["class 2"] * 5
vals = [1,3,5,1,3] + [2,6,7,5,2]
p_df = pd.DataFrame("class": classes, "vals": vals)
fig, ax = plt.subplots(figsize=(8,6))
for label, df in p_df.groupby('class'):
df.vals.plot(kind="kde", ax=ax, label=label)
plt.legend()
这样您可以轻松控制图例。结果如下:
【讨论】:
【参考方案2】:另一种方法是使用seaborn
模块。这将在相同的轴上绘制两个密度估计值,而无需指定一个变量来保存轴,如下所示(使用其他答案中的一些数据框设置):
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
# data to create an example data frame
classes = ["c1"] * 5 + ["c2"] * 5
vals = [1,3,5,1,3] + [2,6,7,5,2]
# the data frame
df = pd.DataFrame("cls": classes, "indices":idx, "vals": vals)
# this is to plot the kde
sns.kdeplot(df.vals[df.cls == "c1"],label='c1');
sns.kdeplot(df.vals[df.cls == "c2"],label='c2');
# beautifying the labels
plt.xlabel('value')
plt.ylabel('density')
plt.show()
这会产生以下图像。
【讨论】:
如果我想要实际值而不是密度怎么办? 请注意,通过这种方式,您不会像问题所要求的那样绘制分组数据,而是将数据框切成两个子数据框并将它们添加到同一个图中。如果您有很多组(特别是如果您不知道这些组实际上是什么),则此解决方案不适用。【参考方案3】:import matplotlib.pyplot as plt
p_df.groupby('class').plot(kind='kde', ax=plt.gca())
【讨论】:
这个方法最简单,也很有效。【参考方案4】:也许你可以试试这个:
fig, ax = plt.subplots(figsize=(10,8))
classes = list(df.class.unique())
for c in classes:
df2 = data.loc[data['class'] == c]
df2.vals.plot(kind="kde", ax=ax, label=c)
plt.legend()
【讨论】:
【参考方案5】: 有两种简单的方法可以在同一个图中绘制每个组。-
使用
pandas.DataFrame.groupby
时,应指定要绘制的列(例如聚合列)。
使用seaborn.kdeplot
或seaborn.displot
并指定hue
参数
pandas v1.2.4
、matplotlib 3.4.2
、seaborn 0.11.1
OP 专门用于绘制kde
,但对于许多绘图类型(例如kind='line'
、sns.lineplot
等),步骤都是相同的。
导入和示例数据
对于样本数据,组在'kind'
列中,将绘制'duration'
的kde
,忽略'waiting'
。
import pandas as pd
import seaborn as sns
df = sns.load_dataset('geyser')
# display(df.head())
duration waiting kind
0 3.600 79 long
1 1.800 54 short
2 3.333 74 long
3 2.283 62 short
4 4.533 85 long
使用pandas.DataFrame.plot
绘图
使用.groupby
或.pivot
重塑数据
.groupby
指定聚合列['duration']
和kind='kde'
。
ax = df.groupby('kind')['duration'].plot(kind='kde', legend=True)
.pivot
ax = df.pivot(columns='kind', values='duration').plot(kind='kde')
使用seaborn.kdeplot
绘图
指定hue='kind'
ax = sns.kdeplot(data=df, x='duration', hue='kind')
使用seaborn.displot
绘图
指定hue='kind'
和kind='kde'
fig = sns.displot(data=df, kind='kde', x='duration', hue='kind')
情节
【讨论】:
以上是关于使用 Pandas 在同一图中绘制分组数据的主要内容,如果未能解决你的问题,请参考以下文章
使用 matplotlib 在一个子图中绘制来自 pandas DataFrame 的两个直方图