Python Matplotlib 不会显示现有子图的滚动平均值
Python Matplotlib wont show rolling averages over existing subplot
我创建了包含 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
通常 pandas 和 matplotlib 的日期时间实用程序不兼容。如果您在使用 pandas 创建的日期轴上使用 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()
希望对您有所帮助。
我创建了包含 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
通常 pandas 和 matplotlib 的日期时间实用程序不兼容。如果您在使用 pandas 创建的日期轴上使用 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()
希望对您有所帮助。