如何在Matplotlib X轴设置自定义年份:解决日期显示为1970年代问题
图表X轴显示1970年代日期,如何修正为2020-2030区间?
问题描述:希望红色曲线起始年份为2020年,所有曲线结束年份为2030年,但当前图表X轴始终显示1970年代的日期。
图表示例:
相关代码:
from matplotlib.dates import YearLocator, MonthLocator, DateFormatter import pylab years = YearLocator() # every year months = MonthLocator() # every month yearsFmt = DateFormatter('%Y') J_diff = cInc[1:] - cInc[:-1] J_diffint = cIncint[1:] - cIncint[:-1] #J_diff = np.diff(cInc) fig = plt.figure(facecolor='w') ax = fig.add_subplot(111, facecolor='#dddddd', axisbelow=True) ax.xaxis.set_major_locator(years) ax.xaxis.set_major_formatter(yearsFmt) ax.xaxis.set_minor_locator(months) #ax.plot(t, U*100000, 'black', alpha=1, lw=2, label='uninfected') #ax.plot(t, Lf/100000, 'r', alpha=1, lw=2, label='latent fast') #ax.plot(t, Ls/100000, 'black', alpha=1, lw=2, label='latent slow') #ax.plot(t, I*100000, 'green', alpha=1, lw=2, label='infected') #ax.plot(t, R*100000, 'red', alpha=1, lw=2, label='recovered') ax.plot(t[1:], J_diff*100000, 'blue', alpha=1, lw=2, label='incidence') ax.plot(t[1:]+500, J_diffint*100000, 'red', alpha=1, lw=2, label='intervention incidence') #ax.plot(t, cInc, 'red', alpha=1, lw=2, label='Prevalence') ax.set_xlabel('Time in years') ax.set_ylabel('Number') ax.grid(b=True, which='major', c='w', lw=2, ls='-') legend = ax.legend() legend.get_frame().set_alpha(0.5) plt.title("Intervention") plt.show()
问题原因
matplotlib默认将数值0映射为Unix纪元起始日期(1970-01-01),你的t数组是从0开始的年份偏移值(而非实际日期对象),再加上错误给红色曲线的X轴数据加了+500,导致X轴刻度逻辑混乱,显示出1970年代的日期。
修正方案
方案一:将数值转换为实际日期对象(推荐)
把t的偏移值转换成对应2020-2030的datetime对象,让matplotlib的日期定位器正确识别年份:
from matplotlib.dates import YearLocator, MonthLocator, DateFormatter import pylab import datetime # 新增导入 years = YearLocator() # every year months = MonthLocator() # every month yearsFmt = DateFormatter('%Y') J_diff = cInc[1:] - cInc[:-1] J_diffint = cIncint[1:] - cIncint[:-1] #J_diff = np.diff(cInc) fig = plt.figure(facecolor='w') ax = fig.add_subplot(111, facecolor='#dddddd', axisbelow=True) ax.xaxis.set_major_locator(years) ax.xaxis.set_major_formatter(yearsFmt) ax.xaxis.set_minor_locator(months) # 将t转换为2020年起始的datetime数组 # 假设t是[0,1,2,...,10],对应2020到2030 t_dates = [datetime.datetime(2020 + int(year), 1, 1) for year in t] # 修改绘图代码,使用转换后的日期对象 ax.plot(t_dates[1:], J_diff*100000, 'blue', alpha=1, lw=2, label='incidence') # 去掉错误的+500,直接用对应2020起始的日期 ax.plot(t_dates[1:], J_diffint*100000, 'red', alpha=1, lw=2, label='intervention incidence') ax.set_xlabel('Time in years') ax.set_ylabel('Number') ax.grid(b=True, which='major', c='w', lw=2, ls='-') legend = ax.legend() legend.get_frame().set_alpha(0.5) plt.title("Intervention") # 手动设置X轴范围为2020-2030 ax.set_xlim(datetime.datetime(2020,1,1), datetime.datetime(2030,1,1)) plt.show()
方案二:手动设置X轴刻度与标签
如果不想使用datetime对象,可以直接自定义X轴的刻度和标签,同时去掉错误的+500:
from matplotlib.dates import YearLocator, MonthLocator, DateFormatter import pylab years = YearLocator() # every year months = MonthLocator() # every month yearsFmt = DateFormatter('%Y') J_diff = cInc[1:] - cInc[:-1] J_diffint = cIncint[1:] - cIncint[:-1] #J_diff = np.diff(cInc) fig = plt.figure(facecolor='w') ax = fig.add_subplot(111, facecolor='#dddddd', axisbelow=True) # 注释掉日期定位器,改用自定义刻度 # ax.xaxis.set_major_locator(years) # ax.xaxis.set_major_formatter(yearsFmt) # ax.xaxis.set_minor_locator(months) # 去掉红色曲线的+500 ax.plot(t[1:], J_diff*100000, 'blue', alpha=1, lw=2, label='incidence') ax.plot(t[1:], J_diffint*100000, 'red', alpha=1, lw=2, label='intervention incidence') # 手动设置X轴刻度和对应标签(假设t范围是0-10,对应2020-2030) ax.set_xticks(t) ax.set_xticklabels([2020 + int(x) for x in t]) # 设置X轴范围 ax.set_xlim(0, 10) ax.set_xlabel('Time in years') ax.set_ylabel('Number') ax.grid(b=True, which='major', c='w', lw=2, ls='-') legend = ax.legend() legend.get_frame().set_alpha(0.5) plt.title("Intervention") plt.show()
关键注意点
- 必须去掉红色曲线X轴数据中的
+500,这个操作会让X轴数值跳到500以上,对应matplotlib的日期是1970+500=2470年,完全偏离需求区间。 - 确保
t的数值范围对应2020-2030的年份偏移(比如0对应2020,10对应2030),如果t是天数,需要先转换成年份偏移再处理。
内容的提问来源于stack exchange,提问作者Landon
相关产品推荐
相关产品推荐

