使用axvspan进行日期范围绘制

11
我想绘制一些随季节变化的时间序列,并使用axvspan将图中冬季部分与夏季部分区分开来。我正在使用pyplot.plot_date。我的y值是一个浮点数的np数组,我的x值是使用datetime对象转换的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

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

2个回答

18
在Matplotlib中,日期时间轴也使用数字,
Matplotlib使用浮点数来表示日期,指定自0001-01-01 UTC以来的天数加1。
许多函数(如plot,scatter,bar等)会自动将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()

enter image description here


太好了,这个可行。谢谢。还有一个问题:是否也可以为多年的时间间隔着色/标记相同?例如,每年三月都用相同的颜色,只有一个标签(“三月”)? - Maarten
你可以创建多个axvspan,但只给第一个加上标签,这样图例中就只会出现一个。 - ImportanceOfBeingErnest

1
感谢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)

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接