formatting timeseries x-axis in pandas/matplotlib

后端 未结 2 731
刺人心
刺人心 2021-01-24 14:52

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

相关标签:
2条回答
  • 2021-01-24 15:03

    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:

    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()
    

    0 讨论(0)
  • 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).

    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.

    0 讨论(0)
提交回复
热议问题