代码之家  ›  专栏  ›  技术社区  ›  Leon Kyriacou

Python Matplotlib不会显示现有子图上的滚动平均值

  •  0
  • Leon Kyriacou  · 技术社区  · 7 年前

    我已经创建了包含并排放置的2个条的子图。 我现在想把7天的滚动平均数加在横线的顶部。

    我无法使绘图正常工作,无论我最后定义的是哪一个,似乎都占据了这个数字。我希望所有4个绘图都在同一个数字上。我该如何实现这一点?

    date_index = pd.date_range(df.Created.min(), df.Created.max(), freq='D')
    
    fig = plt.figure()
    ax2 = fig.add_subplot(111)
    ax22 = ax2.twinx()
    
    s1 = CDdf.resample('D', on='Created').size().fillna(0).reindex(date_index, fill_value=0)
    s2 = CDdf.groupby('Created')['Machine Count'].first().fillna(0).reindex(date_index, fill_value=0)
    s = (s1/s2).fillna(0).reindex(date_index, fill_value=0)
    
    s1.plot(kind='bar', ax=ax2, position=0, label='Sales Total', width=0.25)
    s.plot(kind='bar', ax=ax22, color='red', position=1, label='Adjusted For Machine Count', width=0.25)
    
    s1rolling = s1.rolling(window=7,center=False).mean().fillna(0).reindex(date_index, fill_value=0)
    plt.plot(s1rolling, color='blue', label='_nolegend_')
    
    srolling = s.rolling(window=7,center=False).mean().fillna(0).reindex(date_index, fill_value=0)
    plt.plot(srolling, color='red', label='_nolegend_')
    
    ax2.set_ylim(0,s1.max()*1.1)
    ax22.set_ylim(0,s1.max()*1.1)
    plt.legend(loc='upper left')
    plt.ylabel('Frequency')
    plt.title('Items Deposited Per Day')
    
    ticklabels = s.index.strftime('%Y-%m-%d')
    ax2.xaxis.set_major_formatter(ticker.FixedFormatter(ticklabels))
    
    plt.show()
    

    数据样本:

        Created Quoted Price    Machine Count
    6   2017-10-06  0.99    3
    454 2017-10-21  0.43    11
    534 2017-10-21  0.98    11
    487 2017-10-21  0.05    11
    530 2017-10-21  0.05    11
    482 2017-10-21  0.06    11
    503 2017-10-21  0.05    11
    416 2017-10-21  0.24    11
    532 2017-10-21  0.07    11
    469 2017-10-21  0.52    11
    459 2017-10-21  0.05    11
    515 2017-10-21  1.82    11
    411 2017-10-21  0.32    11
    539 2017-10-21  0.05    11
    508 2017-10-21  0.23    11
    1057    2017-10-28  0.07    11
    1037    2017-10-28  0.06    11
    1042    2017-10-28  0.17    11
    1048    2017-10-28  0.34    11
    1028    2017-10-28  0.09    11
    1053    2017-10-28  0.50    11
    1055    2017-10-28  1.33    11
    1149    2017-10-29  0.25    11
    1142    2017-10-29  0.12    11
    1160    2017-10-29  0.05    11
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   Flabetvibes    7 年前

    通常,pandas和matplotlib的datetimes实用程序是不兼容的。如果您使用 matplotlib.dates 对象,则在大多数情况下都会失败。

    以下是一个解决方案,其中pandas用于打印,matplotlib用于格式化(请参阅注释):

    import matplotlib.pyplot as plt  # version 2.1.0
    import matplotlib.ticker as ticker
    import pandas as pd  # version 0.21.0
    
    df = pd.read_csv('data.csv', delim_whitespace=True, index_col=0, parse_dates=['Created'])
    date_index = pd.date_range(df.Created.min(), df.Created.max(), freq='D')
    
    _, ax = plt.subplots()
    
    s1 = df.resample('D', on='Created').size().fillna(0).reindex(date_index, fill_value=0)
    s2 = df.groupby('Created')['MachineCount'].first().fillna(0).reindex(date_index, fill_value=0)
    s = (s1 / s2).fillna(0).reindex(date_index, fill_value=0)
    
    s1rolling = s1.rolling(window=7, center=False).mean().fillna(0).reindex(date_index, fill_value=0)
    s2rolling = s2.rolling(window=7, center=False).mean().fillna(0).reindex(date_index, fill_value=0)
    srolling = s.rolling(window=7, center=False).mean().fillna(0).reindex(date_index, fill_value=0)
    
    # Plot with pandas without date axis (i.e. use_index=False).
    s1.plot(kind='bar', color='C0', position=0, label='Sales Total', width=0.25, use_index=False)
    s.plot(kind='bar', color='C1', position=1, label='Adjusted For Machine Count', width=0.25, use_index=False)
    
    # Plot with pandas without date axis (i.e. use_index=False).
    s1rolling.plot(kind='line', color='C0', label='_nolegend_', use_index=False)
    srolling.plot(kind='line', color='C1',  label='_nolegend_', use_index=False)
    
    plt.ylim(0, s1.max() * 1.1)
    plt.legend(loc='upper left')
    plt.ylabel('Frequency')
    plt.title('Items Deposited Per Day')
    
    # Format date axis with matplotlib.
    ticklabels = s1.index.strftime('%Y-%m-%d')
    ax.xaxis.set_major_formatter(ticker.FixedFormatter(ticklabels))
    plt.xticks(rotation=90)
    
    plt.tight_layout()
    plt.show()
    

    enter image description here

    我希望这对你有帮助。