Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 56f12a8

Browse files
committed
more units refactoring
svn path=/trunk/matplotlib/; revision=3127
1 parent 1e11bd6 commit 56f12a8

17 files changed

Lines changed: 271 additions & 239 deletions

CHANGELOG

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
2007-03-26 Refactored some of the units support -- units now live in
2+
the respective x and y Axis instances. See also
3+
API_CHANGES for some alterations to the conversion
4+
interface. JDH
5+
16
2007-03-25 Fix masked array handling in quiver.py for numpy. (Numeric
27
and numarray support for masked arrays is broken in other
38
ways when using quiver. I didn't pursue that.) - ADS

examples/backend_driver.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,6 @@ def drive(backend, python='python'):
9696
print '\tSkipping %s, known to fail on backend: %s'%backend
9797
continue
9898

99-
if python=='python2.2' and fname in fail22:
100-
print '\tSkipping %s, known to fail on python2.2'%fname
101-
continue
10299
print '\tdriving %s' % fname
103100
basename, ext = os.path.splitext(fname)
104101
outfile = basename + '_%s'%backend
@@ -109,6 +106,7 @@ def drive(backend, python='python'):
109106
'from __future__ import division\n',
110107
'import matplotlib\n',
111108
'matplotlib.use("%s")\n' % backend,
109+
'from pylab import savefig\n',
112110
))
113111
for line in file(fname):
114112
line_lstrip = line.lstrip()
@@ -134,8 +132,8 @@ def drive(backend, python='python'):
134132
#backends = ['Agg', 'PS', 'SVG', 'Template']
135133
# backends = [ 'GTK', 'WX', 'TkAgg']
136134
default_backends = ['Agg', 'PS', 'SVG', 'Template']
137-
default_backends = ['Agg']
138-
backends = ['Agg']
135+
#default_backends = ['Agg']
136+
#backends = ['Agg']
139137
if sys.platform == 'win32':
140138
python = r'c:\Python24\python.exe'
141139
else:

examples/units/basic_units.py

Lines changed: 90 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -8,87 +8,88 @@
88
from matplotlib.cbook import iterable
99

1010
class ProxyDelegate(object):
11-
def __init__(self, fn_name, proxy_type):
12-
self.proxy_type = proxy_type
13-
self.fn_name = fn_name
14-
def __get__(self, obj, objtype=None):
15-
return self.proxy_type(self.fn_name, obj)
11+
def __init__(self, fn_name, proxy_type):
12+
self.proxy_type = proxy_type
13+
self.fn_name = fn_name
14+
def __get__(self, obj, objtype=None):
15+
return self.proxy_type(self.fn_name, obj)
1616

1717
class TaggedValueMeta (type):
18-
def __init__(cls, name, bases, dict):
19-
for fn_name in cls._proxies.keys():
20-
try:
21-
dummy = getattr(cls, fn_name)
22-
except AttributeError:
23-
setattr(cls, fn_name, ProxyDelegate(fn_name, cls._proxies[fn_name]))
18+
def __init__(cls, name, bases, dict):
19+
for fn_name in cls._proxies.keys():
20+
try:
21+
dummy = getattr(cls, fn_name)
22+
except AttributeError:
23+
setattr(cls, fn_name, ProxyDelegate(fn_name, cls._proxies[fn_name]))
2424

2525
class PassThroughProxy(object):
26-
def __init__(self, fn_name, obj):
27-
self.fn_name = fn_name
28-
self.target = obj.proxy_target
29-
def __call__(self, *args):
30-
fn = getattr(self.target, self.fn_name)
31-
ret = fn(*args)
32-
return ret
26+
def __init__(self, fn_name, obj):
27+
self.fn_name = fn_name
28+
self.target = obj.proxy_target
29+
def __call__(self, *args):
30+
fn = getattr(self.target, self.fn_name)
31+
ret = fn(*args)
32+
return ret
3333

3434
class ConvertArgsProxy(PassThroughProxy):
35-
def __init__(self, fn_name, obj):
36-
PassThroughProxy.__init__(self, fn_name, obj)
37-
self.unit = obj.unit
38-
def __call__(self, *args):
39-
converted_args = []
40-
for a in args:
41-
try:
42-
converted_args.append(a.convert_to(self.unit))
43-
except AttributeError:
44-
converted_args.append(TaggedValue(a, self.unit))
45-
converted_args = tuple([c.get_value() for c in converted_args])
46-
return PassThroughProxy.__call__(self, *converted_args)
35+
def __init__(self, fn_name, obj):
36+
PassThroughProxy.__init__(self, fn_name, obj)
37+
self.unit = obj.unit
38+
def __call__(self, *args):
39+
converted_args = []
40+
for a in args:
41+
try:
42+
converted_args.append(a.convert_to(self.unit))
43+
except AttributeError:
44+
converted_args.append(TaggedValue(a, self.unit))
45+
converted_args = tuple([c.get_value() for c in converted_args])
46+
return PassThroughProxy.__call__(self, *converted_args)
4747

4848
class ConvertReturnProxy(PassThroughProxy):
49-
def __init__(self, fn_name, obj):
50-
PassThroughProxy.__init__(self, fn_name, obj)
51-
self.unit = obj.unit
52-
def __call__(self, *args):
53-
ret = PassThroughProxy.__call__(self, *args)
54-
if (type(ret) == type(NotImplemented)):
55-
return NotImplemented
56-
return TaggedValue(ret, self.unit)
49+
def __init__(self, fn_name, obj):
50+
PassThroughProxy.__init__(self, fn_name, obj)
51+
self.unit = obj.unit
52+
def __call__(self, *args):
53+
ret = PassThroughProxy.__call__(self, *args)
54+
if (type(ret) == type(NotImplemented)):
55+
return NotImplemented
56+
return TaggedValue(ret, self.unit)
5757

5858
class ConvertAllProxy(PassThroughProxy):
59-
def __init__(self, fn_name, obj):
60-
PassThroughProxy.__init__(self, fn_name, obj)
61-
self.unit = obj.unit
62-
def __call__(self, *args):
63-
converted_args = []
64-
arg_units = [self.unit]
65-
for a in args:
66-
if hasattr(a, 'get_unit') and not hasattr(a, 'convert_to'):
67-
# if this arg has a unit type but no conversion ability,
68-
# this operation is prohibited
69-
return NotImplemented
70-
71-
if hasattr(a, 'convert_to'):
72-
try:
73-
a = a.convert_to(self.unit)
74-
except:
75-
pass
76-
arg_units.append(a.get_unit())
77-
converted_args.append(a.get_value())
78-
else:
79-
converted_args.append(a)
80-
if hasattr(a, 'get_unit'):
81-
arg_units.append(a.get_unit())
82-
else:
83-
arg_units.append(None)
84-
converted_args = tuple(converted_args)
85-
ret = PassThroughProxy.__call__(self, *converted_args)
86-
if (type(ret) == type(NotImplemented)):
87-
return NotImplemented
88-
ret_unit = unit_resolver(self.fn_name, arg_units)
89-
if (ret_unit == NotImplemented):
90-
return NotImplemented
91-
return TaggedValue(ret, ret_unit)
59+
def __init__(self, fn_name, obj):
60+
PassThroughProxy.__init__(self, fn_name, obj)
61+
self.unit = obj.unit
62+
63+
def __call__(self, *args):
64+
converted_args = []
65+
arg_units = [self.unit]
66+
for a in args:
67+
if hasattr(a, 'get_unit') and not hasattr(a, 'convert_to'):
68+
# if this arg has a unit type but no conversion ability,
69+
# this operation is prohibited
70+
return NotImplemented
71+
72+
if hasattr(a, 'convert_to'):
73+
try:
74+
a = a.convert_to(self.unit)
75+
except:
76+
pass
77+
arg_units.append(a.get_unit())
78+
converted_args.append(a.get_value())
79+
else:
80+
converted_args.append(a)
81+
if hasattr(a, 'get_unit'):
82+
arg_units.append(a.get_unit())
83+
else:
84+
arg_units.append(None)
85+
converted_args = tuple(converted_args)
86+
ret = PassThroughProxy.__call__(self, *converted_args)
87+
if (type(ret) == type(NotImplemented)):
88+
return NotImplemented
89+
ret_unit = unit_resolver(self.fn_name, arg_units)
90+
if (ret_unit == NotImplemented):
91+
return NotImplemented
92+
return TaggedValue(ret, ret_unit)
9293

9394
class TaggedValue (object):
9495

@@ -102,11 +103,15 @@ def __new__(cls, value, unit):
102103
# generate a new subclass for value
103104
value_class = type(value)
104105
try:
105-
subcls = type('TaggedValue_of_%s' % (`value_class.__name__`),
106+
subcls = type('TaggedValue_of_%s' % (value_class.__name__),
106107
tuple([cls, value_class]),
107108
{})
109+
if subcls not in units.registry:
110+
units.registry[subcls] = basicConverter
108111
return object.__new__(subcls, value, unit)
109-
except:
112+
except TypeError:
113+
if cls not in units.registry:
114+
units.registry[cls] = basicConverter
110115
return object.__new__(cls, value, unit)
111116

112117
def __init__(self, value, unit):
@@ -177,7 +182,7 @@ def __init__(self, name, fullname=None):
177182

178183

179184
def __repr__(self):
180-
return 'BasicUnit(' + `self.name` + ')'
185+
return 'BasicUnit(%s)'%self.name
181186

182187
def __str__(self):
183188
return self.fullname
@@ -314,15 +319,23 @@ def axisinfo(unit):
314319
axisinfo = staticmethod(axisinfo)
315320

316321
def convert(val, unit):
322+
if units.ConversionInterface.is_numlike(val):
323+
return val
324+
317325
if iterable(val):
318-
return [thisval.convert_to(unit).get_value() for thisval in val]
326+
return [thisval.convert_to(unit).get_value() for thisval in val]
319327
else:
320-
return val.convert_to(unit).get_value()
328+
return val.convert_to(unit).get_value()
321329
convert = staticmethod(convert)
322330

323331
def default_units(x):
324332
'return the default unit for x or None'
333+
if iterable(x):
334+
for thisx in x:
335+
return thisx.unit
325336
return x.unit
326337
default_units = staticmethod(default_units)
327338

328-
units.registry[TaggedValue] = BasicUnitConverter()
339+
340+
basicConverter = BasicUnitConverter()
341+
units.registry[TaggedValue] = basicConverter

examples/units/date_support.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import matplotlib
22
matplotlib.rcParams['units'] = True
3-
3+
from matplotlib.cbook import iterable, is_numlike
44
import matplotlib.units as units
55
import matplotlib.dates as dates
66
import matplotlib.ticker as ticker
@@ -22,6 +22,8 @@ def axisinfo(unit):
2222
axisinfo = staticmethod(axisinfo)
2323

2424
def convert(value, unit):
25+
if units.ConversionInterface.is_numlike(value): return value
26+
if not DateConverter.is_date(value): return value
2527
return dates.date2num(value)
2628
convert = staticmethod(convert)
2729

@@ -30,5 +32,6 @@ def default_units(x):
3032
return 'date'
3133
default_units = staticmethod(default_units)
3234

33-
units.registry[datetime.date] = DateConverter()
3435

36+
units.registry[datetime.date] = DateConverter()
37+
units.registry[datetime.datetime] = DateConverter()

examples/units/evans_test.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
"""
2+
A mockup "Foo" units class which supports
3+
conversion and different tick formatting depending on the "unit".
4+
Here the "unit" is just a scalar conversion factor, but this example shows mpl is
5+
entirely agnostic to what kind of units client packages use
6+
"""
7+
18
import matplotlib
29
matplotlib.rcParams['units'] = True
310

@@ -35,7 +42,9 @@ def convert(obj, unit):
3542
convert obj using unit. If obj is a sequence, return the
3643
converted sequence
3744
"""
38-
print 'convert to value', unit
45+
if units.ConversionInterface.is_numlike(obj):
46+
return obj
47+
3948
if iterable(obj):
4049
return [o.value(unit) for o in obj]
4150
else:

examples/units/evans_test2.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
"""
2+
Plot with radians from the basic_units mockup example package
3+
This example shows how the unit class can determine the tick locating,
4+
formatting and axis labeling
5+
"""
16
from basic_units import radians, degrees
27
from pylab import figure, show, nx
38
from matplotlib.cbook import iterable
@@ -12,17 +17,9 @@ def cos( x ):
1217
else:
1318
return math.cos( x.convert_to( radians ).get_value() )
1419

15-
# the following command strips away the units and
16-
# therefore demonstrates nothing. The valeus are
17-
# the same for both graphs. In order to really
18-
# use the units, the list of values passed into
19-
# the plot function must be a unitized type.
2020

21-
# x = nx.arange(0, 15, 0.01) * radians
21+
x = nx.arange(0, 15, 0.01) * radians
2222

23-
x = []
24-
for i in range(0, 1500):
25-
x.append( i*0.01*radians )
2623

2724
fig = figure()
2825

examples/units/units_sample.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
"""
2+
plot using a variety of cm vs inches conversions. The example shows
3+
how default unit instrospection works (ax1), how various keywords can
4+
be used to set the x and y units to override the defaults (ax2, ax3,
5+
ax4) and how one can set the xlimits
6+
7+
"""
18
from basic_units import cm, inch
29
from pylab import figure, show, nx
310

@@ -6,16 +13,18 @@
613
fig = figure()
714

815
ax1 = fig.add_subplot(2,2,1)
9-
ax1.plot(cms, cms, xunits=cm, yunits=cm)
16+
ax1.plot(cms, cms)
1017

1118
ax2 = fig.add_subplot(2,2,2)
1219
ax2.plot(cms, cms, xunits=cm, yunits=inch)
1320

1421
ax3 = fig.add_subplot(2,2,3)
1522
ax3.plot(cms, cms, xunits=inch, yunits=cm)
23+
ax3.set_xlim(3, 6) # scalars are interpreted in current units
1624

1725
ax4 = fig.add_subplot(2,2,4)
1826
ax4.plot(cms, cms, xunits=inch, yunits=inch)
1927
#fig.savefig('simple_conversion_plot.png')
28+
ax4.set_xlim(3*cm, 6*cm) # cm are converted to inches
2029

2130
show()

examples/units/units_scatter.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313

1414
# create masked array
1515

16-
#xsecs = secs*nx.ma.MaskedArray((1,2,3,4,5,6,7,8), nx.Float, mask=(1,0,1,0,0,0,1,0))
17-
xsecs = secs*nx.arange(1,10.)
16+
xsecs = secs*nx.ma.MaskedArray((1,2,3,4,5,6,7,8), nx.Float, mask=(1,0,1,0,0,0,1,0))
17+
#xsecs = secs*nx.arange(1,10.)
1818

1919
fig = figure()
2020
ax1 = fig.add_subplot(3,1,1)

examples/xcorr_demo.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from pylab import figure, show, nx
22

3-
43
x,y = nx.mlab.randn(2,100)
54
fig = figure()
65
ax1 = fig.add_subplot(211)

lib/matplotlib/artist.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ def convert_xunits(self, x):
5353
convert x using xaxis unit type
5454
"""
5555
ax = self.axes
56-
if ax is None or ax.xaxis is None: return x
56+
if ax is None or ax.xaxis is None:
57+
#print 'artist.convert_xunits no conversion: ax=%s'%ax
58+
return x
5759
return ax.xaxis.convert_units(x)
5860

5961
def convert_yunits(self, y):

0 commit comments

Comments
 (0)