在 matplotlib 中使用 axvspan 作为日期范围

Posted

技术标签:

【中文标题】在 matplotlib 中使用 axvspan 作为日期范围【英文标题】:Using axvspan for date ranges in matplotlib 【发布时间】:2019-09-15 22:18:09 【问题描述】:

我想绘制一些随季节变化的时间序列,并使用 axvspan 将冬季的部分绘图阴影与夏季的部分阴影不同。我正在使用pyplot.plot_date。我的 y 值是浮点数的 np 数组,我的 x 值是使用转换的日期时间对象的 np 数组

    datetime.strptime(date, '%m-%d-%Y'). 

我想使用pyplot.axvspan 来应用阴影,但它似乎只适用于 x 轴的常规数字,而我的 x 轴是日期。我遇到的错误是

    ValueError: view limit minimum -36858.05 is less than 1 and is an invalid Matplotlib date value. This often happens if you pass a non-datetime value to an axis that has datetime units

有什么办法可以解决这个问题?

【问题讨论】:

【参考方案1】:

在 matplotlib 日期时间轴也使用数字,namely

Matplotlib 使用浮点数表示日期,指定自 0001-01-01 UTC 以来的天数,再加上 1。

plotscatterbar 等许多函数会自动将 datetime 对象转换为这些数字,而许多辅助函数(例如 axvspan)直到最新版本的 matplotlib 才进行这种自动转换.

所以在 matplotlib 3 中你可以轻松做到

ax.axvspan(datetime(2019,3,1), datetime(2019,3,31))

但如果使用旧版本,您需要手动操作,例如使用matplotlib.dates.date2num,例如

ax.axvspan(date2num(datetime(2019,3,1)), date2num(datetime(2019,3,31)))

一些完整的例子:

from datetime import datetime
import matplotlib.pyplot as plt
from matplotlib.dates import date2num

fig, ax = plt.subplots()

ax.plot([datetime(2019,2,14), datetime(2019,4,26)], [1,2])

ax.axvspan(date2num(datetime(2019,3,1)), date2num(datetime(2019,3,31)), 
           label="March", color="crimson", alpha=0.3)

ax.legend()
fig.autofmt_xdate()
plt.show()

【讨论】:

太好了,这行得通。谢谢。还有一个问题:是否也可以有一个多年的时间间隔,颜色/标签相同?例如每年三月的颜色都一样,只有一个标签(“三月”)? 你会创建几个axvspans,但只给第一个标签。然后只有一个出现在图例中。【参考方案2】:

感谢 ImportanceOfBeingErnest 的帮助,对于任何阅读这本书的人来说,这就是我如何制作具有冬季/夏季背景和单一标签的情节:

yearlist = ['2013','2014','2015','2016','2017','2018','2019']

fig, ax = plt.subplots(figsize=(20, 10))
for i in range(len(yearlist)):
    if yearlist[i] == '2013':
        ax.axvspan(date2num(datetime.datetime(2012,10,15)), date2num(datetime.datetime(int(yearlist[i]),5,15)), 
           label="winter (15 october - 15 may)", color="crimson", alpha=0.3)
        ax.axvspan(date2num(datetime.datetime(int(yearlist[i]),5,15)), date2num(datetime.datetime(int(yearlist[i]),10,15)), 
           label="summer (15 may - 15 october)", color="blue", alpha=0.3)
    else:
        ax.axvspan(date2num(datetime.datetime(int(yearlist[i-1]),10,15)), date2num(datetime.datetime(int(yearlist[i]),5,15))
           , color="crimson", alpha=0.3)
        ax.axvspan(date2num(datetime.datetime(int(yearlist[i]),5,15)), date2num(datetime.datetime(int(yearlist[i]),10,15)), 
            color="blue", alpha=0.3)

【讨论】:

以上是关于在 matplotlib 中使用 axvspan 作为日期范围的主要内容,如果未能解决你的问题,请参考以下文章

python使用matplotlib可视化线图(line plot)使用arrow函数在matplotlib可视化图像中添加箭头(drawing arrows in matplotlib)

Matplotlib快速入门

在 ipython 中使用 matplotlib 显示图像

使用 matplotlib 的频率图

matplotlib 在 tkinter 画布中的缩放功能

如何在 matplotlib 中使用(随机)*.otf 或 *.ttf 字体?