11import math
2+
23import numpy as np
34
45import matplotlib .units as units
56import matplotlib .ticker as ticker
67from matplotlib .axes import Axes
78from matplotlib .cbook import iterable
89
10+
911class ProxyDelegate (object ):
1012 def __init__ (self , fn_name , proxy_type ):
1113 self .proxy_type = proxy_type
1214 self .fn_name = fn_name
15+
1316 def __get__ (self , obj , objtype = None ):
1417 return self .proxy_type (self .fn_name , obj )
1518
19+
1620class TaggedValueMeta (type ):
1721 def __init__ (cls , name , bases , dict ):
1822 for fn_name in cls ._proxies .keys ():
1923 try :
2024 dummy = getattr (cls , fn_name )
2125 except AttributeError :
22- setattr (cls , fn_name , ProxyDelegate (fn_name , cls ._proxies [fn_name ]))
26+ setattr (cls , fn_name ,
27+ ProxyDelegate (fn_name , cls ._proxies [fn_name ]))
28+
2329
2430class PassThroughProxy (object ):
2531 def __init__ (self , fn_name , obj ):
2632 self .fn_name = fn_name
2733 self .target = obj .proxy_target
34+
2835 def __call__ (self , * args ):
29- #print 'passthrough', self.target, self.fn_name
3036 fn = getattr (self .target , self .fn_name )
3137 ret = fn (* args )
3238 return ret
3339
40+
3441class ConvertArgsProxy (PassThroughProxy ):
3542 def __init__ (self , fn_name , obj ):
3643 PassThroughProxy .__init__ (self , fn_name , obj )
3744 self .unit = obj .unit
45+
3846 def __call__ (self , * args ):
3947 converted_args = []
4048 for a in args :
@@ -45,16 +53,19 @@ def __call__(self, *args):
4553 converted_args = tuple ([c .get_value () for c in converted_args ])
4654 return PassThroughProxy .__call__ (self , * converted_args )
4755
56+
4857class ConvertReturnProxy (PassThroughProxy ):
4958 def __init__ (self , fn_name , obj ):
5059 PassThroughProxy .__init__ (self , fn_name , obj )
5160 self .unit = obj .unit
61+
5262 def __call__ (self , * args ):
5363 ret = PassThroughProxy .__call__ (self , * args )
5464 if (type (ret ) == type (NotImplemented )):
5565 return NotImplemented
5666 return TaggedValue (ret , self .unit )
5767
68+
5869class ConvertAllProxy (PassThroughProxy ):
5970 def __init__ (self , fn_name , obj ):
6071 PassThroughProxy .__init__ (self , fn_name , obj )
@@ -91,17 +102,17 @@ def __call__(self, *args):
91102 return NotImplemented
92103 return TaggedValue (ret , ret_unit )
93104
94- class TaggedValue (object ):
95105
96- __metaclass__ = TaggedValueMeta
97- _proxies = {'__add__' :ConvertAllProxy ,
98- '__sub__' :ConvertAllProxy ,
99- '__mul__' :ConvertAllProxy ,
100- '__rmul__' :ConvertAllProxy ,
101- '__cmp__' :ConvertAllProxy ,
102- '__lt__' :ConvertAllProxy ,
103- '__gt__' :ConvertAllProxy ,
104- '__len__' :PassThroughProxy }
106+ class _TaggedValue (object ):
107+
108+ _proxies = {'__add__' : ConvertAllProxy ,
109+ '__sub__' : ConvertAllProxy ,
110+ '__mul__' : ConvertAllProxy ,
111+ '__rmul__' : ConvertAllProxy ,
112+ '__cmp__' : ConvertAllProxy ,
113+ '__lt__' : ConvertAllProxy ,
114+ '__gt__' : ConvertAllProxy ,
115+ '__len__' : PassThroughProxy }
105116
106117 def __new__ (cls , value , unit ):
107118 # generate a new subclass for value
@@ -120,13 +131,9 @@ def __new__(cls, value, unit):
120131
121132 def __init__ (self , value , unit ):
122133 self .value = value
123- self .unit = unit
134+ self .unit = unit
124135 self .proxy_target = self .value
125136
126- def get_compressed_copy (self , mask ):
127- compressed_value = np .ma .masked_array (self .value , mask = mask ).compressed ()
128- return TaggedValue (compressed_value , self .unit )
129-
130137 def __getattribute__ (self , name ):
131138 if (name .startswith ('__' )):
132139 return object .__getattribute__ (self , name )
@@ -135,7 +142,7 @@ def __getattribute__(self, name):
135142 return getattr (variable , name )
136143 return object .__getattribute__ (self , name )
137144
138- def __array__ (self , t = None , context = None ):
145+ def __array__ (self , t = None , context = None ):
139146 if t is not None :
140147 return np .asarray (self .value ).astype (t )
141148 else :
@@ -158,6 +165,7 @@ class IteratorProxy(object):
158165 def __init__ (self , iter , unit ):
159166 self .iter = iter
160167 self .unit = unit
168+
161169 def __next__ (self ):
162170 value = next (self .iter )
163171 return TaggedValue (value , self .unit )
@@ -169,7 +177,6 @@ def get_compressed_copy(self, mask):
169177 return TaggedValue (new_value , self .unit )
170178
171179 def convert_to (self , unit ):
172- #print 'convert to', unit, self.unit
173180 if (unit == self .unit or not unit ):
174181 return self
175182 new_value = self .unit .convert_value_to (self .value , unit )
@@ -182,14 +189,17 @@ def get_unit(self):
182189 return self .unit
183190
184191
192+ TaggedValue = TaggedValueMeta ('TaggedValue' , (_TaggedValue , ), {})
193+
194+
185195class BasicUnit (object ):
186196 def __init__ (self , name , fullname = None ):
187197 self .name = name
188- if fullname is None : fullname = name
198+ if fullname is None :
199+ fullname = name
189200 self .fullname = fullname
190201 self .conversions = dict ()
191202
192-
193203 def __repr__ (self ):
194204 return 'BasicUnit(%s)' % self .name
195205
@@ -201,11 +211,11 @@ def __call__(self, value):
201211
202212 def __mul__ (self , rhs ):
203213 value = rhs
204- unit = self
214+ unit = self
205215 if hasattr (rhs , 'get_unit' ):
206216 value = rhs .get_value ()
207- unit = rhs .get_unit ()
208- unit = unit_resolver ('__mul__' , (self , unit ))
217+ unit = rhs .get_unit ()
218+ unit = unit_resolver ('__mul__' , (self , unit ))
209219 if (unit == NotImplemented ):
210220 return NotImplemented
211221 return TaggedValue (value , unit )
@@ -235,44 +245,43 @@ def get_conversion_fn(self, unit):
235245 return self .conversions [unit ]
236246
237247 def convert_value_to (self , value , unit ):
238- #print 'convert value to: value ="%s", unit="%s"'%(value, type(unit)), self.conversions
239248 conversion_fn = self .conversions [unit ]
240249 ret = conversion_fn (value )
241250 return ret
242251
243-
244252 def get_unit (self ):
245253 return self
246254
255+
247256class UnitResolver (object ):
248257 def addition_rule (self , units ):
249258 for unit_1 , unit_2 in zip (units [:- 1 ], units [1 :]):
250259 if (unit_1 != unit_2 ):
251260 return NotImplemented
252261 return units [0 ]
262+
253263 def multiplication_rule (self , units ):
254264 non_null = [u for u in units if u ]
255265 if (len (non_null ) > 1 ):
256266 return NotImplemented
257267 return non_null [0 ]
258268
259269 op_dict = {
260- '__mul__' :multiplication_rule ,
261- '__rmul__' :multiplication_rule ,
262- '__add__' :addition_rule ,
263- '__radd__' :addition_rule ,
264- '__sub__' :addition_rule ,
265- '__rsub__' :addition_rule ,
266- }
270+ '__mul__' : multiplication_rule ,
271+ '__rmul__' : multiplication_rule ,
272+ '__add__' : addition_rule ,
273+ '__radd__' : addition_rule ,
274+ '__sub__' : addition_rule ,
275+ '__rsub__' : addition_rule }
267276
268277 def __call__ (self , operation , units ):
269278 if (operation not in self .op_dict ):
270279 return NotImplemented
271280
272281 return self .op_dict [operation ](self , units )
273282
274- unit_resolver = UnitResolver ()
275283
284+ unit_resolver = UnitResolver ()
276285
277286cm = BasicUnit ('cm' , 'centimeters' )
278287inch = BasicUnit ('inch' , 'inches' )
@@ -288,11 +297,12 @@ def __call__(self, operation, units):
288297hertz = BasicUnit ('Hz' , 'Hertz' )
289298minutes = BasicUnit ('min' , 'minutes' )
290299
291- secs .add_conversion_fn (hertz , lambda x :1. / x )
300+ secs .add_conversion_fn (hertz , lambda x : 1. / x )
292301secs .add_conversion_factor (minutes , 1 / 60.0 )
293302
303+
294304# radians formatting
295- def rad_fn (x ,pos = None ):
305+ def rad_fn (x , pos = None ):
296306 n = int ((x / np .pi ) * 2.0 + 0.25 )
297307 if n == 0 :
298308 return '0'
@@ -335,7 +345,6 @@ def axisinfo(unit, axis):
335345 def convert (val , unit , axis ):
336346 if units .ConversionInterface .is_numlike (val ):
337347 return val
338- #print 'convert checking iterable'
339348 if iterable (val ):
340349 return [thisval .convert_to (unit ).get_value () for thisval in val ]
341350 else :
@@ -350,15 +359,12 @@ def default_units(x, axis):
350359 return x .unit
351360
352361
353-
354- def cos ( x ):
355- if ( iterable (x ) ):
356- result = []
357- for val in x :
358- result .append ( math .cos ( val .convert_to ( radians ).get_value () ) )
359- return result
362+ def cos (x ):
363+ if iterable (x ):
364+ return [math .cos (val .convert_to (radians ).get_value ()) for val in x ]
360365 else :
361- return math .cos ( x .convert_to ( radians ).get_value () )
366+ return math .cos (x .convert_to (radians ).get_value ())
367+
362368
363369basicConverter = BasicUnitConverter ()
364370units .registry [BasicUnit ] = basicConverter
0 commit comments