11#!/usr/bin/env python
22"""
33
4- Matplotlib provides sophisticated date plotting capabilites , standing
4+ Matplotlib provides sophisticated date plotting capabilities , standing
55on the shoulders of python datetime, the add-on modules pytz and
66dateutils. datetime objects are converted to floating point numbers
77which represent the number of days since 0001-01-01 UTC. The helper
1717timezone aware, and the default timezone is given by the timezone
1818parameter in your matplotlibrc file. If you leave out a tz timezone
1919instance, the default from your rc file will be assumed. If you want
20- to use a custom time zone, pass a matplotlib. pytz.timezone instance
20+ to use a custom time zone, pass a pytz.timezone instance
2121with the tz keyword argument to num2date, plot_date, and any custom
2222date tickers or locators you create. See http://pytz.sourceforge.net
2323for information on pytz and timezone handling.
2424
25- dateutils https://moin.conectiva.com.br/DateUtil the code to handle
25+ The dateutil module (http://labix.org/python-dateutil)
26+ provides additional code to handle
2627date ticking, making it easy to place ticks on any kinds of dates -
2728see examples below.
2829
7879import sys , re , time , math , datetime
7980import locale
8081
82+ import pytz
8183import matplotlib
82-
84+ import numpy as npy
8385
8486import matplotlib .units as units
87+ import matplotlib .cbook as cbook
88+ import matplotlib .ticker as ticker
8589
86- from cbook import iterable , is_string_like , is_numlike
8790from pytz import timezone
88- from numerix import arange , asarray
89- from ticker import Formatter , Locator , Base
9091from dateutil .rrule import rrule , MO , TU , WE , TH , FR , SA , SU , YEARLY , \
9192 MONTHLY , WEEKLY , DAILY , HOURLY , MINUTELY , SECONDLY
9293from dateutil .relativedelta import relativedelta
9394import dateutil .parser
9495
95- from matplotlib import cbook
9696
97- UTC = timezone ('UTC' )
97+ __all__ = ( 'date2num' , 'num2date' , 'drange' , 'epoch2num' ,
98+ 'num2epoch' , 'mx2num' , 'DateFormatter' ,
99+ 'IndexDateFormatter' , 'DateLocator' , 'RRuleLocator' ,
100+ 'YearLocator' , 'MonthLocator' , 'WeekdayLocator' ,
101+ 'DayLocator' , 'HourLocator' , 'MinuteLocator' ,
102+ 'SecondLocator' , 'rrule' , 'MO' , 'TU' , 'WE' , 'TH' , 'FR' ,
103+ 'SA' , 'SU' , 'YEARLY' , 'MONTHLY' , 'WEEKLY' , 'DAILY' ,
104+ 'HOURLY' , 'MINUTELY' , 'SECONDLY' , 'relativedelta' ,
105+ 'seconds' , 'minutes' , 'hours' , 'weeks' )
106+
107+
108+
109+ UTC = pytz .timezone ('UTC' )
98110
99111def _get_rc_timezone ():
100112 s = matplotlib .rcParams ['timezone' ]
101- return timezone (s )
113+ return pytz . timezone (s )
102114
103115
104116HOURS_PER_DAY = 24.
@@ -113,17 +125,8 @@ def _get_rc_timezone():
113125 MO , TU , WE , TH , FR , SA , SU )
114126WEEKDAYS = (MONDAY , TUESDAY , WEDNESDAY , THURSDAY , FRIDAY , SATURDAY , SUNDAY )
115127
116- __all__ = ['date2num' , 'num2date' , 'drange' , 'HOURS_PER_DAY' ,
117- 'MINUTES_PER_DAY' , 'SECONDS_PER_DAY' , 'MUSECONDS_PER_DAY' ,
118- 'SEC_PER_MIN' , 'SEC_PER_HOUR' , 'SEC_PER_DAY' ,
119- 'SEC_PER_WEEK' , 'MONDAY' , 'TUESDAY' , 'WEDNESDAY' ,
120- 'THURSDAY' , 'FRIDAY' , 'SATURDAY' , 'SUNDAY' , 'MO' , 'TU' ,
121- 'WE' , 'TH' , 'FR' , 'SA' , 'SU' , 'WEEKDAYS' , 'YEARLY' ,
122- 'MONTHLY' , 'WEEKLY' , 'DAILY' , 'HOURLY' , 'MINUTELY' ,
123- 'SECONDLY' , 'DateFormatter' , 'rrulewrapper' ,
124- 'RRuleLocator' , 'YearLocator' , 'MonthLocator' ,
125- 'WeekdayLocator' , 'DayLocator' , 'HourLocator' ,
126- 'MinuteLocator' , 'SecondLocator' , 'timezone' ]
128+
129+
127130
128131def _to_ordinalf (dt ):
129132 """
@@ -188,7 +191,7 @@ def datestr2num(d):
188191 Convert a date string to a datenum using dateutil.parser.parse
189192 d can be a single string or a sequence of strings
190193 """
191- if is_string_like (d ):
194+ if cbook . is_string_like (d ):
192195 dt = dateutil .parser .parse (d )
193196 return date2num (dt )
194197 else :
@@ -203,18 +206,18 @@ def date2num(d):
203206 which gives number of days (fraction part represents hours,
204207 minutes, seconds) since 0001-01-01 00:00:00 UTC
205208 """
206- if not iterable (d ): return _to_ordinalf (d )
207- else : return asarray ([_to_ordinalf (val ) for val in d ])
209+ if not cbook . iterable (d ): return _to_ordinalf (d )
210+ else : return npy . asarray ([_to_ordinalf (val ) for val in d ])
208211
209212
210213def julian2num (j ):
211214 'convert a Julian date (or sequence) to a matplotlib date (or sequence)'
212- if iterable (j ): j = asarray (j )
215+ if cbook . iterable (j ): j = npy . asarray (j )
213216 return j + 1721425.5
214217
215218def num2julian (n ):
216219 'convert a matplotlib date (or seguence) to a Julian date (or sequence)'
217- if iterable (n ): n = asarray (n )
220+ if cbook . iterable (n ): n = npy . asarray (n )
218221 return n - 1721425.5
219222
220223def num2date (x , tz = None ):
@@ -228,7 +231,7 @@ def num2date(x, tz=None):
228231 if x is a sequence, a sequence of datetimes will be returned
229232 """
230233 if tz is None : tz = _get_rc_timezone ()
231- if not iterable (x ): return _from_ordinalf (x , tz )
234+ if not cbook . iterable (x ): return _from_ordinalf (x , tz )
232235 else : return [_from_ordinalf (val , tz ) for val in x ]
233236
234237def drange (dstart , dend , delta ):
@@ -240,15 +243,15 @@ def drange(dstart, dend, delta):
240243 delta .microseconds / MUSECONDS_PER_DAY )
241244 f1 = _to_ordinalf (dstart )
242245 f2 = _to_ordinalf (dend )
243- return arange (f1 , f2 , step )
246+ return npy . arange (f1 , f2 , step )
244247
245248
246249
247250### date tickers and formatters ###
248251
249252
250253
251- class DateFormatter (Formatter ):
254+ class DateFormatter (ticker . Formatter ):
252255 """
253256 Tick location is seconds since the epoch. Use a strftime format
254257 string
@@ -329,7 +332,7 @@ def strftime(self, dt, fmt):
329332
330333
331334
332- class IndexDateFormatter (Formatter ):
335+ class IndexDateFormatter (ticker . Formatter ):
333336 """
334337 Use with IndexLocator to cycle format strings by index.
335338 """
@@ -354,7 +357,7 @@ def __call__(self, x, pos=0):
354357 return cbook .unicode_safe (dt .strftime (self .fmt ))
355358
356359
357- class AutoDateFormatter (Formatter ):
360+ class AutoDateFormatter (ticker . Formatter ):
358361 """
359362 This class attempt to figure out the best format to use. This is
360363 most useful when used with the AutoDateLocator.
@@ -413,7 +416,7 @@ def __getattr__(self, name):
413416 return self .__dict__ [name ]
414417 return getattr (self ._rrule , name )
415418
416- class DateLocator (Locator ):
419+ class DateLocator (ticker . Locator ):
417420 hms0d = {'byhour' :0 , 'byminute' :0 ,'bysecond' :0 }
418421 def __init__ (self , tz = None ):
419422 """
@@ -689,7 +692,7 @@ def __init__(self, base=1, month=1, day=1, tz=None):
689692 (default jan 1)
690693 """
691694 DateLocator .__init__ (self , tz )
692- self .base = Base (base )
695+ self .base = ticker . Base (base )
693696 self .replaced = { 'month' : month ,
694697 'day' : day ,
695698 'hour' : 0 ,
@@ -906,76 +909,28 @@ def epoch2num(e):
906909 days since 0001
907910 """
908911 spd = 24. * 3600.
909- return 719163 + asarray (e )/ spd
912+ return 719163 + npy . asarray (e )/ spd
910913
911914def num2epoch (d ):
912915 """
913916 convert days since 0001 to epoch. d can be a number or sequence
914917 """
915918 spd = 24. * 3600.
916- return (asarray (d )- 719163 )* spd
919+ return (npy . asarray (d )- 719163 )* spd
917920
918921def mx2num (mxdates ):
919922 """
920923 Convert mx datetime instance (or sequence of mx instances) to the
921924 new date format,
922925 """
923926 scalar = False
924- if not iterable (mxdates ):
927+ if not cbook . iterable (mxdates ):
925928 scalar = True
926929 mxdates = [mxdates ]
927930 ret = epoch2num ([m .ticks () for m in mxdates ])
928931 if scalar : return ret [0 ]
929932 else : return ret
930933
931- if __name__ == '__main__' :
932-
933- #tz = None
934- tz = timezone ('US/Pacific' )
935- #tz = UTC
936-
937- dt = datetime .datetime (1011 , 10 , 9 , 13 , 44 , 22 , 101010 , tzinfo = tz )
938- x = date2num (dt )
939- _close_to_dt (dt , num2date (x , tz ))
940-
941- #tz = _get_rc_timezone()
942-
943-
944- d1 = datetime .datetime ( 2000 , 3 , 1 , tzinfo = tz )
945- d2 = datetime .datetime ( 2000 , 3 , 5 , tzinfo = tz )
946-
947- #d1 = datetime.datetime( 2002, 1, 5, tzinfo=tz)
948- #d2 = datetime.datetime( 2003, 12, 1, tzinfo=tz)
949- delta = datetime .timedelta (hours = 6 )
950- dates = drange (d1 , d2 , delta )
951-
952- #print 'orig', d1
953- #print 'd2n and back', num2date(date2num(d1), tz)
954- from _transforms import Value , Interval
955- v1 = Value (date2num (d1 ))
956- v2 = Value (date2num (d2 ))
957- dlim = Interval (v1 ,v2 )
958- vlim = Interval (v1 ,v2 )
959-
960- #locator = HourLocator(byhour=(3,15), tz=tz)
961- #locator = MinuteLocator(byminute=(15,30,45), tz=tz)
962- #locator = YearLocator(base=5, month=7, day=4, tz=tz)
963- #locator = MonthLocator(bymonthday=15)
964- locator = DayLocator (tz = tz )
965- locator .set_data_interval (dlim )
966- locator .set_view_interval (vlim )
967- dmin , dmax = locator .autoscale ()
968- vlim .set_bounds (dmin , dmax )
969- ticks = locator ()
970-
971-
972- fmt = '%Y-%m-%d %H:%M:%S %Z'
973- formatter = DateFormatter (fmt , tz )
974-
975- #for t in ticks: print formatter(t)
976-
977- for t in dates : print formatter (t )
978-
979934
980935def date_ticker_factory (span , tz = None , numticks = 5 ):
981936 """
@@ -1057,7 +1012,7 @@ def convert(value, unit):
10571012 if units .ConversionInterface .is_numlike (value ): return value
10581013 return date2num (value )
10591014 convert = staticmethod (convert )
1060-
1015+
10611016 def default_units (x ):
10621017 'return the default unit for x or None'
10631018 return 'date'
@@ -1069,13 +1024,53 @@ def default_units(x):
10691024
10701025
10711026
1072- __all__ = ( 'date2num' , 'num2date' , 'drange' , 'epoch2num' ,
1073- 'num2epoch' , 'mx2num' , 'DateFormatter' ,
1074- 'IndexDateFormatter' , 'DateLocator' , 'RRuleLocator' ,
1075- 'YearLocator' , 'MonthLocator' , 'WeekdayLocator' ,
1076- 'DayLocator' , 'HourLocator' , 'MinuteLocator' ,
1077- 'SecondLocator' , 'rrule' , 'MO' , 'TU' , 'WE' , 'TH' , 'FR' ,
1078- 'SA' , 'SU' , 'YEARLY' , 'MONTHLY' , 'WEEKLY' , 'DAILY' ,
1079- 'HOURLY' , 'MINUTELY' , 'SECONDLY' , 'relativedelta' ,
1080- 'seconds' , 'minutes' , 'hours' , 'weeks' )
1027+ if __name__ == '__main__' :
1028+
1029+ #tz = None
1030+ tz = pytz .timezone ('US/Pacific' )
1031+ #tz = UTC
1032+
1033+ dt = datetime .datetime (1011 , 10 , 9 , 13 , 44 , 22 , 101010 , tzinfo = tz )
1034+ x = date2num (dt )
1035+ _close_to_dt (dt , num2date (x , tz ))
1036+
1037+ #tz = _get_rc_timezone()
1038+
1039+
1040+ d1 = datetime .datetime ( 2000 , 3 , 1 , tzinfo = tz )
1041+ d2 = datetime .datetime ( 2000 , 3 , 5 , tzinfo = tz )
1042+
1043+ #d1 = datetime.datetime( 2002, 1, 5, tzinfo=tz)
1044+ #d2 = datetime.datetime( 2003, 12, 1, tzinfo=tz)
1045+ delta = datetime .timedelta (hours = 6 )
1046+ dates = drange (d1 , d2 , delta )
1047+
1048+ #print 'orig', d1
1049+ #print 'd2n and back', num2date(date2num(d1), tz)
1050+ from _transforms import Value , Interval
1051+ v1 = Value (date2num (d1 ))
1052+ v2 = Value (date2num (d2 ))
1053+ dlim = Interval (v1 ,v2 )
1054+ vlim = Interval (v1 ,v2 )
1055+
1056+ #locator = HourLocator(byhour=(3,15), tz=tz)
1057+ #locator = MinuteLocator(byminute=(15,30,45), tz=tz)
1058+ #locator = YearLocator(base=5, month=7, day=4, tz=tz)
1059+ #locator = MonthLocator(bymonthday=15)
1060+ locator = DayLocator (tz = tz )
1061+ locator .set_data_interval (dlim )
1062+ locator .set_view_interval (vlim )
1063+ dmin , dmax = locator .autoscale ()
1064+ vlim .set_bounds (dmin , dmax )
1065+ ticks = locator ()
1066+
1067+
1068+ fmt = '%Y-%m-%d %H:%M:%S %Z'
1069+ formatter = DateFormatter (fmt , tz )
1070+
1071+ #for t in ticks: print formatter(t)
1072+
1073+ for t in dates : print formatter (t )
1074+
1075+
10811076
0 commit comments