python中带阴影范围的多年时间序列费用

python中带阴影范围的多年时间序列费用,python,pandas,matplotlib,Python,Pandas,Matplotlib,我在Excel中创建了这些图表,这些图表是从以下结构的数据框架中创建的: 因此,可以这样创建图表,将5年范围区域堆叠在Min范围(无填充)的顶部,以便范围区域可以着色。最小值/最大值/范围/平均值列均在2016-2020年计算 我知道,通过使用日期索引和应用月份标签,我可以在同一轴上绘制多年的线,但有没有办法复制此图表的阴影,更具体地说,如果我的数据帧采用简单的日期索引值格式,例如: Quantity 1/1/2016 6 2/1/2016 4 3/1/2

我在Excel中创建了这些图表,这些图表是从以下结构的数据框架中创建的:

因此,可以这样创建图表,将
5年范围
区域堆叠在
Min
范围(无填充)的顶部,以便范围区域可以着色。最小值/最大值/范围/平均值列均在2016-2020年计算

我知道,通过使用日期索引和应用月份标签,我可以在同一轴上绘制多年的线,但有没有办法复制此图表的阴影,更具体地说,如果我的数据帧采用简单的日期索引值格式,例如:

            Quantity
1/1/2016    6
2/1/2016    4
3/1/2016    1
4/1/2016    10
5/1/2016    7
6/1/2016    10
7/1/2016    10
8/1/2016    2
9/1/2016    1
10/1/2016   2
11/1/2016   3
…   …
1/1/2020    4
2/1/2020    8
3/1/2020    3
4/1/2020    5
5/1/2020    8
6/1/2020    6
7/1/2020    6
8/1/2020    7
9/1/2020    8
10/1/2020   5
11/1/2020   4
12/1/2020   3
1/1/2021    9
2/1/2021    7
3/1/2021    7
我在绘图库中找不到任何类似的东西。

两步过程

  • 重新构造DF,使年份为列,行按统一日期时间索引
  • 使用matplotlib进行绘图

  • 对不起,罗布,完全错过了这个!这起作用了,我还有最后一个问题——如果我有多年的每周数据,我该如何应对?我可以将年度周格式转换为日期时间(例如2018-W04),但然后根据年份获得不同的日期。有没有办法将其保留为周数并绘制多年的图表?如果您改变了多索引的构建方式,您可以每周进行一次
    dfg=(df.set_index(pd.MultiIndex.from_数组([df.index.isocalendar().week,df.index.isocalendar().year],name=[“week”,“year”)).loc[lambda-dfa:dfa.index.get_-level_值(“week”)因此,当我尝试并绘制它返回ufunc“isfinite”时,输入类型不受支持,并且根据强制转换规则“safe”
    dfg=(df.set_index(pd.MultiIndex.from_数组([df.index.isocalendar().week.astype(int),df.index.isocalendar().year],name=[“week”,“year”)).loc[lambda dfa:dfa.index.get_level_values(“week”)谢谢!事实上我已经计算出了这一部分,我只是很难将其转换为绘图,因为MonthLocator在这里不适用
    
    import datetime as dt
    import matplotlib.pyplot as plt
    import matplotlib.dates as mdates
    
    # straight date as index, quantity as column
    d = pd.date_range("1-Jan-2016", "1-Mar-2021", freq="MS")
    df = pd.DataFrame({"Quantity":np.random.randint(1, 10, len(d))}, index=d)
    
    
    # re-structure as multi-index, make year column
    # add calculated columns
    dfg = (df.set_index(pd.MultiIndex.from_arrays([df.index.map(lambda d: dt.date(dt.date.today().year, d.month, d.day)), 
                                                   df.index.year], names=["month","year"]))
     .unstack("year")
     .droplevel(0, axis=1)
     .assign(min=lambda dfa: dfa.loc[:,[c for c in dfa.columns if dfa[c].count()==12]].min(axis=1),
             max=lambda dfa: dfa.loc[:,[c for c in dfa.columns if dfa[c].count()==12]].max(axis=1),
             avg=lambda dfa: dfa.loc[:,[c for c in dfa.columns if dfa[c].count()==12]].mean(axis=1).round(1),
            )
    )
    
    fig, ax = plt.subplots(1, figsize=[14,4])
    
    # now plot all the parts
    ax.fill_between(dfg.index, dfg["min"], dfg["max"], label="5y range", facecolor="oldlace")
    ax.plot(dfg.index, dfg[2020], label="2020", c="r")
    ax.plot(dfg.index, dfg[2021], label="2021", c="g")
    ax.plot(dfg.index, dfg.avg, label="5 yr avg", c="y", ls=(0,(1,2)), lw=3)
    
    # adjust axis
    ax.xaxis.set_major_locator(mdates.MonthLocator())
    ax.xaxis.set_major_formatter(mdates.DateFormatter('%b'))
    ax.legend(loc = 'best')