|
From: <md...@us...> - 2007-09-13 12:50:07
|
Revision: 3847
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3847&view=rev
Author: mdboom
Date: 2007-09-13 05:50:05 -0700 (Thu, 13 Sep 2007)
Log Message:
-----------
Merged revisions 3836-3846 via svnmerge from
http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib
........
r3844 | jdh2358 | 2007-09-12 16:37:41 -0400 (Wed, 12 Sep 2007) | 1 line
fixed a bar units bug
........
r3845 | jouni | 2007-09-13 02:29:14 -0400 (Thu, 13 Sep 2007) | 3 lines
More work on dviread and usetex in pdf. It is more usable now,
so I am renaming the method from _draw_tex to draw_tex.
........
Modified Paths:
--------------
branches/transforms/API_CHANGES
branches/transforms/CHANGELOG
branches/transforms/lib/matplotlib/artist.py
branches/transforms/lib/matplotlib/axes.py
branches/transforms/lib/matplotlib/axis.py
branches/transforms/lib/matplotlib/backends/backend_pdf.py
branches/transforms/lib/matplotlib/dviread.py
branches/transforms/lib/matplotlib/mlab.py
branches/transforms/lib/matplotlib/patches.py
Added Paths:
-----------
branches/transforms/examples/units/bar_demo2.py
Property Changed:
----------------
branches/transforms/
Property changes on: branches/transforms
___________________________________________________________________
Name: svnmerge-integrated
- /trunk/matplotlib:1-3835
+ /trunk/matplotlib:1-3846
Modified: branches/transforms/API_CHANGES
===================================================================
--- branches/transforms/API_CHANGES 2007-09-13 12:44:16 UTC (rev 3846)
+++ branches/transforms/API_CHANGES 2007-09-13 12:50:05 UTC (rev 3847)
@@ -1,3 +1,5 @@
+ Made skiprows=1 the default on csv2rec
+
The gd and paint backends have been deleted.
The errorbar method and function now accept additional kwargs
Modified: branches/transforms/CHANGELOG
===================================================================
--- branches/transforms/CHANGELOG 2007-09-13 12:44:16 UTC (rev 3846)
+++ branches/transforms/CHANGELOG 2007-09-13 12:50:05 UTC (rev 3847)
@@ -1,3 +1,10 @@
+2007-09-13 The usetex support in the pdf backend is more usable now,
+ so I am enabling it. - JKS
+
+2007-09-12 Fixed a Axes.bar unit bug - JDH
+
+2007-09-10 Made skiprows=1 the default on csv2rec - JDH
+
2007-09-09 Split out the plotting part of pylab and put it in
pyplot.py; removed numerix from the remaining pylab.py,
which imports everything from pyplot.py. The intention
Copied: branches/transforms/examples/units/bar_demo2.py (from rev 3845, trunk/matplotlib/examples/units/bar_demo2.py)
===================================================================
--- branches/transforms/examples/units/bar_demo2.py (rev 0)
+++ branches/transforms/examples/units/bar_demo2.py 2007-09-13 12:50:05 UTC (rev 3847)
@@ -0,0 +1,34 @@
+"""
+plot using a variety of cm vs inches conversions. The example shows
+how default unit instrospection works (ax1), how various keywords can
+be used to set the x and y units to override the defaults (ax2, ax3,
+ax4) and how one can set the xlimits using scalars (ax3, current units
+assumed) or units (conversions applied to get the numbers to current
+units)
+
+"""
+from basic_units import cm, inch
+from pylab import figure, show, nx
+
+cms = cm *nx.arange(0, 10, 2)
+bottom=0*cm
+width=0.8*cm
+
+fig = figure()
+
+ax1 = fig.add_subplot(2,2,1)
+ax1.bar(cms, cms, bottom=bottom)
+
+ax2 = fig.add_subplot(2,2,2)
+ax2.bar(cms, cms, bottom=bottom, width=width, xunits=cm, yunits=inch)
+
+ax3 = fig.add_subplot(2,2,3)
+ax3.bar(cms, cms, bottom=bottom, width=width, xunits=inch, yunits=cm)
+ax3.set_xlim(3, 6) # scalars are interpreted in current units
+
+ax4 = fig.add_subplot(2,2,4)
+ax4.bar(cms, cms, bottom=bottom, width=width, xunits=inch, yunits=inch)
+#fig.savefig('simple_conversion_plot.png')
+ax4.set_xlim(3*cm, 6*cm) # cm are converted to inches
+
+show()
Modified: branches/transforms/lib/matplotlib/artist.py
===================================================================
--- branches/transforms/lib/matplotlib/artist.py 2007-09-13 12:44:16 UTC (rev 3846)
+++ branches/transforms/lib/matplotlib/artist.py 2007-09-13 12:50:05 UTC (rev 3847)
@@ -51,7 +51,7 @@
self._remove_method = None
def remove(self):
- '''
+ """
Remove the artist from the figure if possible. The effect will not
be visible until the figure is redrawn, e.g., with ax.draw_idle().
Call ax.relim() to update the axes limits if desired.
@@ -60,7 +60,7 @@
was added to axes with autolim=True.
Note: there is no support for removing the artist's legend entry.
- '''
+ """
# There is no method to set the callback. Instead the parent should set
# the _remove_method attribute directly. This would be a protected
Modified: branches/transforms/lib/matplotlib/axes.py
===================================================================
--- branches/transforms/lib/matplotlib/axes.py 2007-09-13 12:44:16 UTC (rev 3846)
+++ branches/transforms/lib/matplotlib/axes.py 2007-09-13 12:50:05 UTC (rev 3847)
@@ -1193,23 +1193,27 @@
def _process_unit_info(self, xdata=None, ydata=None, kwargs=None):
'look for unit kwargs and update the axis instances as necessary'
- if self.xaxis is None or self.xaxis is None: return
+ if self.xaxis is None or self.yaxis is None: return
-
+ #print 'processing', self.get_geometry()
if xdata is not None:
self.xaxis.update_units(xdata)
+ #print '\tset from xdata', self.xaxis.units
if ydata is not None:
self.yaxis.update_units(ydata)
+ #print '\tset from ydata', self.yaxis.units
# process kwargs 2nd since these will override default units
if kwargs is not None:
xunits = kwargs.pop( 'xunits', self.xaxis.units)
if xunits!=self.xaxis.units:
+ #print '\tkw setting xunits', xunits
self.xaxis.set_units(xunits)
yunits = kwargs.pop('yunits', self.yaxis.units)
if yunits!=self.yaxis.units:
+ #print '\tkw setting yunits', yunits
self.yaxis.set_units(yunits)
def in_axes(self, xwin, ywin):
@@ -3122,11 +3126,13 @@
else:
raise ValueError, 'invalid orientation: %s' % orientation
- left = npy.asarray(left)
- height = npy.asarray(height)
- width = npy.asarray(width)
- bottom = npy.asarray(bottom)
+ # do not convert to array here as unit info is lost
+ #left = npy.asarray(left)
+ #height = npy.asarray(height)
+ #width = npy.asarray(width)
+ #bottom = npy.asarray(bottom)
+
if len(linewidth) == 1: linewidth = linewidth * nbars
# if color looks like a color string, an RGB tuple or a
@@ -3169,14 +3175,14 @@
# lets do some conversions now
if self.xaxis is not None:
xconv = self.xaxis.converter
- if ( xconv ):
+ if xconv is not None:
units = self.xaxis.get_units()
left = xconv.convert( left, units )
width = xconv.convert( width, units )
if self.yaxis is not None:
yconv = self.yaxis.converter
- if ( yconv ):
+ if yconv is not None :
units = self.yaxis.get_units()
bottom = yconv.convert( bottom, units )
height = yconv.convert( height, units )
@@ -3216,12 +3222,14 @@
if xerr is not None or yerr is not None:
if orientation == 'vertical':
- x = left + 0.5*width
- y = bottom + height
+ # using list comps rather than arrays to preserve unit info
+ x = [l+0.5*w for l, w in zip(left, width)]
+ y = [b+h for b,h in zip(bottom, height)]
elif orientation == 'horizontal':
- x = left + width
- y = bottom + 0.5*height
+ # using list comps rather than arrays to preserve unit info
+ x = [l+w for l,w in zip(left, width)]
+ y = [b+0.5*h for b,h in zip(bottom, height)]
self.errorbar(
x, y,
Modified: branches/transforms/lib/matplotlib/axis.py
===================================================================
--- branches/transforms/lib/matplotlib/axis.py 2007-09-13 12:44:16 UTC (rev 3846)
+++ branches/transforms/lib/matplotlib/axis.py 2007-09-13 12:50:05 UTC (rev 3847)
@@ -821,7 +821,7 @@
return x
ret = self.converter.convert(x, self.units)
- #print 'convert_units converting: units=%s, converter=%s, in=%s, out=%s'%(self.units, self.converter, x, ret)
+ #print 'convert_units converting: axis=%s, units=%s, converter=%s, in=%s, out=%s'%(self, self.units, self.converter, x, ret)
return ret
def set_units(self, u):
Modified: branches/transforms/lib/matplotlib/backends/backend_pdf.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_pdf.py 2007-09-13 12:44:16 UTC (rev 3846)
+++ branches/transforms/lib/matplotlib/backends/backend_pdf.py 2007-09-13 12:50:05 UTC (rev 3847)
@@ -527,7 +527,7 @@
widths.append(afmdata.get_width_from_char_name(ch))
except KeyError:
matplotlib.verbose.report(
- 'No width for %s in %s' % (ch, fullname), 'debug')
+ 'No width for %s in %s' % (ch, fullname), 'debug-annoying')
widths.append(0)
differencesArray = [ Name(ch) for ch in enc ]
@@ -561,7 +561,7 @@
except KeyError:
matplotlib.verbose.report(
'No name for glyph %d in %s' % (ch, fullname),
- 'debug')
+ 'debug-annoying')
need_idx = True
@@ -1449,9 +1449,7 @@
# Pop off the global transformation
self.file.output(Op.grestore)
- def _draw_tex(self, gc, x, y, s, prop, angle):
- # Rename to draw_tex to enable
-
+ def draw_tex(self, gc, x, y, s, prop, angle):
texmanager = self.get_texmanager()
fontsize = prop.get_size_in_points()
dvifile = texmanager.make_dvi(s, fontsize)
@@ -1494,7 +1492,7 @@
elt[3][-1] += next[3][0]
elt[4] += next[4]-next[1]
else:
- elt[3] += [offset, next[3][0]]
+ elt[3] += [offset*1000.0/dvifont.size, next[3][0]]
elt[4] = next[4]
del seq[i+1]
continue
Modified: branches/transforms/lib/matplotlib/dviread.py
===================================================================
--- branches/transforms/lib/matplotlib/dviread.py 2007-09-13 12:44:16 UTC (rev 3846)
+++ branches/transforms/lib/matplotlib/dviread.py 2007-09-13 12:50:05 UTC (rev 3847)
@@ -84,16 +84,22 @@
e = 0 # zero depth
else: # glyph
x,y,font,g,w = elt
- h = (font.scale * font.tfm.height[g]) >> 20
- e = (font.scale * font.tfm.depth[g]) >> 20
+ h = _mul2012(font._scale, font._tfm.height[g])
+ e = _mul2012(font._scale, font._tfm.depth[g])
minx = min(minx, x)
miny = min(miny, y - h)
maxx = max(maxx, x + w)
maxy = max(maxy, y + e)
maxy_pure = max(maxy_pure, y)
+ if self.dpi is None:
+ # special case for ease of debugging: output raw dvi coordinates
+ return mpl_cbook.Bunch(text=self.text, boxes=self.boxes,
+ width=maxx-minx, height=maxy_pure-miny,
+ descent=maxy-maxy_pure)
+
d = self.dpi / (72.27 * 2**16) # from TeX's "scaled points" to dpi units
- text = [ ((x-minx)*d, (maxy-y)*d, DviFont(f), g, w*d)
+ text = [ ((x-minx)*d, (maxy-y)*d, f, g, w*d)
for (x,y,f,g,w) in self.text ]
boxes = [ ((x-minx)*d, (maxy-y)*d, h*d, w*d) for (x,y,h,w) in self.boxes ]
@@ -110,11 +116,11 @@
while True:
byte = ord(self.file.read(1))
self._dispatch(byte)
- if self.state == _dvistate.inpage:
- matplotlib.verbose.report(
- 'Dvi._read: after %d at %f,%f' %
- (byte, self.h, self.v),
- 'debug-annoying')
+# if self.state == _dvistate.inpage:
+# matplotlib.verbose.report(
+# 'Dvi._read: after %d at %f,%f' %
+# (byte, self.h, self.v),
+# 'debug-annoying')
if byte == 140: # end of page
return True
if self.state == _dvistate.post_post: # end of file
@@ -225,21 +231,11 @@
# I think we can assume this is constant
self.state = _dvistate.outer
- def _width_of(self, char, font):
- width = font.tfm.width.get(char, None)
- if width is not None:
- return (width * font.scale) >> 20
-
- matplotlib.verbose.report(
- 'No width for char %d in font %s' % (char, font.name),
- 'debug')
- return 0
-
def _set_char(self, char):
if self.state != _dvistate.inpage:
raise ValueError, "misplaced set_char in dvi file"
self._put_char(char)
- self.h += self._width_of(char, self.fonts[self.f])
+ self.h += self.fonts[self.f]._width_of(char)
def _set_rule(self, a, b):
if self.state != _dvistate.inpage:
@@ -251,20 +247,33 @@
if self.state != _dvistate.inpage:
raise ValueError, "misplaced put_char in dvi file"
font = self.fonts[self.f]
- if font.vf is None:
+ if font._vf is None:
self.text.append((self.h, self.v, font, char,
- self._width_of(char, font)))
+ font._width_of(char)))
+# matplotlib.verbose.report(
+# 'Dvi._put_char: %d,%d %d' %(self.h, self.v, char),
+# 'debug-annoying')
else:
- self.text.extend([(self.h + x, self.v + y, f, g, w)
- for x, y, f, g, w in font.vf[char].text])
- self.boxes.extend([(self.h + x, self.v + y, a, b)
- for x, y, a, b in font.vf[char].boxes])
+ scale = font._scale
+ for x, y, f, g, w in font._vf[char].text:
+ newf = DviFont(scale=_mul2012(scale, f._scale),
+ tfm=f._tfm, texname=f.texname, vf=f._vf)
+ self.text.append((self.h + _mul2012(x, scale),
+ self.v + _mul2012(y, scale),
+ newf, g, newf._width_of(g)))
+ self.boxes.extend([(self.h + _mul2012(x, scale),
+ self.v + _mul2012(y, scale),
+ _mul2012(a, scale), _mul2012(b, scale))
+ for x, y, a, b in font._vf[char].boxes])
def _put_rule(self, a, b):
if self.state != _dvistate.inpage:
raise ValueError, "misplaced put_rule in dvi file"
if a > 0 and b > 0:
self.boxes.append((self.h, self.v, a, b))
+# matplotlib.verbose.report(
+# 'Dvi._put_rule: %d,%d %d,%d' % (self.h, self.v, a, b),
+# 'debug-annoying')
def _nop(self):
pass
@@ -357,7 +366,7 @@
vf = _vffile(n[-l:])
- self.fonts[k] = mpl_cbook.Bunch(scale=s, tfm=tfm, name=n, vf=vf)
+ self.fonts[k] = DviFont(scale=s, tfm=tfm, texname=n, vf=vf)
def _post(self):
if self.state != _dvistate.outer:
@@ -370,17 +379,20 @@
raise NotImplementedError
class DviFont(object):
- __slots__ = ('texname', 'size')
+ """
+ Object that holds a font's texname and size and supports comparison.
+ There are also internal attributes (for use by dviread.py) that
+ are _not_ used for comparison.
- def __init__(self, f):
- """
- Object that holds a font's texname and size and supports comparison.
+ The size is in Adobe points (converted from TeX points).
+ """
+ __slots__ = ('texname', 'size', '_scale', '_vf', '_tfm')
- The size is in Adobe points (converted from TeX points).
- """
+ def __init__(self, scale, tfm, texname, vf):
+ self._scale, self._tfm, self.texname, self._vf = \
+ scale, tfm, texname, vf
# TODO: would it make more sense to have the size in dpi units?
- self.texname = f.name
- self.size = f.scale * (72.0 / (72.27 * 2**16))
+ self.size = scale * (72.0 / (72.27 * 2**16))
def __eq__(self, other):
return self.__class__ == other.__class__ and \
@@ -389,6 +401,16 @@
def __ne__(self, other):
return not self.__eq__(other)
+ def _width_of(self, char):
+ width = self._tfm.width.get(char, None)
+ if width is not None:
+ return _mul2012(width, self._scale)
+
+ matplotlib.verbose.report(
+ 'No width for char %d in font %s' % (char, self.texname),
+ 'debug')
+ return 0
+
class Vf(Dvi):
"""
A virtual font (*.vf file) containing subroutines for dvi files.
@@ -465,7 +487,8 @@
raise ValueError, "pre command in middle of vf file"
if i != 202:
raise ValueError, "Unknown vf format %d" % i
- matplotlib.verbose.report('vf file comment: ' + x, 'debug')
+ if len(x):
+ matplotlib.verbose.report('vf file comment: ' + x, 'debug')
self.state = _dvistate.outer
# cs = checksum, ds = design size
@@ -474,7 +497,7 @@
if self._first_font is None:
self._first_font = k
-def fix2comp(num):
+def _fix2comp(num):
"""
Convert from two's complement to negative.
"""
@@ -484,6 +507,13 @@
else:
return num
+def _mul2012(num1, num2):
+ """
+ Multiply two numbers in 20.12 fixed point format.
+ """
+ # Separated into a function because >> has surprising precedence
+ return (num1*num2) >> 20
+
class Tfm(object):
"""
A TeX Font Metric file. This implementation covers only the bare
@@ -497,6 +527,7 @@
(this is a dict because indexing may not start from 0)
height[i], depth[i]: height and depth of character #i
"""
+ __slots__ = ('checksum', 'design_size', 'width', 'height', 'depth')
def __init__(self, filename):
matplotlib.verbose.report('opening tfm file ' + filename, 'debug')
@@ -525,9 +556,9 @@
[ struct.unpack('!%dI' % (len(x)/4), x)
for x in (widths, heights, depths) ]
for i in range(ec-bc):
- self.width[bc+i] = fix2comp(widths[ord(char_info[4*i])])
- self.height[bc+i] = fix2comp(heights[ord(char_info[4*i+1]) >> 4])
- self.depth[bc+i] = fix2comp(depths[ord(char_info[4*i+1]) & 0xf])
+ self.width[bc+i] = _fix2comp(widths[ord(char_info[4*i])])
+ self.height[bc+i] = _fix2comp(heights[ord(char_info[4*i+1]) >> 4])
+ self.depth[bc+i] = _fix2comp(depths[ord(char_info[4*i+1]) & 0xf])
class PsfontsMap(object):
@@ -552,6 +583,7 @@
the pdf-related files perhaps only avoid the "Base 14" pdf fonts.
But the user may have configured these files differently.
"""
+ __slots__ = ('_font',)
def __init__(self, filename):
self._font = {}
@@ -627,7 +659,17 @@
encoding=encoding, filename=filename)
class Encoding(object):
+ """
+ Parses a *.enc file referenced from a psfonts.map style file.
+ The format this class understands is a very limited subset of
+ PostScript.
+ Usage (subject to change):
+ for name in Encoding(filename):
+ whatever(name)
+ """
+ __slots__ = ('encoding',)
+
def __init__(self, filename):
file = open(filename, 'rt')
try:
@@ -694,6 +736,10 @@
return result
+# With multiple text objects per figure (e.g. tick labels) we may end
+# up reading the same tfm and vf files many times, so we implement a
+# simple cache. TODO: is this worth making persistent?
+
_tfmcache = {}
_vfcache = {}
@@ -721,19 +767,22 @@
if __name__ == '__main__':
- matplotlib.verbose.set_level('debug')
- dvi = Dvi('foo.dvi', 72)
+ import sys
+ matplotlib.verbose.set_level('debug-annoying')
+ fname = sys.argv[1]
+ try: dpi = float(sys.argv[2])
+ except IndexError: dpi = None
+ dvi = Dvi(fname, dpi)
fontmap = PsfontsMap(find_tex_file('pdftex.map'))
- for text,boxes in dvi:
+ for page in dvi:
print '=== new page ==='
fPrev = None
- for x,y,f,c in text:
- texname = dvi.fonts[f].name
- print x,y,c,chr(c),texname
+ for x,y,f,c,w in page.text:
if f != fPrev:
- print 'font', texname, '=', fontmap[texname].__dict__
+ print 'font', f.texname, 'scaled', f._scale/pow(2.0,20)
fPrev = f
- for x,y,w,h in boxes:
+ print x,y,c, 32 <= c < 128 and chr(c) or '.', w
+ for x,y,w,h in page.boxes:
print x,y,'BOX',w,h
Modified: branches/transforms/lib/matplotlib/mlab.py
===================================================================
--- branches/transforms/lib/matplotlib/mlab.py 2007-09-13 12:44:16 UTC (rev 3846)
+++ branches/transforms/lib/matplotlib/mlab.py 2007-09-13 12:50:05 UTC (rev 3847)
@@ -1253,9 +1253,9 @@
if r==1 or c==1:
X.shape = max(r,c),
if unpack: return X.transpose()
- return X
+ else: return X
-def csv2rec(fname, comments='#', skiprows=0, checkrows=5, delimiter=',',
+def csv2rec(fname, comments='#', skiprows=1, checkrows=5, delimiter=',',
converterd=None, names=None, missing=None):
"""
Load data from comma/space/tab delimited file in fname into a
Modified: branches/transforms/lib/matplotlib/patches.py
===================================================================
--- branches/transforms/lib/matplotlib/patches.py 2007-09-13 12:44:16 UTC (rev 3846)
+++ branches/transforms/lib/matplotlib/patches.py 2007-09-13 12:50:05 UTC (rev 3847)
@@ -77,6 +77,8 @@
if len(kwargs): artist.setp(self, **kwargs)
__init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
+
+
def contains(self, mouseevent):
"""Test whether the mouse event occurred in the patch.
@@ -352,7 +354,6 @@
Return the vertices of the rectangle
"""
x, y = self.xy
-
left, right = self.convert_xunits((x, x + self.width))
bottom, top = self.convert_yunits((y, y + self.height))
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|