如何将每日数据绘制为月平均值(不同年份)
How to plot daily data as monthly averages (for separate years)
我正在尝试绘制一个图表来表示从 1980 年 1 月 1 日到 2013 年 12 月 31 日的每月河流流量数据集。
请查看这个graph
计划将“Jan Feb Mar Apr May...Dec”绘制为 x 轴,将流量 (m3/s) 绘制为 y 轴。图表上的实际线条将代表年份。或者,图表上的线条将显示从 1980 年到 2013 年每年的月平均值(从 1 月到 12 月)。
DAT = pd.read_excel('Modelled Discharge_UIB_1980-2013_Daily.xlsx',
sheet_name='Karhmong', header=None, skiprows=1,
names=['year', 'month', 'day', 'flow'],
parse_dates={ 'date': ['year', 'month', 'day'] },
index_col='date')
上面是显示是什么类型的数据
date flow
1980-01-01 104.06
1980-01-02 103.81
1980-01-03 103.57
1980-01-04 103.34
1980-01-05 103.13
... ...
2013-12-27 105.65
2013-12-28 105.32
2013-12-29 105.00
2013-12-30 104.71
2013-12-31 104.42
因为我想比较所有年份所以我尝试了下面的命令
DAT1980 = DAT[DAT.index.year==1980]
DAT1980
DAT1981 = DAT[DAT.index.year==1981
DAT1981
...等等
就 x 轴的月份分组而言,我尝试使用命令
对月份进行分组
datmonth = np.unique(DAT.index.month)
到目前为止所有这些命令都没有导致错误
然而,当我绘制图表时,我得到了这个错误
图表绘图命令
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(12,6))
ax.plot(datmonth, DAT1980, color='purple', linestyle='--', label='1980')
ax.grid()
plt.legend()
ax.set_title('Monthly River Indus Discharge Comparison 1980-2013')
ax.set_ylabel('Discharge (m3/s)')
ax.set_xlabel('Month')
axs.set_xlim(3, 5)
axs.xaxis.set_major_formatter
fig.autofmt_xdate()
ax.legend(loc='upper left', bbox_to_anchor=(1, 1))
我得到“ValueError:x 和 y 必须具有相同的第一维,但具有形状 (12,) 和 (366, 1)”作为错误
然后我尝试了
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(12,6))
ax.plot(DAT.index.month, DAT.index.year==1980, color='purple', linestyle='--', label='1980')
ax.grid()
ax.plot(DAT.index.month, DAT.index.year==1981, color='black', marker='o', linestyle='-', label='C1981')
ax.grid()
plt.legend()
ax.set_title('Monthly River Indus Discharge Comparison 1980-2013')
ax.set_ylabel('Discharge (m3/s)')
ax.set_xlabel('Month')
#axs.set_xlim(1, 12)
axs.xaxis.set_major_formatter
fig.autofmt_xdate()
ax.legend(loc='upper left', bbox_to_anchor=(1, 1))
它比之前的图表效果更好,但仍然不是我想要的
(please check out the graph here)
因为我的意图是创建一个类似于 this
的图表
我衷心感谢您的任何建议!非常感谢,如果您需要任何进一步的信息,请随时询问,我会尽快回复。
欢迎来到 SO!干得好,清楚地描述了您的问题并显示了大量代码:)
这里和那里存在一些语法问题,但我看到的主要问题是您需要在某些时候添加 groupby/aggregation 操作。也就是说,您有每日数据,但您想要的图有每月分辨率(每年)。听起来你想要每年每个月的每日值的平均值(如果有误请纠正我)。
这是一些假数据:
dr = pd.date_range('01-01-1980', '12-31-2013', freq='1D')
flow = np.random.rand(len(dr))
df = pd.DataFrame(flow, columns=['flow'], index=dr)
看起来像你的例子:
flow
1980-01-01 0.751287
1980-01-02 0.411040
1980-01-03 0.134878
1980-01-04 0.692086
1980-01-05 0.671108
...
2013-12-27 0.683654
2013-12-28 0.772894
2013-12-29 0.380631
2013-12-30 0.957220
2013-12-31 0.864612
[12419 rows x 1 columns]
您可以使用 groupby
获取每个月的平均值,使用您在上面使用的相同日期时间属性(使用一些额外的方法来帮助使数据更易于使用)
monthly = (df.groupby([df.index.year, df.index.month])
.mean()
.rename_axis(index=['year', 'month'],)
.reset_index())
monthly
有每年每个月的流量数据,即你要绘制的内容:
year month flow
0 1980 1 0.514496
1 1980 2 0.633738
2 1980 3 0.566166
3 1980 4 0.553763
4 1980 5 0.537686
.. ... ... ...
403 2013 8 0.402805
404 2013 9 0.479226
405 2013 10 0.446874
406 2013 11 0.526942
407 2013 12 0.599161
[408 rows x 3 columns]
现在要绘制单个年份,您可以从 monthly
对其进行索引并绘制流量数据。我使用你的大部分坐标轴格式:
# make figure
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(12,6))
# plotting for one year
sub = monthly[monthly['year'] == 1980]
ax.plot(sub['month'], sub['flow'], color='purple', linestyle='--', label='1980')
# some formatting
ax.set_title('Monthly River Indus Discharge Comparison 1980-2013')
ax.set_ylabel('Discharge (m3/s)')
ax.set_xlabel('Month')
ax.set_xticks(range(1, 13))
ax.set_xticklabels(['J','F','M','A','M','J','J','A','S','O','N','D'])
ax.legend()
ax.grid()
生成以下内容:
您可以使用某种循环来绘制几年:
years = [1980, 1981, 1982, ...]
for year in years:
sub = monthly[monthly['year'] == year]
ax.plot(sub['month'], sub['flow'], ...)
你们 运行 遇到了一些其他挑战(比如找到一种方法来为 30 多行设置漂亮的样式,并在循环中这样做)。如果您无法通过此处的其他 post 找到如何完成某些事情,您可以打开一个新的 post(在此基础上构建)。祝你好运!
我正在尝试绘制一个图表来表示从 1980 年 1 月 1 日到 2013 年 12 月 31 日的每月河流流量数据集。
请查看这个graph
计划将“Jan Feb Mar Apr May...Dec”绘制为 x 轴,将流量 (m3/s) 绘制为 y 轴。图表上的实际线条将代表年份。或者,图表上的线条将显示从 1980 年到 2013 年每年的月平均值(从 1 月到 12 月)。
DAT = pd.read_excel('Modelled Discharge_UIB_1980-2013_Daily.xlsx',
sheet_name='Karhmong', header=None, skiprows=1,
names=['year', 'month', 'day', 'flow'],
parse_dates={ 'date': ['year', 'month', 'day'] },
index_col='date')
上面是显示是什么类型的数据
date flow
1980-01-01 104.06
1980-01-02 103.81
1980-01-03 103.57
1980-01-04 103.34
1980-01-05 103.13
... ...
2013-12-27 105.65
2013-12-28 105.32
2013-12-29 105.00
2013-12-30 104.71
2013-12-31 104.42
因为我想比较所有年份所以我尝试了下面的命令
DAT1980 = DAT[DAT.index.year==1980]
DAT1980
DAT1981 = DAT[DAT.index.year==1981
DAT1981
...等等
就 x 轴的月份分组而言,我尝试使用命令
对月份进行分组datmonth = np.unique(DAT.index.month)
到目前为止所有这些命令都没有导致错误
然而,当我绘制图表时,我得到了这个错误
图表绘图命令
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(12,6))
ax.plot(datmonth, DAT1980, color='purple', linestyle='--', label='1980')
ax.grid()
plt.legend()
ax.set_title('Monthly River Indus Discharge Comparison 1980-2013')
ax.set_ylabel('Discharge (m3/s)')
ax.set_xlabel('Month')
axs.set_xlim(3, 5)
axs.xaxis.set_major_formatter
fig.autofmt_xdate()
ax.legend(loc='upper left', bbox_to_anchor=(1, 1))
我得到“ValueError:x 和 y 必须具有相同的第一维,但具有形状 (12,) 和 (366, 1)”作为错误
然后我尝试了
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(12,6))
ax.plot(DAT.index.month, DAT.index.year==1980, color='purple', linestyle='--', label='1980')
ax.grid()
ax.plot(DAT.index.month, DAT.index.year==1981, color='black', marker='o', linestyle='-', label='C1981')
ax.grid()
plt.legend()
ax.set_title('Monthly River Indus Discharge Comparison 1980-2013')
ax.set_ylabel('Discharge (m3/s)')
ax.set_xlabel('Month')
#axs.set_xlim(1, 12)
axs.xaxis.set_major_formatter
fig.autofmt_xdate()
ax.legend(loc='upper left', bbox_to_anchor=(1, 1))
它比之前的图表效果更好,但仍然不是我想要的 (please check out the graph here)
因为我的意图是创建一个类似于 this
的图表我衷心感谢您的任何建议!非常感谢,如果您需要任何进一步的信息,请随时询问,我会尽快回复。
欢迎来到 SO!干得好,清楚地描述了您的问题并显示了大量代码:)
这里和那里存在一些语法问题,但我看到的主要问题是您需要在某些时候添加 groupby/aggregation 操作。也就是说,您有每日数据,但您想要的图有每月分辨率(每年)。听起来你想要每年每个月的每日值的平均值(如果有误请纠正我)。
这是一些假数据:
dr = pd.date_range('01-01-1980', '12-31-2013', freq='1D')
flow = np.random.rand(len(dr))
df = pd.DataFrame(flow, columns=['flow'], index=dr)
看起来像你的例子:
flow
1980-01-01 0.751287
1980-01-02 0.411040
1980-01-03 0.134878
1980-01-04 0.692086
1980-01-05 0.671108
...
2013-12-27 0.683654
2013-12-28 0.772894
2013-12-29 0.380631
2013-12-30 0.957220
2013-12-31 0.864612
[12419 rows x 1 columns]
您可以使用 groupby
获取每个月的平均值,使用您在上面使用的相同日期时间属性(使用一些额外的方法来帮助使数据更易于使用)
monthly = (df.groupby([df.index.year, df.index.month])
.mean()
.rename_axis(index=['year', 'month'],)
.reset_index())
monthly
有每年每个月的流量数据,即你要绘制的内容:
year month flow
0 1980 1 0.514496
1 1980 2 0.633738
2 1980 3 0.566166
3 1980 4 0.553763
4 1980 5 0.537686
.. ... ... ...
403 2013 8 0.402805
404 2013 9 0.479226
405 2013 10 0.446874
406 2013 11 0.526942
407 2013 12 0.599161
[408 rows x 3 columns]
现在要绘制单个年份,您可以从 monthly
对其进行索引并绘制流量数据。我使用你的大部分坐标轴格式:
# make figure
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(12,6))
# plotting for one year
sub = monthly[monthly['year'] == 1980]
ax.plot(sub['month'], sub['flow'], color='purple', linestyle='--', label='1980')
# some formatting
ax.set_title('Monthly River Indus Discharge Comparison 1980-2013')
ax.set_ylabel('Discharge (m3/s)')
ax.set_xlabel('Month')
ax.set_xticks(range(1, 13))
ax.set_xticklabels(['J','F','M','A','M','J','J','A','S','O','N','D'])
ax.legend()
ax.grid()
生成以下内容:
您可以使用某种循环来绘制几年:
years = [1980, 1981, 1982, ...]
for year in years:
sub = monthly[monthly['year'] == year]
ax.plot(sub['month'], sub['flow'], ...)
你们 运行 遇到了一些其他挑战(比如找到一种方法来为 30 多行设置漂亮的样式,并在循环中这样做)。如果您无法通过此处的其他 post 找到如何完成某些事情,您可以打开一个新的 post(在此基础上构建)。祝你好运!