typo
[PyX/mjg.git] / pyx / timeaxis.py
blob269e8a309c5cf0ca4dc61b586436c474e4bf12ad
1 import datetime
2 import graph, helper
4 """some experimental code for creating a time axis
5 - it needs python 2.3 to be used (it is based on the new datetime data type)
6 - a timeaxis is always based on the datetime data type (there is no distinction between times and dates)
7 """
9 class _timemap:
10 "time axis mapping based "
12 __implements__ = graph._Imap
14 def setbasepoints(self, basepoints):
15 (self.x1, self.y1), (self.x2, self.y2) = basepoints
16 self.dx = self.x2-self.x1
17 self.dy = self.y2-self.y1
18 if self.dx < datetime.timedelta(0):
19 raise RuntimeError("reverse time axis is not expected to work") # and should not happen
21 def convert(self, x):
22 # XXX float division of timedelta instances
23 def mstimedelta(td):
24 "return the timedelta in microseconds"
25 return td.microseconds + 1000000*(td.seconds + 3600*24*td.days)
26 return self.y1 + self.dy * mstimedelta(x - self.x1) / float(mstimedelta(self.dx))
27 # we could store float(mstimedelta(self.dx)) instead of self.dx, but
28 # I prefer a different solution (not based on huge integers) for the
29 # future
31 def invert(self, y):
32 f = (y - self.y1) / float(self.dy)
33 return self.x1 + datetime.timedelta(days=f*self.dx.days, seconds=f*self.dx.seconds, microseconds=f*self.dx.seconds)
36 class timetick(datetime.datetime):
38 def __init__(self, year, month, day, ticklevel=0, labellevel=0, label=None, labelattrs=[], **kwargs):
39 datetime.datetime.__init__(self, year, month, day, **kwargs)
40 self.ticklevel = ticklevel
41 self.labellevel = labellevel
42 self.label = label
43 self.labelattrs = helper.ensurelist(labelattrs)[:]
45 def merge(self, other):
46 if self.ticklevel is None or (other.ticklevel is not None and other.ticklevel < self.ticklevel):
47 self.ticklevel = other.ticklevel
48 if self.labellevel is None or (other.labellevel is not None and other.labellevel < self.labellevel):
49 self.labellevel = other.labellevel
52 class timetexter:
54 def __init__(self, formats="%c"):
55 self.formats = formats
57 def labels(self, ticks):
58 for tick in ticks:
59 if tick.labellevel is not None and tick.label is None:
60 tick.label = tick.strftime(self.formats)
63 class timeaxis(graph._axis, _timemap):
65 def __init__(self, part=[], rater=graph.axisrater(), **args):
66 graph._axis.__init__(self, divisor=None, **args)
67 if self.fixmin and self.fixmax:
68 self.relsize = self.max - self.min
69 self.relsize = 0.000001*self.relsize.microseconds + self.relsize.seconds + 3600*24*self.relsize.days
70 self.part = part
71 self.rater = rater
74 class symbol(graph.symbol):
75 "the preliminary symbol class uses its "
77 def minmidmax(self, point, i, mini, maxi, di, dmini, dmaxi):
78 min = max = mid = None
79 mid = point[i]
80 if di is not None: min = point[i] - point[di]
81 elif dmini is not None: min = point[i] - point[dmini]
82 elif mini is not None: min = point[mini]
83 if di is not None: max = point[i] + point[di]
84 elif dmaxi is not None: max = point[i] + point[dmaxi]
85 elif maxi is not None: max = point[maxi]
86 if mid is not None:
87 if min is not None and min > mid: raise ValueError("minimum error in errorbar")
88 if max is not None and max < mid: raise ValueError("maximum error in errorbar")
89 else:
90 if min is not None and max is not None and min > max: raise ValueError("minimum/maximum error in errorbar")
91 return min, mid, max