Matplotlib用奇数间隔对YearLocator进行日期 [英] Matplotlib dates YearLocator with odd intervals

查看:28
本文介绍了Matplotlib用奇数间隔对YearLocator进行日期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在,当我的时间序列在十年的开始(即1990、2000、2010等)开始时,我有一些工作代码可以格式化为我的规范,但是我不知道如何适应我的规范当我的时间序列在甚至不连续的一年(即1993年)开始时,代码具有正确的格式.

 将pandas导入为pd导入matplotlib.pyplot作为plt从matplotlib导入日期开始def format_xaxis(fig):years = date.YearLocator(10,month = 1,day = 1)years1 = dates.YearLocator(2,month = 1,day = 1)dfmt = dates.DateFormatter('%Y')dfmt1 = dates.DateFormatter('%y')[图轴中i的i.xaxis.set_major_locator(年)][图轴中i的i.xaxis.set_minor_locator(years1)][Fig.axes中i的i.xaxis.set_major_formatter(dfmt)][图轴中i的i.xaxis.set_minor_formatter(dfmt1)][图轴中i的i.get_xaxis().set_tick_params(which ='major',pad = 15)]对于图轴中的t:对于t.xaxis.get_major_ticks()中的刻度:tick.label1.set_horizo​​ntalalignment('center')用于t.get_xmajorticklabels()中的标签:label.set_rotation(0)label.set_weight('bold')对于t.xaxis.get_minorticklabels()中的标签:label.set_fontsize('small')用于t.xaxis.get_minorticklabels()[:: 5]中的标签:label.set_visible(False)df = pd.DataFrame.from_dict({'Y':{0:0.15,1:0.18,2:0.23,3:0.15,4:0.15,5:0.15,6:0.17,7:0.175,8:0.212,9:0.184,10:0.18,11:0.18,12:0.21,13:0.139,14:0.15,15:0.128,16:0.126,17:0.1,18:0.11,19:0.183,20:0.14,21:0.12,22:0.155,23:0.245,24:0.248,25:0.262,26:0.17,27:0.143,28:0.13,29:0.102,30:0.258,31:0.293,32:0.196,33:0.21,34:0.14、35:0.17},'日期':{0:'1990-06-10 00:00:00',1:'1991-07-26 00:00:00',2:'1992-10-15 00:00:00',3:'1993-10-08 00:00:00',4:'1994-04-07 00:00:00',5:'1994-11-20 00:00:00',6:'1995-04-24 00:00:00',7:'1996-02-13 00:00:00',8:'1996-04-15 00:00:00',9:'1996-09-12 00:00:00',10:'1997-02-13 00:00:00',11:'1997-04-20 00:00:00',12:'1997-08-23 00:00:00',13:'1997-11-06 00:00:00',14:'1998-04-15 00:00:00',15:'1999-05-04 00:00:00',16:'2000-03-17 00:00:00',17:'2000-06-01 00:00:00',18:'2001-10-05 00:00:00',19:'2002-09-20 00:00:00',20:'2003-04-25 00:00:00',21:'2003-09-20 00:00:00',22:'2005-05-07 00:00:00',23:'2006-10-07 00:00:00',24:'2007-10-13 00:00:00',25:'2008-02-02 00:00:00',26:'2008-03-28 00:00:00',27:'2008-10-10 00:00:00',28:'2009-10-10 00:00:00',29:'2011-10-05 00:00:00',30:'2012-10-03 00:00:00',31:'2013-09-21 00:00:00',32:'2014-09-23 00:00:00',33:"2015-09-22 00:00:00",34:"2016-10-01 00:00:00",35:"2017-09-29 00:00:00'}})df ['Date'] = pd.to_datetime(df ['Date'],format ='%Y-%m-%d%H:%M:%S')无花果,ax = plt.subplots()df.plot('Date','Y',ax = ax,marker ='x',ls ='-')ax.set_xlim(pd.datetime(1990,1,1),pd.datetime(2018,1,1))format_xaxis(图) 

产生的图如下:

我如何用从1993年开始的时间序列重新创建上述图?我仍然希望每两年设置一次次刻度号(即95,97,99,01,...).是否可以使用

Right now I have a working bit of code that formats to my specification when my time series begin at the start of a decade (i.e. 1990, 2000, 2010,etc.), but I don't know how to adapt my code to have the correct formatting when my time series begins at a year that isn't even (i.e. 1993).

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import dates

def format_xaxis(fig):

     years = dates.YearLocator(10,month=1,day=1)
     years1=dates.YearLocator(2,month=1,day=1)
     dfmt = dates.DateFormatter('%Y')
     dfmt1 = dates.DateFormatter('%y')

     [i.xaxis.set_major_locator(years) for i in fig.axes]
     [i.xaxis.set_minor_locator(years1) for i in fig.axes]
     [i.xaxis.set_major_formatter(dfmt) for i in fig.axes]
     [i.xaxis.set_minor_formatter(dfmt1) for i in fig.axes]
     [i.get_xaxis().set_tick_params(which='major', pad=15) for i in fig.axes]

     for t in fig.axes:
         for tick in t.xaxis.get_major_ticks():
             tick.label1.set_horizontalalignment('center')
         for label in t.get_xmajorticklabels() :
             label.set_rotation(0)
             label.set_weight('bold')
         for label in t.xaxis.get_minorticklabels():
             label.set_fontsize('small')
         for label in t.xaxis.get_minorticklabels()[::5]:
             label.set_visible(False)


df = pd.DataFrame.from_dict({'Y': {0: 0.15,  1: 0.18,  2: 0.23,  3: 0.15,  4: 0.15,  5: 0.15,  6: 0.17,  7: 0.175,  8: 0.212,  9: 0.184,  10: 0.18,  11: 0.18,  12: 0.21,  13: 0.139,  14: 0.15,  15: 0.128,  16: 0.126,  17: 0.1,  18: 0.11,  19: 0.183,  20: 0.14,  21: 0.12,  22: 0.155,  23: 0.245,  24: 0.248,  25: 0.262,  26: 0.17,  27: 0.143,  28: 0.13,  29: 0.102,  30: 0.258,  31: 0.293,  32: 0.196,  33: 0.21,  34: 0.14,  35: 0.17}, 
                             'Date': {0: '1990-06-10 00:00:00',  1: '1991-07-26 00:00:00',  2: '1992-10-15 00:00:00',  3: '1993-10-08 00:00:00',  4: '1994-04-07 00:00:00',  5: '1994-11-20 00:00:00',  6: '1995-04-24 00:00:00',  7: '1996-02-13 00:00:00',  8: '1996-04-15 00:00:00',  9: '1996-09-12 00:00:00',  10: '1997-02-13 00:00:00',  11: '1997-04-20 00:00:00',  12: '1997-08-23 00:00:00',  13: '1997-11-06 00:00:00',  14: '1998-04-15 00:00:00',  15: '1999-05-04 00:00:00',  16: '2000-03-17 00:00:00',  17: '2000-06-01 00:00:00',  18: '2001-10-05 00:00:00',  19: '2002-09-20 00:00:00',  20: '2003-04-25 00:00:00',  21: '2003-09-20 00:00:00',  22: '2005-05-07 00:00:00',  23: '2006-10-07 00:00:00',  24: '2007-10-13 00:00:00',  25: '2008-02-02 00:00:00',  26: '2008-03-28 00:00:00',  27: '2008-10-10 00:00:00',  28: '2009-10-10 00:00:00',  29: '2011-10-05 00:00:00',  30: '2012-10-03 00:00:00',  31: '2013-09-21 00:00:00',  32: '2014-09-23 00:00:00',  33: '2015-09-22 00:00:00',  34: '2016-10-01 00:00:00',  35: '2017-09-29 00:00:00'}})

df['Date'] = pd.to_datetime(df['Date'], format='%Y-%m-%d %H:%M:%S')

fig, ax = plt.subplots()

df.plot('Date','Y',ax=ax,marker='x',ls='-')
ax.set_xlim(pd.datetime(1990, 1, 1), pd.datetime(2018, 1, 1))

format_xaxis(fig)

Which produces a plot that looks like:

How would I recreate the above plot with a time series that begins on 1993? I would still like the minor tick labels to be set every two years (i.e. 95,97,99,01,....). Is it possible to use matplotlib.dates.YearLocator for format dates when a time series plot begins on an odd year?

解决方案

You may subclass YearLocator to have your custom OffsetYearLocator.

Version for matplotlib <= 3.0

from matplotlib import dates

class OffsetYearLocator(dates.YearLocator):
    def __init__(self, *args, **kwargs):
        self.offset = kwargs.pop("offset", 0)
        dates.YearLocator.__init__(self,*args, **kwargs)
    def tick_values(self, vmin, vmax):
        ymin = self.base.le(vmin.year)-self.offset
        ymax = self.base.ge(vmax.year)+(self.base._base-self.offset)
        ticks = [vmin.replace(year=ymin, **self.replaced)]
        while True:
            dt = ticks[-1]
            if dt.year >= ymax:
                return dates.date2num(ticks)
            year = dt.year + self.base.get_base()
            ticks.append(dt.replace(year=year, **self.replaced))

Version for matplotlib >= 3.1

from matplotlib import dates

class OffsetYearLocator(dates.YearLocator):
    def __init__(self, *args, **kwargs):
        self.offset = kwargs.pop("offset", 0)
        dates.YearLocator.__init__(self,*args, **kwargs)
    def tick_values(self, vmin, vmax):
        ymin = self.base.le(vmin.year) * self.base.step - self.offset
        ymax = self.base.ge(vmax.year) * self.base.step + (self.base.step-self.offset)
        ticks = [vmin.replace(year=ymin, **self.replaced)]
        while True:
            dt = ticks[-1]
            if dt.year >= ymax:
                return dates.date2num(ticks)
            year = dt.year + self.base.step
            ticks.append(dt.replace(year=year, **self.replaced))

This can handle an additional argument offset, which is substracted from the year. In this case, one would keep the base as 2 (every two years), but use an offset of 1.

years1 = OffsetYearLocator(2, month=1, day=1, offset=1)

Complete example (using the version for matplotlib >= 3.1):

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import dates

class OffsetYearLocator(dates.YearLocator):
    def __init__(self, *args, **kwargs):
        self.offset = kwargs.pop("offset", 0)
        dates.YearLocator.__init__(self,*args, **kwargs)
    def tick_values(self, vmin, vmax):
        ymin = self.base.le(vmin.year) * self.base.step - self.offset
        ymax = self.base.ge(vmax.year) * self.base.step + (self.base.step-self.offset)
        ticks = [vmin.replace(year=ymin, **self.replaced)]
        while True:
            dt = ticks[-1]
            if dt.year >= ymax:
                return dates.date2num(ticks)
            year = dt.year + self.base.step
            ticks.append(dt.replace(year=year, **self.replaced))

def format_xaxis(ax):

    years = dates.YearLocator(10,month=1,day=1)
    years1=OffsetYearLocator(2,month=1,day=1, offset=1)
    dfmt = dates.DateFormatter('%Y')
    dfmt1 = dates.DateFormatter('%y')

    ax.xaxis.set_major_locator(years)
    ax.xaxis.set_minor_locator(years1)
    ax.xaxis.set_major_formatter(dfmt)
    ax.xaxis.set_minor_formatter(dfmt1)
    ax.get_xaxis().set_tick_params(which='major', pad=15)

    plt.setp(ax.get_xmajorticklabels(), rotation=0, weight="bold", ha="center")


df = pd.DataFrame.from_dict({'YData': {0: 0.15,  1: 0.18,  2: 0.23,  3: 0.15,  4: 0.15,  5: 0.15,  6: 0.17,  7: 0.175,  8: 0.212,  9: 0.184,  10: 0.18,  11: 0.18,  12: 0.21,  13: 0.139,  14: 0.15,  15: 0.128,  16: 0.126,  17: 0.1,  18: 0.11,  19: 0.183,  20: 0.14,  21: 0.12,  22: 0.155,  23: 0.245,  24: 0.248,  25: 0.262,  26: 0.17,  27: 0.143,  28: 0.13,  29: 0.102,  30: 0.258,  31: 0.293,  32: 0.196,  33: 0.21,  34: 0.14,  35: 0.17}, 
                             'Date': {0: '1990-06-10 00:00:00',  1: '1991-07-26 00:00:00',  2: '1992-10-15 00:00:00',  3: '1993-10-08 00:00:00',  4: '1994-04-07 00:00:00',  5: '1994-11-20 00:00:00',  6: '1995-04-24 00:00:00',  7: '1996-02-13 00:00:00',  8: '1996-04-15 00:00:00',  9: '1996-09-12 00:00:00',  10: '1997-02-13 00:00:00',  11: '1997-04-20 00:00:00',  12: '1997-08-23 00:00:00',  13: '1997-11-06 00:00:00',  14: '1998-04-15 00:00:00',  15: '1999-05-04 00:00:00',  16: '2000-03-17 00:00:00',  17: '2000-06-01 00:00:00',  18: '2001-10-05 00:00:00',  19: '2002-09-20 00:00:00',  20: '2003-04-25 00:00:00',  21: '2003-09-20 00:00:00',  22: '2005-05-07 00:00:00',  23: '2006-10-07 00:00:00',  24: '2007-10-13 00:00:00',  25: '2008-02-02 00:00:00',  26: '2008-03-28 00:00:00',  27: '2008-10-10 00:00:00',  28: '2009-10-10 00:00:00',  29: '2011-10-05 00:00:00',  30: '2012-10-03 00:00:00',  31: '2013-09-21 00:00:00',  32: '2014-09-23 00:00:00',  33: '2015-09-22 00:00:00',  34: '2016-10-01 00:00:00',  35: '2017-09-29 00:00:00'}})

df['Date'] = pd.to_datetime(df['Date'], format='%Y-%m-%d %H:%M:%S')

fig, ax = plt.subplots()

ax.plot('Date','YData', data=df, marker='x',ls='-')
ax.set_xlim(pd.datetime(1990,1,1), pd.datetime(2018,1,1))

format_xaxis(ax)

plt.show()

这篇关于Matplotlib用奇数间隔对YearLocator进行日期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆