简体   繁体   English

在pandas / matplotlib中格式化时间轴x轴

[英]formatting timeseries x-axis in pandas/matplotlib

I would like to show each month abbreviation, as well as the year on the year. 我想显示每个月的缩写,以及每年的缩写。

I am quite close. 我很近 The issue I am currently having is that the years are incorrect. 我目前遇到的问题是年份不正确。 I have figured out that this is a issue between numpy.datetime64 (the datetime index is in this format), and python datetime which is used the 1970 epoch. 我发现这是numpy.datetime64(datetime索引采用这种格式)和python datetime(在1970年时代)之间存在的问题。 The two years shown on the chart should be 2017 and 2018 but they show 48 and 49. 图表上显示的两年应为2017年和2018年,但它们分别为48和49。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

from matplotlib.dates import MonthLocator, WeekdayLocator, DateFormatter, YearLocator

indx = pd.date_range('2017-04-01', '2019-01-01')
s = pd.Series(np.random.randn(len(indx)), index=indx)

df = pd.DataFrame(s)

ax = df.plot()
months = MonthLocator(range(1, 13), bymonthday=1, interval=1)
monthsFmt = DateFormatter("%b")
years = YearLocator(1, month=4, day=1)
yrsFmt = DateFormatter("\n %y")

ax.xaxis.set_major_locator(years)
ax.xaxis.set_major_formatter(yrsFmt)


ax.xaxis.set_minor_locator(months)
ax.xaxis.set_minor_formatter(monthsFmt)

plt.show()

How do I show the right years here? 如何在这里显示正确的年份?

在此处输入图片说明

After some playing around it seems to work if you specify the axis and then plot onto that (rather than call the pandas plot function). 经过一番尝试之后,如果指定轴然后在其上绘图(而不是调用pandas plot函数),它似乎可以工作。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

from matplotlib.dates import MonthLocator, WeekdayLocator, DateFormatter, YearLocator

indx = pd.date_range('2017-04-01', '2019-01-01')
s = pd.Series(np.random.randn(len(indx)), index=indx)

df = pd.DataFrame(s)

fig, ax = plt.subplots(1)
ax.plot(df)

months = MonthLocator(range(1, 13), bymonthday=1, interval=1)
monthsFmt = DateFormatter("%b")
years = YearLocator(1, month=4, day=1)
yrsFmt = DateFormatter("\n %Y")

ax.xaxis.set_major_locator(years)
ax.xaxis.set_major_formatter(yrsFmt)


ax.xaxis.set_minor_locator(months)
ax.xaxis.set_minor_formatter(monthsFmt)

fig.show()

Also note that I changed %y to %Y so it is formatted as 2017/2018 rather than 17/18. 另请注意,我将%y更改为%Y,因此其格式设置为2017/2018,而不是17/18。 在此处输入图片说明

Matplotlib counts years from zero but UNIX since 1970. Therefore you got years of 48, 49 and etc. To avoid this behavior of matplotlib you have to get from your pandas datetime index date part and then use %Y descriptor to get full years for major ticks: Matplotlib从零开始计数年数,但是从1970年开始是UNIX。因此,您得到48、49等年数。要避免matplotlib的这种行为,您必须从熊猫datetime索引日期部分获得,然后使用%Y描述符获取主要年份的完整年份。蜱:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.dates import MonthLocator, WeekdayLocator, DateFormatter, YearLocator

indx = pd.date_range('2017-04-01', '2019-01-01')
s = pd.Series(np.random.randn(len(indx)), index=indx.date) # get dates
df = pd.DataFrame(s)

months = MonthLocator() # MonthLocator without args set ticks for every month
monthsFmt = DateFormatter("%b")
years = YearLocator(month=4, day=1)
yrsFmt = DateFormatter("\n%Y") # correct year descriptor

ax = df.plot()
ax.xaxis.set_minor_locator(months)
ax.xaxis.set_minor_formatter(monthsFmt)
for tick in ax.xaxis.get_minor_ticks():tick.label.set_fontsize(9) 
ax.xaxis.set_major_locator(years)
ax.xaxis.set_major_formatter(yrsFmt)

plt.show()

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM