[Scipy-svn] r2732 - in trunk/Lib/sandbox/timeseries: . plotlib
scipy-svn@scip...
scipy-svn@scip...
Tue Feb 20 12:12:21 CST 2007
Author: pierregm
Date: 2007-02-20 12:12:18 -0600 (Tue, 20 Feb 2007)
New Revision: 2732
Modified:
trunk/Lib/sandbox/timeseries/plotlib/mpl_timeseries_new.py
trunk/Lib/sandbox/timeseries/tdates.py
Log:
tdates : fixed name __getdateinfo__
mpl_timeseries_new : fixed TimeSeries_DateFormatter
Modified: trunk/Lib/sandbox/timeseries/plotlib/mpl_timeseries_new.py
===================================================================
--- trunk/Lib/sandbox/timeseries/plotlib/mpl_timeseries_new.py 2007-02-19 15:39:39 UTC (rev 2731)
+++ trunk/Lib/sandbox/timeseries/plotlib/mpl_timeseries_new.py 2007-02-20 18:12:18 UTC (rev 2732)
@@ -1,12 +1,12 @@
"""
Classes to plot TimeSeries w/ matplotlib.
-:author: Pierre GF Gerard-Marchant
-:contact: pierregm_at_uga_edu
+:author: Pierre GF Gerard-Marchant & Matt Knox
+:contact: pierregm_at_uga_dot_edu - mattknow_ca_at_hotmail_dot_com
:date: $Date: 2007-02-02 23:19:06 -0500 (Fri, 02 Feb 2007) $
-:version: $Id: mpl_timeseries.py 2676 2007-02-03 04:19:06Z pierregm $
+:version: $Id: tdates.py 2726 2007-02-19 07:37:26Z pierregm $
"""
-__author__ = "Pierre GF Gerard-Marchant ($Author: pierregm $)"
+__author__ = "Pierre GF Gerard-Marchant & Matt Knox ($Author: pierregm $)"
__version__ = '1.0'
__revision__ = "$Revision: 2676 $"
__date__ = '$Date: 2007-02-02 23:19:06 -0500 (Fri, 02 Feb 2007) $'
@@ -133,7 +133,10 @@
def _get_default_annual_spacing(nyears):
"""Returns a default spacing between consecutive ticks for annual data."""
- if nyears < 20:
+
+ if nyears < 11:
+ (min_spacing, maj_spacing) = (1, 1)
+ elif nyears < 15:
(min_spacing, maj_spacing) = (1, 2)
elif nyears < 50:
(min_spacing, maj_spacing) = (1, 5)
@@ -149,34 +152,6 @@
(min_spacing, maj_spacing) = (20, 100)
return (min_spacing, maj_spacing)
-def _get_default_quarterly_spacing(nquarters):
- """Returns a default spacing between consecutive ticks for quarterly data."""
- if nquarters <= 3*4:
- (min_spacing, maj_spacing) = (1,4)
- elif nquarters <= 11*4:
- (min_spacing, maj_spacing) = (1,4)
- else:
- (min_anndef, maj_anndef) = _get_default_annual_spacing(nquarters//4)
- min_spacing = min_anndef * 4
- maj_spacing = maj_anndef * 4
- return (min_spacing, maj_spacing)
-
-def _get_default_monthly_spacing(nmonths):
- """Returns a default spacing between consecutive ticks for monthly data."""
- if nmonths <= 10:
- (min_spacing, maj_spacing) = (1,3)
- elif nmonths <= 2*12:
- (min_spacing, maj_spacing) = (1,6)
- elif nmonths <= 3*12:
- (min_spacing, maj_spacing) = (1,12)
- elif nmonths <= 11*12:
- (min_spacing, maj_spacing) = (3,12)
- else:
- (min_anndef, maj_anndef) = _get_default_annual_spacing(nmonths//12)
- min_spacing = min_anndef * 12
- maj_spacing = maj_anndef * 12
- return (min_spacing, maj_spacing)
-
#...............................................................................
class TimeSeries_DateLocator(Locator):
"Locates the ticks along an axis controlled by a DateArray."
@@ -202,6 +177,10 @@
"Returns the default ticks spacing."
raise NotImplementedError('Derived must override')
+ def _get_default_locs(self, vmin, vmax):
+ "Returns the default ticks spacing."
+ raise NotImplementedError('Derived must override')
+
def __call__(self):
'Return the locations of the ticks.'
self.verify_intervals()
@@ -209,12 +188,12 @@
if vmax < vmin:
vmin, vmax = vmax, vmin
if self.isdynamic:
- base = self._get_default_spacing(vmax-vmin+1)
+ locs = self._get_default_locs(vmin, vmax)
else:
base = self.base
- d = vmin // base
- vmin = (d+1) * base + self.offset
- locs = range(vmin, vmax+1, base)
+ (d, m) = divmod(vmin, base)
+ vmin = (d+1) * base
+ locs = range(vmin, vmax+1, base)
return locs
def autoscale(self):
@@ -223,21 +202,12 @@
"""
self.verify_intervals()
dmin, dmax = self.dataInterval.get_bounds()
- if self.isdynamic:
- base = self._get_default_spacing(dmax-dmin+1)
- else:
- base = self.base
- (d,m) = divmod(dmin, base)
- if m < base/2:
- vmin = d * base
- else:
- vmin = (d+1) * base
- (d,m) = divmod(dmax, base)
- vmax = (d+1) * base
+ locs = self._get_default_locs(dmin, dmax)
+ (vmin, vmax) = locs[[0, -1]]
if vmin == vmax:
vmin -= 1
vmax += 1
- return nonsingular(vmin, vmax)
+ return nonsingular(vmin, vmax)
#...............................................................................
class TimeSeries_AnnualLocator(TimeSeries_DateLocator):
@@ -248,12 +218,17 @@
TimeSeries_DateLocator.__init__(self,'A', minor_locator, dynamic_mode,
base, quarter, month, day)
- def _get_default_spacing(self, span):
+ def _get_default_locs(self, vmin, vmax):
"Returns the default tick spacing for annual data."
+ span = vmax - vmin + 1
(minor, major) = _get_default_annual_spacing(span)
if self.isminor:
- return minor
- return major
+ base = minor
+ else:
+ base = major
+ offset = base - (vmin % base)
+ return N.arange(vmin+offset, vmax+1, base)
+
#...............................................................................
class TimeSeries_QuarterlyLocator(TimeSeries_DateLocator):
"Locates the ticks along an axis controlled by a quarterly DateArray."
@@ -264,12 +239,24 @@
base, quarter, month, day)
self.offset=1
- def _get_default_spacing(self, span):
- "Returns the default tick spacing for quarterly data."
- (minor, major) = _get_default_quarterly_spacing(span)
+ def _get_default_locs(self, vmin, vmax):
+ "Returns the default ticks spacing."
+ nquarters = vmax - vmin + 1
+ if nquarters <= 3*4:
+ (min_spacing, maj_spacing) = (1, 4)
+ elif nquarters <= 11*4:
+ (min_spacing, maj_spacing) = (1, 4)
+ else:
+ (min_anndef, maj_anndef) = _get_default_annual_spacing(nquarters//4)
+ min_spacing = min_anndef * 4
+ maj_spacing = maj_anndef * 4
if self.isminor:
- return minor
- return major
+ base = min_spacing
+ else:
+ base = maj_spacing
+ offset = base - (vmin+4-1) % base
+ return N.arange(vmin+offset, vmax+1, base)
+
#...............................................................................
class TimeSeries_MonthlyLocator(TimeSeries_DateLocator):
"Locates the ticks along an axis controlled by a monthly DateArray."
@@ -280,12 +267,28 @@
base, quarter, month, day)
self.offset = 1
- def _get_default_spacing(self, span):
- "Returns the default tick spacing for monthly data."
- (minor, major) = _get_default_monthly_spacing(span)
+ def _get_default_locs(self, vmin, vmax):
+ "Returns the default ticks spacing."
+ nmonths = vmax - vmin + 1
+ if nmonths <= 10:
+ (min_spacing, maj_spacing) = (1, 3)
+ elif nmonths <= 2*12:
+ (min_spacing, maj_spacing) = (1, 6)
+ elif nmonths <= 3*12:
+ (min_spacing, maj_spacing) = (1, 12)
+ elif nmonths <= 11*12:
+ (min_spacing, maj_spacing) = (3, 12)
+ else:
+ (min_anndef, maj_anndef) = _get_default_annual_spacing(nmonths//12)
+ min_spacing = min_anndef * 12
+ maj_spacing = maj_anndef * 12
if self.isminor:
- return minor
- return major
+ base = min_spacing
+ offset = ((4 - (vmin-1) % 4) % base)
+ else:
+ base = maj_spacing
+ offset = ((4 - (vmin-1) % 4) % 4)
+ return N.arange(vmin+offset, vmax+1, base)
#...............................................................................
class TimeSeries_DailyLocator(TimeSeries_DateLocator):
@@ -310,18 +313,21 @@
#
if span <= daysperyear//12:
minor = default
- major = default[(dates.day_of_week == 1)]
+ major = default[(dates.day == 1)]
elif span <= daysperyear//3:
- minor = default[(dates.day_of_week == 1)]
+ minor = default
major = default[(dates.day == 1)]
elif span <= 1.5 * daysperyear:
+ monthstart = (dates.day == 1)
minor = default[(dates.day_of_week == 1)]
- major = default[(dates.day == 1)]
+ major = default[monthstart]
elif span <= 3 * daysperyear:
+ quarterstart = (dates.day == 1) & (dates.month % 3 == 1)
minor = default[(dates.day == 1)]
- major = default[(dates.day_of_year == 1)]
+ major = default[quarterstart]
elif span <= 11 * daysperyear:
- minor = default[(dates.quarter != (dates-1).quarter)]
+ quarterstart = (dates.day == 1) & (dates.month % 3 == 1)
+ minor = default[quarterstart]
major = default[(dates.day_of_year == 1)]
else:
(min_anndef, maj_anndef) = _get_default_annual_spacing(span/daysperyear)
@@ -475,16 +481,170 @@
class TimeSeries_DateFormatter(Formatter):
"""Formats the ticks along a DateArray axis."""
- def __init__(self, freq, fmt=None):
- if fmt is None:
- fmt = Date.default_fmtstr[freq]
- self.fmt = fmt
+ def __init__(self, freq, minor_locator=False, dynamic_mode=True,):
+ self.format = None
self.freqstr = freq
+ self.locs = []
+ self.formatdict = {}
+ self.isminor = minor_locator
+ self.isdynamic = dynamic_mode
+ self.offset = 0
+
+
+ def _initialize_dates(self, locs):
+ "Returns a DateArray for the current frequency."
+ freq = self.freqstr
+ dates = date_array(dlist=self.locs, freq=freq)
+ return dates
+ def set_locs(self, locs):
+ 'Sets the locations of the ticks'
+ self.locs = locs
+ if len(self.locs) > 0:
+ self.verify_intervals()
+ d = abs(self.viewInterval.span())
+ self._set_format(d)
+ #
def __call__(self, x, pos=0):
- return Date(self.freqstr, value=int(x)).strfmt(self.fmt)
+ if self.isminor:
+ fmt = self.formatdict.pop(x, '')
+ if fmt is not '':
+ retval = Date(self.freqstr, value=int(x)).strfmt(fmt)
+ else:
+ retval = ''
+ else:
+ retval = ''
+ return retval
+
+
+#...............................................................................
+class TimeSeries_AnnualFormatter(TimeSeries_DateFormatter):
+ #
+ def __init__(self, minor_locator=False, dynamic_mode=True,):
+ TimeSeries_DateFormatter.__init__(self, 'A',
+ minor_locator=minor_locator,
+ dynamic_mode=dynamic_mode,)
+ def _set_format(self, span):
+ dates = self._initialize_dates(self.locs)
+ format = N.empty(len(self.locs), dtype="|S2")
+ format.flat = ''
+ if span <= 11:
+ format[:] = "%Y"
+ elif span < 15:
+ format[(self.locs % 2 == 0)] = "%Y"
+ elif span < 50:
+ format[(self.locs % 5 == 0)] = "%Y"
+ elif span < 100:
+ format[(self.locs % 10 == 0)] = "%Y"
+ elif span < 200:
+ format[(self.locs % 20 == 0)] = "%Y"
+ elif span < 400:
+ format[(self.locs % 25 == 0)] = "%Y"
+ elif span < 1000:
+ format[(self.locs % 50 == 0)] = "%Y"
+ else:
+ format[(self.locs % 100 == 0)] = "%Y"
+ self.formatdict = dict([(x,f) for (x,f) in zip(self.locs, format)])
+
+#...............................................................................
+class TimeSeries_QuarterlyFormatter(TimeSeries_DateFormatter):
+ #
+ def __init__(self, minor_locator=False, dynamic_mode=True,):
+ TimeSeries_DateFormatter.__init__(self, 'Q',
+ minor_locator=minor_locator,
+ dynamic_mode=dynamic_mode,)
+ def _set_format(self, span):
+ dates = self._initialize_dates(self.locs)
+ format = N.empty(len(self.locs), dtype="|S7")
+ format.flat = ''
+ (years,quarters) = divmod(self.locs-1, 4)
+ if span <= 3*4:
+ yearchange = (self.locs % 4 == 1)
+ format[:] = "Q%q"
+ format[(quarters == 0)] = "Q%q\n%Y"
+ format[0] = "Q%q\n%Y"
+ elif span <= 11*4:
+ format[(years % 2 == 1) & (quarters == 0)] = "%Y"
+ else:
+ format[(years % 5 == 4)] = "%Y"
+ self.formatdict = dict([(x,f) for (x,f) in zip(self.locs, format)])
+
+
+#...............................................................................
+class TimeSeries_MonthlyFormatter(TimeSeries_DateFormatter):
+ #
+ def __init__(self, minor_locator=False, dynamic_mode=True,):
+ TimeSeries_DateFormatter.__init__(self, 'M',
+ minor_locator=minor_locator,
+ dynamic_mode=dynamic_mode,)
+ #
+ def _set_format(self, span):
+ dates = self._initialize_dates(self.locs)
+ yearchange = (self.locs % 12 == 1)
+ format = N.empty(len(self.locs), dtype="|S6")
+ format.flat = ''
+ if span <= 1.5 * 12:
+ format[:] = "%b"
+ format[yearchange] = "%b\n%Y"
+ format[0] = "%b\n%Y"
+ elif span <= 3*12:
+ format[(dates.month % 2 == 1)] = "%b"
+ format[yearchange] = "%b\n%Y"
+ else:
+ format[yearchange] = "%Y"
+ self.formatdict = dict([(x,f) for (x,f) in zip(self.locs, format)])
+
+
+#...............................................................................
+class TimeSeries_DailyFormatter(TimeSeries_DateFormatter):
+ #
+ def __init__(self, freq, minor_locator=False, dynamic_mode=True,):
+ TimeSeries_DateFormatter.__init__(self, freq,
+ minor_locator=minor_locator,
+ dynamic_mode=dynamic_mode,)
+ if self.freqstr == 'B':
+ self.daysinyear = 261
+ else:
+ self.daysinyear = 365
+ #
+ def _set_format(self, span):
+ dayperyear = self.daysinyear
+ dates = self._initialize_dates(self.locs)
+ yearchange = (dates.day_of_year == 1)
+ format = N.empty(len(self.locs), dtype="|S8")
+ format.flat = ''
+ if span <= dayperyear // 12:
+ format[:] = '%d'
+ format[(dates.day == 1)] = '\n%b'
+ format[yearchange] = '\n%b\n%Y'
+ format[0] = '\n%b\n%Y'
+ elif span <= dayperyear // 4:
+ format[(dates.day_of_week == 1)] = '%d'
+ format[(dates.day == 1)] = '\n%b'
+ format[yearchange] = '\n%b\n%Y'
+ elif span <= 1.5 * dayperyear:
+ monthweekchange = (dates.day_of_week == 0) | (dates.day == 1)
+ format[monthweekchange] = '\n%b'
+ format[yearchange] = '\n%b\n%Y'
+ elif span <= 3 * dayperyear:
+ quarterchange = (dates.months % 3 == 1) & (dates.day == 1)
+ format[quarterchange] = '%b'
+ format[yearchange] = '\n%Y'
+ else:
+ format[:] = '%Y'
+ self.formatdict = dict([(x,f) for (x,f) in zip(self.locs, format)])
+
+
+# Monthly:
+# if span <= 1.5 * 12: '%b' on minor ticks, '%Y' on major ticks
+#elif span <= 3 * 12 : '%b' every even month on minor ticks, '%Y' on major
+#elif span <= 11 * 12 : '%Y' on major
+# Daily:
+
+
+
#####--------------------------------------------------------------------------
#---- --- TimeSeries plots ---
#####--------------------------------------------------------------------------
@@ -652,46 +812,50 @@
# Get the locator class .................
if self.freqstr in 'BDU':
locator = TimeSeries_DailyLocator
+ formatter = TimeSeries_DailyFormatter
self.xaxis.set_major_locator(locator(self.freqstr,
minor_locator=False,
dynamic_mode=True))
self.xaxis.set_minor_locator(locator(self.freqstr,
minor_locator=True,
dynamic_mode=True))
+ self.xaxis.set_major_formatter(formatter(self.freqstr,
+ minor_locator=False,
+ dynamic_mode=True))
+ self.xaxis.set_minor_formatter(formatter(self.freqstr,
+ minor_locator=True,
+ dynamic_mode=True))
else:
if self.freqstr == 'A':
locator = TimeSeries_AnnualLocator
+ formatter = TimeSeries_AnnualFormatter
elif self.freqstr == 'Q':
locator = TimeSeries_QuarterlyLocator
+ formatter = TimeSeries_QuarterlyFormatter
elif self.freqstr == 'M':
locator = TimeSeries_MonthlyLocator
+ formatter = TimeSeries_MonthlyFormatter
self.xaxis.set_major_locator(locator(minor_locator=False,
dynamic_mode=True))
self.xaxis.set_minor_locator(locator(minor_locator=True,
dynamic_mode=True))
+ self.xaxis.set_major_formatter(formatter(minor_locator=False,
+ dynamic_mode=True))
+ self.xaxis.set_minor_formatter(formatter(minor_locator=True,
+ dynamic_mode=True))
#........................................
- self.xaxis.set_major_formatter(TimeSeries_DateFormatter(self.freqstr))
- if rcParams['backend'] == 'PS':
- rotate = False
- warnings.warn("dateplot: PS backend detected, rotate disabled")
- if self.is_last_row():
- if rotate:
- setp(self.get_xticklabels(),rotation=45)
+# if rcParams['backend'] == 'PS':
+# rotate = False
+# warnings.warn("dateplot: PS backend detected, rotate disabled")
+# if self.is_last_row():
+# if rotate:
+# setp(self.get_xticklabels(),rotation=45)
# self.xaxis.set_major_formatter(FuncFormatter(self.dateticks_formatter))
# self.xaxis.set_minor_formatter(FuncFormatter(self.dateticks_formatter))
# else:
# self.set_xticklabels([])
# self.set_xlabel('')
-# #............................................
-# def plot_shifts(self,shifts,**kwargs):
-# """Plots regime shifts.
-#:param shifts: Shifts/trends to plot.
-#:type shifts: `RegimeShift`
-# """
-# self.tsplot(self.xdata,shifts.regimes,**kwargs)
-# for x in shifts.xshifts[0]:
-# self.axvline(self.xdata[x],ls=':',c='#999999',lw=0.5)
- #............................................
+
TSPlot = TimeSeriesPlot
@@ -760,16 +924,16 @@
################################################################################
if __name__ == '__main__':
- da = date_array(start_date=Date(freq='D', year=2003, quarter=3, month=1, day=17),
+ da = date_array(start_date=Date(freq='A', year=2003, quarter=3, month=1, day=17),
length=51)
ser = timeseries.time_series(MA.arange(len(da)), dates=da)
ser[4] = MA.masked
- ser_2 = timeseries.time_series(MA.arange(len(da)), dates=da.asfreq('M'))
+# ser_2 = timeseries.time_series(MA.arange(len(da)), dates=da.asfreq('Q'))
pylab.figure()
pylab.gcf().add_tsplot(111)
pylab.gca().tsplot(ser, 'ko-')
pylab.gca().format_dateaxis()
- pylab.gca().tsplot(ser_2, 'rs')
+# pylab.gca().tsplot(ser_2, 'rs')
pylab.show()
\ No newline at end of file
Modified: trunk/Lib/sandbox/timeseries/tdates.py
===================================================================
--- trunk/Lib/sandbox/timeseries/tdates.py 2007-02-19 15:39:39 UTC (rev 2731)
+++ trunk/Lib/sandbox/timeseries/tdates.py 2007-02-20 18:12:18 UTC (rev 2732)
@@ -554,43 +554,43 @@
@property
def day(self):
"Returns the day of month."
- return self.__getDateInfo__('D')
+ return self.__getdateinfo__('D')
@property
def day_of_week(self):
"Returns the day of week."
- return self.__getDateInfo__('W')
+ return self.__getdateinfo__('W')
@property
def day_of_year(self):
"Returns the day of year."
- return self.__getDateInfo__('R')
+ return self.__getdateinfo__('R')
@property
def month(self):
"Returns the month."
- return self.__getDateInfo__('M')
+ return self.__getdateinfo__('M')
@property
def quarter(self):
"Returns the quarter."
- return self.__getDateInfo__('Q')
+ return self.__getdateinfo__('Q')
@property
def year(self):
"Returns the year."
- return self.__getDateInfo__('Y')
+ return self.__getdateinfo__('Y')
@property
def second(self):
"Returns the seconds."
- return self.__getDateInfo__('S')
+ return self.__getdateinfo__('S')
@property
def minute(self):
"Returns the minutes."
- return self.__getDateInfo__('T')
+ return self.__getdateinfo__('T')
@property
def hour(self):
"Returns the hour."
- return self.__getDateInfo__('H')
+ return self.__getdateinfo__('H')
@property
def week(self):
"Returns the week."
- return self.__getDateInfo__('I')
+ return self.__getdateinfo__('I')
days = day
weekdays = day_of_week
@@ -603,9 +603,9 @@
hours = hour
weeks = week
- def __getDateInfo(self, info):
+ def __getdateinfo__(self, info):
return numeric.asarray(cseries.getDateInfo(numeric.asarray(self), self.freq, info), dtype=int_)
-
+ __getDateInfo = __getdateinfo__
#.... Conversion methods ....................
#
def tovalue(self):
More information about the Scipy-svn
mailing list