我有以下 Pandas 数据框,并想在 n
中水平创建 a1 row
绘图,其中 n = unique labels(l1,l2,.)(例如在以下示例中由于 l1 and l2
) 为两个图。然后对于这两个图,每个图都将 a4
绘制为 x 轴,将 a3
绘制为 y 轴。例如,ax[0]
将包含 a1
的图形,其中包含三条线,连接以下数据的点 [(1,15)(2,20)],[(1,17)(2,19)],[(1,23)(2,15)]
。
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
d = {'a1': ['l1','l1','l1','l1','l1','l1','l2','l2','l2','l2','l2','l2'],
'a2': ['a', 'a', 'b','b','c','c','d','d','e','e','f','f'],
'a3': [15,20,17,19,23,15,22,21,23,23,24,27],
'a4': [1,2,1,2,1,2,1,2,1,2,1,2]}
df=pd.DataFrame(d)
df
a1 a2 a3 a4
1 a 15 1
1 a 20 2
1 b 17 1
1 b 19 2
1 c 23 1
1 c 15 2
2 d 22 1
2 d 21 2
2 e 23 1
2 e 23 2
2 f 24 1
2 f 27 2
我目前有以下几点:
def graph(dataframe):
x = dataframe["a4"]
y = dataframe["a3"]
ax[0].plot(x,y) #how do I plot and set the title for each group in their respective subplot without the use of for-loop?
fig, ax = plt.subplots(1,len(pd.unique(df["a1"])),sharey='row',figsize=(15,2))
df.groupby(["a1"]).apply(graph)
然而,我上面的尝试只在第一个子图上绘制了所有 a3 和 a4(因为我写了 ax[0].plot()
)。我总是可以使用 for 循环来完成所需的任务,但是对于 a1
中的大量唯一组,计算成本会很高。有没有办法使它成为行 ax[0].plot(x,y)
上的单行并且它在没有 for 循环的情况下完成所需的任务?任何输入表示赞赏。
答案 0 :(得分:1)
在使用 Pandas 绘制此数据时,我没有看到任何避免 for 循环的方法。我最初的想法是重塑数据框以使 subplots=True
工作,如下所示:
dfp = df.pivot(columns='a1').swaplevel(axis=1).sort_index(axis=1)
dfp
但我不知道如何选择列 MultiIndex
的级别 1 来使 dfp.plot(x='a4', y='a3', subplots=True)
之类的东西起作用。
删除级别 0,然后运行绘图功能
dfp.droplevel(axis=1, level=0).plot(x='a4', y='a3', subplots=True)
加注 ValueError: x must be a label or position
。即使这有效,仍然存在将正确的点链接在一起的问题。
创建 seaborn package 是为了方便地绘制此类数据集。如果您愿意使用它,这里是一个带有 relplot
的示例:
import pandas as pd # v 1.1.3
import seaborn as sns # v 0.11.0
d = {'a1': ['l1','l1','l1','l1','l1','l1','l2','l2','l2','l2','l2','l2'],
'a2': ['a', 'a', 'b','b','c','c','d','d','e','e','f','f'],
'a3': [15,20,17,19,23,15,22,21,23,23,24,27],
'a4': [1,2,1,2,1,2,1,2,1,2,1,2]}
df = pd.DataFrame(d)
sns.relplot(data=df, x='a4', y='a3', col='a1', hue ='a2', kind='line', height=4)
您可以使用 palette
参数自定义颜色并使用 col_wrap
调整网格布局。