Matplotlib 创建基于Datetime的Numpy Linspace
使用 Matplotlib 制图,有时候需要创建基于时间的数据序列。而Python中最常用的日期和时间数据类型是 datetime。但Matplotlib无法直接接受datetime类型数据,并进行可视化展示。在此情况下,我们可使用 numpy.linspace() 来创建一些能够与时间处理相容的数据序列。
此文将给出一些列出数据以及如何在 Matplotlib 中可视化这些数据的案例。
阅读更多:Matplotlib 教程
创建随时间变化的数据序列
首先,让我们生成一个包含日期时间信息的numpy数组,其中每个数据点之间的时间间隔都是一周:
import datetime as dt
import numpy as np
start = dt.datetime(2018, 1, 1)
stop = dt.datetime(2018, 12, 31)
dates = np.linspace(start, stop, 52)
在此例中,创建了一个时间间隔为 52 个时间点(即固定时间间隔为1周)的 numpy 数组。可以得到以下数据:
array([datetime.datetime(2018, 1, 1, 0, 0), datetime.datetime(2018, 1, 8, 0, 0),
datetime.datetime(2018, 1, 15, 0, 0), datetime.datetime(2018, 1, 22, 0, 0),
datetime.datetime(2018, 1, 29, 0, 0), datetime.datetime(2018, 2, 5, 0, 0),
datetime.datetime(2018, 2, 12, 0, 0), datetime.datetime(2018, 2, 19, 0, 0),
datetime.datetime(2018, 2, 26, 0, 0), datetime.datetime(2018, 3, 5, 0, 0),
datetime.datetime(2018, 3, 12, 0, 0), datetime.datetime(2018, 3, 19, 0, 0),
datetime.datetime(2018, 3, 26, 0, 0), datetime.datetime(2018, 4, 2, 0, 0),
datetime.datetime(2018, 4, 9, 0, 0), datetime.datetime(2018, 4, 16, 0, 0),
datetime.datetime(2018, 4, 23, 0, 0), datetime.datetime(2018, 4, 30, 0, 0),
datetime.datetime(2018, 5, 7, 0, 0), datetime.datetime(2018, 5, 14, 0, 0),
datetime.datetime(2018, 5, 21, 0, 0), datetime.datetime(2018, 5, 28, 0, 0),
datetime.datetime(2018, 6, 4, 0, 0), datetime.datetime(2018, 6, 11, 0, 0),
datetime.datetime(2018, 6, 18, 0, 0), datetime.datetime(2018, 6, 25, 0, 0),
datetime.datetime(2018, 7, 2, 0, 0), datetime.datetime(2018, 7, 9, 0, 0),
datetime.datetime(2018, 7, 16, 0, 0), datetime.datetime(2018, 7, 23, 0, 0),
datetime.datetime(2018, 7, 30, 0, 0), datetime.datetime(2018, 8, 6, 0, 0),
datetime.datetime(2018, 8, 13, 0, 0), datetime.datetime(2018, 8, 20, 0, 0),
datetime.datetime(2018, 8, 27, 0, 0), datetime.datetime(2018, 9, 3, 0, 0),
datetime.datetime(2018, 9, 10, 0, 0), datetime.datetime(2018, 9, 17, 0, 0),
datetime.datetime(2018, 9, 24, 0, 0), datetime.datetime(2018, 10, 1, 0, 0), datetime.datetime(2018, 10, 8, 0, 0),
datetime.datetime(2018, 10, 15, 0, 0), datetime.datetime(2018, 10, 22, 0, 0),
datetime.datetime(2018, 10, 29, 0, 0), datetime.datetime(2018, 11, 5, 0, 0),
datetime.datetime(2018, 11, 12, 0, 0), datetime.datetime(2018, 11, 19, 0, 0),
datetime.datetime(2018, 11, 26, 0, 0), datetime.datetime(2018, 12, 3, 0, 0),
datetime.datetime(2018, 12, 10, 0, 0), datetime.datetime(2018, 12, 17, 0, 0),
datetime.datetime(2018, 12, 24, 0, 0), datetime.datetime(2018, 12, 31, 0, 0)],
dtype=object)
接下来,我们使用np.random模块,生成对应的数据,以便可视化展示。
y = np.random.normal(loc=0.0, scale=1.0, size=len(dates))
fig, ax = plt.subplots()
ax.plot_date(dates, y, '-')
# 设置时间间隔格式
date_format = mpl_dates.DateFormatter('%b, %d %Y')
ax.xaxis.set_major_formatter(date_format)
# 设置x轴标签旋转角度
fig.autofmt_xdate()
np.random.normal()
函数的作用是创建一个正态分布的 numpy 数组。
优化横坐标的时间标签
当数据序列不是固定的一周也不是固定的时间间隔时,我们需要进行特别的处理来优化横坐标的时间标签。
这一步可以通过 matplotlib.dates 模块中的日历来完成。在下面的示例中,我们将通过每个月的第一个星期一(weekday=0)来处理时间标签。
import matplotlib.dates as mdates
start = dt.datetime(2018, 1, 1)
stop = dt.datetime(2020, 1, 1)
dates_2 = mdates.MonthLocator(bymonthday=1, interval=3)
dates_2_fmt = mdates.DateFormatter('%Y-%m-%d')
y = np.random.normal(loc=0.0, scale=1.0, size=len(dates))
fig, ax = plt.subplots()
ax.plot(dates, y)
# 设置横轴上显示的时间标签及其格式
ax.xaxis.set_major_locator(dates_2)
ax.xaxis.set_major_formatter(dates_2_fmt)
# 旋转横坐标上显示的日期标签
fig.autofmt_xdate()
处理时间序列数据的缺失值
在实际数据处理中,经常遇到对某一段时间序列数据的缺失值的处理。无论是插值法还是去除缺失值,都要用到时间信息。在下面的示例中,我们将按周进行数据插值,并展示如何处理缺失值。
start = dt.datetime(2018, 1, 1)
stop = dt.datetime(2019, 1, 1)
# 每周生成一个数据点
dates = np.linspace(start, stop, 52)
# 生成带有缺失值的数据序列
data = np.random.randn(len(dates)) * 10
data[10:15] = np.nan
fig, ax = plt.subplots()
ax.plot(dates, data, 'o-', label='input data')
# 按周进行数据插值
new_dates = np.linspace(start, stop, 365)
new_data = np.interp(new_dates, dates, data)
# 绘制插值后的曲线
ax.plot(new_dates, new_data, '-', label='resampled')
# 设置x轴标签旋转角度
fig.autofmt_xdate()
# 显示图例
ax.legend()
通过 np.interp()
函数,按周对数据进行了插值。
总结
本文展示了如何使用 numpy 库来创建基于 datetime 的数据,并根据不同的需求进行可视化处理。除此之外,还介绍了如何处理缺失值、如何优化横坐标的时间标签等细节问题,希望能对大家的数据处理和分析有所帮助。