使用 python matplotlib 创建多线图
Using python matplotlib to create multi line graph
我想创建一个折线图,其中 y 轴有多条线,用于在我的数据框列中找到的每个唯一条目。
我的数据框看起来像这样 –
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame({'command': ['start', 'start', 'hold',
'release', 'hold', 'start',
'hold', 'hold', 'hold'],
'name': ['fred', 'wilma', 'barney',
'fred', 'barney', 'betty',
'pebbles', 'dino', 'wilma'],
'date': ['2020-05', '2020-05', '2020-05',
'2020-06', '2020-06', '2020-06',
'2020-07', '2020-07', '2020-07']})
我正在尝试创建一个以 X 轴为日期的折线图,而 y 轴将为每个命令条目(在本例中为开始、保持和释放)单独一行。
我尝试使用 groupby 然后执行这个 –
dfg = df.groupby(['command', 'date']).size()
for i in dfg.command.unique():
x = dfg[dfg.command==i]['date']
y = dfg[dfg.command==i]['size']
plt.plot(x, y)
plt.show()
但是我得到这个错误 - AttributeError: 'Series' object has no attribute 'command'
我还尝试创建一个枢轴 table 并从那里构建图表,如下所示 -
df_pv = pd.pivot_table(df, index=['command', 'date'],
values='name',
aggfunc='count')
df_pv.rename(columns={'name': 'count'}, inplace=True)
for i in df_pv.command.unique():
x = df_pv[df_pv.command==i]['date']
y = df_pv[df_pv.command==i]['count']
plt.plot(x, y)
plt.show()
但是 returns 错误 - AttributeError: 'DataFrame' object has no attribute 'command'
我不确定我的方法是否遗漏了什么?
或者是否有更好的实现方法?
谢谢。
你们非常亲密。正如第一个错误所示 df.groupby(['command', 'date']).size()
returns 一个带有多索引的系列。如果您想使用它,可以使用 .reset_index()
将其转换为数据框
dfg = df.groupby(['command', 'date']).size().reset_index()
fig,ax = plt.subplots()
for com in dfg['command'].unique():
ax.plot(dfg.loc[dfg['command']==com,'date'],dfg.loc[dfg['command']==com,0],'o-', label=com)
ax.legend()
请注意,您也可以直接使用 MultiIndex(尽管我通常觉得它更麻烦)。
您可以使用 groupby(level=)
遍历多索引的特定级别,并使用 MultiIndex.get_level_values()
:
访问给定级别的内容
dfg = df.groupby(['command', 'date']).size()
fig,ax = plt.subplots()
for com,subdf in dfg.groupby(level=0):
ax.plot(subdf.index.get_level_values(level=1),subdf.values,'o-', label=com)
ax.legend()
最后,如果你想省去自己编写循环的麻烦,你可以使用 seaborn
,这对于这种绘图来说非常容易使用(尽管你需要转换你的数据框就像在第一个解决方案中一样)
dfg = df.groupby(['command', 'date']).size().reset_index()
plt.figure()
sns.lineplot(data=dfg, x='date', y=0, hue='command', marker='o')
如果你真的想变得很花哨,你可以放弃自己转换原始数据框,让 seaborn.lineplot()
来做,通过指示它如何聚合每个日期的值:
sns.lineplot(data=df, x='date', y=0, hue='command', estimator=pd.value_counts, marker='o')
所有这些解决方案都产生相同的输出,但在美学上存在一些细微差异。
我想创建一个折线图,其中 y 轴有多条线,用于在我的数据框列中找到的每个唯一条目。
我的数据框看起来像这样 –
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame({'command': ['start', 'start', 'hold',
'release', 'hold', 'start',
'hold', 'hold', 'hold'],
'name': ['fred', 'wilma', 'barney',
'fred', 'barney', 'betty',
'pebbles', 'dino', 'wilma'],
'date': ['2020-05', '2020-05', '2020-05',
'2020-06', '2020-06', '2020-06',
'2020-07', '2020-07', '2020-07']})
我正在尝试创建一个以 X 轴为日期的折线图,而 y 轴将为每个命令条目(在本例中为开始、保持和释放)单独一行。
我尝试使用 groupby 然后执行这个 –
dfg = df.groupby(['command', 'date']).size()
for i in dfg.command.unique():
x = dfg[dfg.command==i]['date']
y = dfg[dfg.command==i]['size']
plt.plot(x, y)
plt.show()
但是我得到这个错误 - AttributeError: 'Series' object has no attribute 'command'
我还尝试创建一个枢轴 table 并从那里构建图表,如下所示 -
df_pv = pd.pivot_table(df, index=['command', 'date'],
values='name',
aggfunc='count')
df_pv.rename(columns={'name': 'count'}, inplace=True)
for i in df_pv.command.unique():
x = df_pv[df_pv.command==i]['date']
y = df_pv[df_pv.command==i]['count']
plt.plot(x, y)
plt.show()
但是 returns 错误 - AttributeError: 'DataFrame' object has no attribute 'command'
我不确定我的方法是否遗漏了什么?
或者是否有更好的实现方法?
谢谢。
你们非常亲密。正如第一个错误所示 df.groupby(['command', 'date']).size()
returns 一个带有多索引的系列。如果您想使用它,可以使用 .reset_index()
dfg = df.groupby(['command', 'date']).size().reset_index()
fig,ax = plt.subplots()
for com in dfg['command'].unique():
ax.plot(dfg.loc[dfg['command']==com,'date'],dfg.loc[dfg['command']==com,0],'o-', label=com)
ax.legend()
请注意,您也可以直接使用 MultiIndex(尽管我通常觉得它更麻烦)。
您可以使用 groupby(level=)
遍历多索引的特定级别,并使用 MultiIndex.get_level_values()
:
dfg = df.groupby(['command', 'date']).size()
fig,ax = plt.subplots()
for com,subdf in dfg.groupby(level=0):
ax.plot(subdf.index.get_level_values(level=1),subdf.values,'o-', label=com)
ax.legend()
最后,如果你想省去自己编写循环的麻烦,你可以使用 seaborn
,这对于这种绘图来说非常容易使用(尽管你需要转换你的数据框就像在第一个解决方案中一样)
dfg = df.groupby(['command', 'date']).size().reset_index()
plt.figure()
sns.lineplot(data=dfg, x='date', y=0, hue='command', marker='o')
如果你真的想变得很花哨,你可以放弃自己转换原始数据框,让 seaborn.lineplot()
来做,通过指示它如何聚合每个日期的值:
sns.lineplot(data=df, x='date', y=0, hue='command', estimator=pd.value_counts, marker='o')
所有这些解决方案都产生相同的输出,但在美学上存在一些细微差异。