首页 > 解决方案 > 在熊猫上使用 for 循环绘图

问题描述

假设我有一个带有“日期”列的 df 用于过滤我想要的冠军,并且我通过将“日期”列设置为索引来做到这一点。此外,我有一个功能可以根据需要配置所有列类型:

import pandas as pd
df = pd.DataFrame({'Date':['26-12-2018','26-12-2018','27-12-2018','27-12-2018','28-12-2018','28-12-2018'],
                   'In':['A','B','D','Z','Q','E'],
                   'Out' : ['Z', 'D', 'F', 'H', 'Z', 'A'],
                   'Score_in' : ['6', '2', '1', '0', '1', '3'], 
                   'Score_out' : ['2','3','0', '1','1','3'],
                   'Place' : ['One','Two','Four', 'Two','Two','One']})

我可以在同一个图上绘制吗 - 因为它是一个网格 - 例如:

df.groupby('In').Score_in.sum().add(df.groupby('Out').Score_out.sum())

通过将函数参数“day”作为迭代器传递给每一天的for循环?我不明白有多好,例如:

for it in range(26:28:1):

    if it == day:
        ..plot_settings.. f(it)

标签: pythonpandasmatplotlib

解决方案


这是一段代码,用于构建数据的 matplotlib 图。应该注意的是,据我所知,matplotlib 并不是这种绘图最友好的包。

import matplotlib.pyplot as plt 
import matplotlib.dates as mdates 

df["score"] = pd.to_numeric(df["score"])
df = df.groupby(["Date", "team"]).sum()
df = df.reset_index()

fig, ax = plt.subplots()

groups = df.Date.unique()
num_groups = len(groups)

ind = np.arange(num_groups)    # the x locations for the groups
width = 0.10                   # the width of the bars

days = pd.date_range(df.Date.min(), df.Date.max(), freq = "1D")

rect_list = []
for inx, t in enumerate(df.team.unique()) :
    sub_df = df[df.team == t]
    sub_df = sub_df.set_index("Date").reindex(days)

    x_locations = ind + width * inx
    rects = ax.bar(x_locations, sub_df.score, width, bottom = 0)
    rect_list.append(rects)

ax.legend(rect_list, df.team.unique())
        
ax.set_xticks(ind + width*2)

labels = [pd.to_datetime(x).strftime("%Y-%m-%d") for x in groups]
ax.set_xticklabels(labels)

fig.show()

结果是:

在此处输入图像描述

如果您希望将每一天都放在一个单独的情节中,您可以执行以下操作:

import matplotlib.pyplot as plt 
import matplotlib.dates as mdates 

df["score"] = pd.to_numeric(df["score"])
df = df.groupby(["Date", "team"]).sum()
df = df.reset_index()

days = df.Date.unique()

fig, subplots = plt.subplots(len(days), 1)

all_teams = df.team.unique()

for d, ax in zip(days, subplots):

    sub_df = df[df.Date == d]
    
    sub_df.set_index("team", inplace=True)
    sub_df = sub_df.reindex(all_teams).sort_index().fillna(value = 0)
    
    rects = ax.bar(sub_df.index, sub_df.score, width, bottom = 0)
    ax.set_title(pd.to_datetime(d).strftime("%Y-%m-%d"))

plt.show()

输出:

在此处输入图像描述


推荐阅读