You can subscribe to this list here.
2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(115) |
Aug
(120) |
Sep
(137) |
Oct
(170) |
Nov
(461) |
Dec
(263) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2008 |
Jan
(120) |
Feb
(74) |
Mar
(35) |
Apr
(74) |
May
(245) |
Jun
(356) |
Jul
(240) |
Aug
(115) |
Sep
(78) |
Oct
(225) |
Nov
(98) |
Dec
(271) |
2009 |
Jan
(132) |
Feb
(84) |
Mar
(74) |
Apr
(56) |
May
(90) |
Jun
(79) |
Jul
(83) |
Aug
(296) |
Sep
(214) |
Oct
(76) |
Nov
(82) |
Dec
(66) |
2010 |
Jan
(46) |
Feb
(58) |
Mar
(51) |
Apr
(77) |
May
(58) |
Jun
(126) |
Jul
(128) |
Aug
(64) |
Sep
(50) |
Oct
(44) |
Nov
(48) |
Dec
(54) |
2011 |
Jan
(68) |
Feb
(52) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
|
|
|
1
(16) |
2
(7) |
3
(4) |
4
|
5
|
6
(4) |
7
(5) |
8
(6) |
9
(7) |
10
(4) |
11
|
12
(2) |
13
(5) |
14
(3) |
15
|
16
(5) |
17
(1) |
18
|
19
|
20
(5) |
21
(7) |
22
(3) |
23
(5) |
24
(1) |
25
|
26
|
27
(6) |
28
(7) |
29
(3) |
30
(8) |
31
(6) |
|
Revision: 3716 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3716&view=rev Author: mdboom Date: 2007年08月20日 05:46:53 -0700 (2007年8月20日) Log Message: ----------- Remove a Unicode character Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/mathtext.py Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2007年08月17日 22:36:01 UTC (rev 3715) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2007年08月20日 12:46:53 UTC (rev 3716) @@ -176,9 +176,9 @@ or a Type1 symbol name (i.e. 'phi'). """ - # From UTF #25: U+2212 − minus sign is the preferred + # From UTF #25: U+2212 minus sign is the preferred # representation of the unary and binary minus sign rather than - # the ASCII-derived U+002D - hyphen-minus, because minus sign is + # the ASCII-derived U+002D hyphen-minus, because minus sign is # unambiguous and because it is rendered with a more desirable # length, usually longer than a hyphen. if symbol == '-': This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3715 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3715&view=rev Author: efiring Date: 2007年08月17日 15:36:01 -0700 (2007年8月17日) Log Message: ----------- Added coll.update(kwargs) to hline method; thanks to Daniel Fish Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/axes.py Modified: trunk/matplotlib/lib/matplotlib/axes.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axes.py 2007年08月16日 21:57:58 UTC (rev 3714) +++ trunk/matplotlib/lib/matplotlib/axes.py 2007年08月17日 22:36:01 UTC (rev 3715) @@ -2345,7 +2345,6 @@ respective values are constant, else the widths of the lines are determined by xmin and xmax - colors is a line collections color args, either a single color or a len(x) list of colors @@ -2370,23 +2369,18 @@ xmin = npy.asarray(xmin) xmax = npy.asarray(xmax) - if len(xmin)!=len(y): raise ValueError, 'xmin and y are unequal sized sequences' if len(xmax)!=len(y): raise ValueError, 'xmax and y are unequal sized sequences' - - - verts = [ ((thisxmin, thisy), (thisxmax, thisy)) for thisxmin, thisxmax, thisy in zip(xmin, xmax, y)] coll = mcoll.LineCollection(verts, colors=colors, linestyle=linestyle, label=label) self.add_collection(coll) + coll.update(kwargs) - - minx = min(xmin.min(), xmax.min()) maxx = max(xmin.max(), xmax.max()) miny = y.min() @@ -2444,8 +2438,6 @@ if len(ymax)==1: ymax = ymax*npy.ones(x.shape, x.dtype) - - if len(ymin)!=len(x): raise ValueError, 'ymin and x are unequal sized sequences' if len(ymax)!=len(x): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3714 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3714&view=rev Author: dsdale Date: 2007年08月16日 14:57:58 -0700 (2007年8月16日) Log Message: ----------- revert changes that cause embedding_in_qt4 to fail Modified Paths: -------------- trunk/matplotlib/examples/embedding_in_qt4.py Modified: trunk/matplotlib/examples/embedding_in_qt4.py =================================================================== --- trunk/matplotlib/examples/embedding_in_qt4.py 2007年08月16日 21:48:52 UTC (rev 3713) +++ trunk/matplotlib/examples/embedding_in_qt4.py 2007年08月16日 21:57:58 UTC (rev 3714) @@ -64,13 +64,11 @@ def compute_initial_figure(self): self.axes.plot([0, 1, 2, 3], [1, 2, 0, 4], 'r') - self.axes.set_yscale('log') def update_figure(self): # Build a list of 4 random integers between 0 and 10 (both inclusive) l = [ random.randint(0, 10) for i in xrange(4) ] - l[l<=0]=1 self.axes.plot([0, 1, 2, 3], l, 'r') self.draw() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3713 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3713&view=rev Author: dsdale Date: 2007年08月16日 14:48:52 -0700 (2007年8月16日) Log Message: ----------- fic bug in traited config: mathtext settings Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/config/mplconfig.py Modified: trunk/matplotlib/lib/matplotlib/config/mplconfig.py =================================================================== --- trunk/matplotlib/lib/matplotlib/config/mplconfig.py 2007年08月16日 21:28:24 UTC (rev 3712) +++ trunk/matplotlib/lib/matplotlib/config/mplconfig.py 2007年08月16日 21:48:52 UTC (rev 3713) @@ -159,6 +159,16 @@ unicode = T.false preamble = T.ListStr([]) dvipnghack = T.false + + class mathtext(TConfig): + cal = T.Trait('cursive', 'cursive', 'normal', 'normal') + rm = T.Trait('serif', 'serif', 'normal', 'normal') + tt = T.Trait('monospace', 'monospace', 'normal', 'normal') + it = T.Trait('serif', 'serif', 'normal', 'italic') + bf = T.Trait('serif', 'serif', 'bold', 'normal') + sf = T.Trait('sans-serif', 'sans-serif', 'normal', 'normal') + use_cm = T.true + fallback_to_cm = T.true class axes(TConfig): hold = T.Trait(True, mplT.BoolHandler()) @@ -329,6 +339,15 @@ 'text.latex.preamble' : (self.tconfig.text.latex, 'preamble'), 'text.dvipnghack' : (self.tconfig.text.latex, 'dvipnghack'), 'text.markup' : (self.tconfig.text, 'markup'), + + 'mathtext.cal' : (self.tconfig.mathtext, 'cal'), + 'mathtext.rm' : (self.tconfig.mathtext, 'rm'), + 'mathtext.tt' : (self.tconfig.mathtext, 'tt'), + 'mathtext.it' : (self.tconfig.mathtext, 'it'), + 'mathtext.bf' : (self.tconfig.mathtext, 'bf'), + 'mathtext.sf' : (self.tconfig.mathtext, 'sf'), + 'mathtext.use_cm' : (self.tconfig.mathtext, 'use_cm'), + 'mathtext.fallback_to_cm' : (self.tconfig.mathtext, 'fallback_to_cm'), 'image.aspect' : (self.tconfig.image, 'aspect'), 'image.interpolation' : (self.tconfig.image, 'interpolation'), This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3712 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3712&view=rev Author: dsdale Date: 2007年08月16日 14:28:24 -0700 (2007年8月16日) Log Message: ----------- fixed bug in traited config: text.markup Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/config/mplconfig.py Modified: trunk/matplotlib/lib/matplotlib/config/mplconfig.py =================================================================== --- trunk/matplotlib/lib/matplotlib/config/mplconfig.py 2007年08月16日 19:43:35 UTC (rev 3711) +++ trunk/matplotlib/lib/matplotlib/config/mplconfig.py 2007年08月16日 21:28:24 UTC (rev 3712) @@ -328,7 +328,7 @@ 'text.latex.unicode' : (self.tconfig.text.latex, 'unicode'), 'text.latex.preamble' : (self.tconfig.text.latex, 'preamble'), 'text.dvipnghack' : (self.tconfig.text.latex, 'dvipnghack'), - 'text.markup' : (self.tconfig.text.markup, 'markup'), + 'text.markup' : (self.tconfig.text, 'markup'), 'image.aspect' : (self.tconfig.image, 'aspect'), 'image.interpolation' : (self.tconfig.image, 'interpolation'), This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3711 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3711&view=rev Author: dsdale Date: 2007年08月16日 12:43:35 -0700 (2007年8月16日) Log Message: ----------- update traited config for text.markup Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/config/mplconfig.py trunk/matplotlib/lib/matplotlib/config/rcsetup.py Modified: trunk/matplotlib/lib/matplotlib/config/mplconfig.py =================================================================== --- trunk/matplotlib/lib/matplotlib/config/mplconfig.py 2007年08月16日 12:53:13 UTC (rev 3710) +++ trunk/matplotlib/lib/matplotlib/config/mplconfig.py 2007年08月16日 19:43:35 UTC (rev 3711) @@ -153,7 +153,7 @@ class text(TConfig): color = T.Trait('black',mplT.ColorHandler()) usetex = T.false - markup = T.Trait('plain', 'tex') + markup = T.Trait('plain', 'plain', 'tex') class latex(TConfig): unicode = T.false Modified: trunk/matplotlib/lib/matplotlib/config/rcsetup.py =================================================================== --- trunk/matplotlib/lib/matplotlib/config/rcsetup.py 2007年08月16日 12:53:13 UTC (rev 3710) +++ trunk/matplotlib/lib/matplotlib/config/rcsetup.py 2007年08月16日 19:43:35 UTC (rev 3711) @@ -198,6 +198,17 @@ except ValueError: raise ValueError('not a valid font size') +def validate_mathtext_font(s): + s = eval(s) + if type(s) in (list, tuple) and len(s) == 3: + return s + raise ValueError('Mathtext font specifier must be a 3-tuple of (family, weight, style)') + +validate_markup = ValidateInStrings( + 'markup', + ['plain', 'tex'], + ignorecase=True) + validate_verbose = ValidateInStrings('verbose',[ 'silent', 'helpful', 'debug', 'debug-annoying', ]) @@ -323,21 +334,24 @@ 'font.stretch' : ['normal', str], # 'font.weight' : ['normal', str], # 'font.size' : [12.0, validate_float], # - 'font.serif' : [['Bitstream Vera Serif','New Century Schoolbook', - 'Century Schoolbook L','Utopia','ITC Bookman', - 'Bookman','Nimbus Roman No9 L','Times New Roman', - 'Times','Palatino','Charter','serif'], + 'font.serif' : [['Bitstream Vera Serif', 'DejaVu Serif', + 'New Century Schoolbook', 'Century Schoolbook L', + 'Utopia', 'ITC Bookman', 'Bookman', + 'Nimbus Roman No9 L','Times New Roman', + 'Times','Palatino','Charter','serif'], validate_stringlist], - 'font.sans-serif' : [['Bitstream Vera Sans','Lucida Grande','Verdana', - 'Geneva','Lucid','Arial','Helvetica','Avant Garde', - 'sans-serif'], validate_stringlist], + 'font.sans-serif' : [['Bitstream Vera Sans', 'DejaVu Sans', + 'Lucida Grande', 'Verdana', 'Geneva', 'Lucid', + 'Arial', 'Helvetica', 'Avant Garde', 'sans-serif'], + validate_stringlist], 'font.cursive' : [['Apple Chancery','Textile','Zapf Chancery', 'Sand','cursive'], validate_stringlist], 'font.fantasy' : [['Comic Sans MS','Chicago','Charcoal','Impact' 'Western','fantasy'], validate_stringlist], - 'font.monospace' : [['Bitstream Vera Sans Mono','Andale Mono' - 'Nimbus Mono L','Courier New','Courier','Fixed' - 'Terminal','monospace'], validate_stringlist], + 'font.monospace' : [['Bitstream Vera Sans Mono', 'DejaVu Sans Mono', + 'Andale Mono', 'Nimbus Mono L', 'Courier New', + 'Courier','Fixed', 'Terminal','monospace'], + validate_stringlist], # text props 'text.color' : ['k', validate_color], # black @@ -345,8 +359,22 @@ 'text.latex.unicode' : [False, validate_bool], 'text.latex.preamble' : [[''], validate_latex_preamble], 'text.dvipnghack' : [False, validate_bool], + 'text.fontstyle' : ['normal', str], + 'text.fontangle' : ['normal', str], + 'text.fontvariant' : ['normal', str], + 'text.fontweight' : ['normal', str], + 'text.fontsize' : ['medium', validate_fontsize], + 'text.markup' : ['plain', validate_markup], - # image props + 'mathtext.cal' : [('cursive', 'normal', 'normal'), validate_mathtext_font], + 'mathtext.rm' : [('serif', 'normal', 'normal'), validate_mathtext_font], + 'mathtext.tt' : [('monospace', 'normal', 'normal'), validate_mathtext_font], + 'mathtext.it' : [('serif', 'normal', 'italic'), validate_mathtext_font], + 'mathtext.bf' : [('serif', 'bold', 'normal'), validate_mathtext_font], + 'mathtext.sf' : [('sans-serif', 'normal', 'normal'), validate_mathtext_font], + 'mathtext.use_cm' : [True, validate_bool], + 'mathtext.fallback_to_cm' : [True, validate_bool], + 'image.aspect' : ['equal', validate_aspect], # equal, auto, a number 'image.interpolation' : ['bilinear', str], 'image.cmap' : ['jet', str], # one of gray, jet, etc @@ -445,8 +473,8 @@ 'pdf.fonttype' : [3, validate_fonttype], # 3 (Type3) or 42 (Truetype) 'svg.image_inline' : [True, validate_bool], # write raster image data directly into the svg file 'svg.image_noscale' : [False, validate_bool], # suppress scaling of raster data embedded in SVG - 'svg.embed_char_paths' : [False, validate_bool], # True to save -#all characters as paths in the SVG + 'svg.embed_char_paths' : [False, validate_bool], # True to save all characters as paths in the SVG + 'plugins.directory' : ['.matplotlib_plugins', str], # where plugin directory is locate } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3710 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3710&view=rev Author: dsdale Date: 2007年08月16日 05:53:13 -0700 (2007年8月16日) Log Message: ----------- added set_extent method to AxesImage Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/examples/embedding_in_qt4.py trunk/matplotlib/lib/matplotlib/image.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2007年08月14日 14:13:27 UTC (rev 3709) +++ trunk/matplotlib/CHANGELOG 2007年08月16日 12:53:13 UTC (rev 3710) @@ -1,3 +1,6 @@ +2007年08月16日 Added a set_extent method to AxesImage, allow data extent + to be modified after initial call to imshow - DSD + 2007年08月14日 Fixed a bug in pyqt4 subplots-adjust. Thanks to Xavier Gnata for the report and suggested fix - DSD Modified: trunk/matplotlib/examples/embedding_in_qt4.py =================================================================== --- trunk/matplotlib/examples/embedding_in_qt4.py 2007年08月14日 14:13:27 UTC (rev 3709) +++ trunk/matplotlib/examples/embedding_in_qt4.py 2007年08月16日 12:53:13 UTC (rev 3710) @@ -64,11 +64,13 @@ def compute_initial_figure(self): self.axes.plot([0, 1, 2, 3], [1, 2, 0, 4], 'r') + self.axes.set_yscale('log') def update_figure(self): # Build a list of 4 random integers between 0 and 10 (both inclusive) l = [ random.randint(0, 10) for i in xrange(4) ] + l[l<=0]=1 self.axes.plot([0, 1, 2, 3], l, 'r') self.draw() Modified: trunk/matplotlib/lib/matplotlib/image.py =================================================================== --- trunk/matplotlib/lib/matplotlib/image.py 2007年08月14日 14:13:27 UTC (rev 3709) +++ trunk/matplotlib/lib/matplotlib/image.py 2007年08月16日 12:53:13 UTC (rev 3710) @@ -236,6 +236,18 @@ # by mistake. self.set_data(A) + + def set_extent(self, extent): + """extent is data axes (left, right, bottom, top) for making image plots + """ + self._extent = extent + + xmin, xmax, ymin, ymax = extent + corners = (xmin, ymin), (xmax, ymax) + self.axes.update_datalim(corners) + if self.axes._autoscaleon: + self.axes.set_xlim((xmin, xmax)) + self.axes.set_ylim((ymin, ymax)) def get_interpolation(self): """ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3709 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3709&view=rev Author: dsdale Date: 2007年08月14日 07:13:27 -0700 (2007年8月14日) Log Message: ----------- fixed a bug in pyqt4 subplots-adjust Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/__init__.py trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2007年08月14日 13:22:56 UTC (rev 3708) +++ trunk/matplotlib/CHANGELOG 2007年08月14日 14:13:27 UTC (rev 3709) @@ -1,3 +1,6 @@ +2007年08月14日 Fixed a bug in pyqt4 subplots-adjust. Thanks to + Xavier Gnata for the report and suggested fix - DSD + 2007年08月13日 Use pickle to cache entire fontManager; change to using font_manager module-level function findfont wrapper for the fontManager.findfont method - EF Modified: trunk/matplotlib/lib/matplotlib/__init__.py =================================================================== --- trunk/matplotlib/lib/matplotlib/__init__.py 2007年08月14日 13:22:56 UTC (rev 3708) +++ trunk/matplotlib/lib/matplotlib/__init__.py 2007年08月14日 14:13:27 UTC (rev 3709) @@ -709,11 +709,10 @@ if NEWCONFIG: #print "importing from reorganized config system!" - from config import rcParams, rcdefaults try: - from config import mplConfig, save_config + from config import rcParams, rcdefaults, mplConfig, save_config except: - pass + from config import rcParams, rcdefaults def use(arg): """ Modified: trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py 2007年08月14日 13:22:56 UTC (rev 3708) +++ trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py 2007年08月14日 14:13:27 UTC (rev 3709) @@ -405,13 +405,17 @@ self.sliderhspace = QtGui.QSlider(QtCore.Qt.Vertical) # constraints - QtCore.QObject.connect( self.sliderleft, QtCore.SIGNAL( "valueChanged(int)" ), + QtCore.QObject.connect( self.sliderleft, + QtCore.SIGNAL( "valueChanged(int)" ), self.sliderright.setMinimum ) - QtCore.QObject.connect( self.sliderright, QtCore.SIGNAL( "valueChanged(int)" ), + QtCore.QObject.connect( self.sliderright, + QtCore.SIGNAL( "valueChanged(int)" ), self.sliderleft.setMaximum ) - QtCore.QObject.connect( self.sliderbottom, QtCore.SIGNAL( "valueChanged(int)" ), + QtCore.QObject.connect( self.sliderbottom, + QtCore.SIGNAL( "valueChanged(int)" ), self.slidertop.setMinimum ) - QtCore.QObject.connect( self.slidertop, QtCore.SIGNAL( "valueChanged(int)" ), + QtCore.QObject.connect( self.slidertop, + QtCore.SIGNAL( "valueChanged(int)" ), self.sliderbottom.setMaximum ) sliders = (self.sliderleft, self.sliderbottom, self.sliderright, @@ -464,38 +468,56 @@ self.setLayout(layout) self.sliderleft.setSliderPosition(int(targetfig.subplotpars.left*1000)) - self.sliderbottom.setSliderPosition(int(targetfig.subplotpars.bottom*1000)) - self.sliderright.setSliderPosition(int(targetfig.subplotpars.right*1000)) + self.sliderbottom.setSliderPosition(\ + int(targetfig.subplotpars.bottom*1000)) + self.sliderright.setSliderPosition(\ + int(targetfig.subplotpars.right*1000)) self.slidertop.setSliderPosition(int(targetfig.subplotpars.top*1000)) - self.sliderwspace.setSliderPosition(int(targetfig.subplotpars.wspace*1000)) - self.sliderhspace.setSliderPosition(int(targetfig.subplotpars.hspace*1000)) + self.sliderwspace.setSliderPosition(\ + int(targetfig.subplotpars.wspace*1000)) + self.sliderhspace.setSliderPosition(\ + int(targetfig.subplotpars.hspace*1000)) - QtCore.QObject.connect( self.sliderleft, QtCore.SIGNAL( "valueChanged(int)" ), + QtCore.QObject.connect( self.sliderleft, + QtCore.SIGNAL( "valueChanged(int)" ), self.funcleft ) - QtCore.QObject.connect( self.sliderbottom, QtCore.SIGNAL( "valueChanged(int)" ), + QtCore.QObject.connect( self.sliderbottom, + QtCore.SIGNAL( "valueChanged(int)" ), self.funcbottom ) - QtCore.QObject.connect( self.sliderright, QtCore.SIGNAL( "valueChanged(int)" ), + QtCore.QObject.connect( self.sliderright, + QtCore.SIGNAL( "valueChanged(int)" ), self.funcright ) - QtCore.QObject.connect( self.slidertop, QtCore.SIGNAL( "valueChanged(int)" ), + QtCore.QObject.connect( self.slidertop, + QtCore.SIGNAL( "valueChanged(int)" ), self.functop ) - QtCore.QObject.connect( self.sliderwspace, QtCore.SIGNAL( "valueChanged(int)" ), + QtCore.QObject.connect( self.sliderwspace, + QtCore.SIGNAL( "valueChanged(int)" ), self.funcwspace ) - QtCore.QObject.connect( self.sliderhspace, QtCore.SIGNAL( "valueChanged(int)" ), + QtCore.QObject.connect( self.sliderhspace, + QtCore.SIGNAL( "valueChanged(int)" ), self.funchspace ) def funcleft(self, val): + if val == self.sliderright.value(): + val -= 1 self.targetfig.subplots_adjust(left=val/1000.) if self.drawon: self.targetfig.canvas.draw() def funcright(self, val): + if val == self.sliderleft.value(): + val += 1 self.targetfig.subplots_adjust(right=val/1000.) if self.drawon: self.targetfig.canvas.draw() def funcbottom(self, val): + if val == self.slidertop.value(): + val -= 1 self.targetfig.subplots_adjust(bottom=val/1000.) if self.drawon: self.targetfig.canvas.draw() def functop(self, val): + if val == self.sliderbottom.value(): + val += 1 self.targetfig.subplots_adjust(top=val/1000.) if self.drawon: self.targetfig.canvas.draw() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3708 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3708&view=rev Author: mdboom Date: 2007年08月14日 06:22:56 -0700 (2007年8月14日) Log Message: ----------- Make searching and copy/paste work in Pdf files (by adding a ToUnicode CMap). Only works with Type42 fonts. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007年08月14日 07:07:45 UTC (rev 3707) +++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007年08月14日 13:22:56 UTC (rev 3708) @@ -485,6 +485,27 @@ os.path.splitext(os.path.basename(filename))[0], symbol_name) + _identityToUnicodeCMap = """/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (Adobe) + /Ordering (UCS) + /Supplement 0 +>> def +/CMapName /Adobe-Identity-UCS def +/CMapType 2 def +1 begincodespacerange +<0000> <ffff> +endcodespacerange +%d beginbfrange +%s +endbfrange +endcmap +CMapName currentdict /CMap defineresource pop +end +end""" + def embedTTF(self, filename, characters): """Embed the TTF font from the named file into the document.""" @@ -612,6 +633,7 @@ cidToGidMapObject = self.reserveObject('CIDToGIDMap stream') fontfileObject = self.reserveObject('font file stream') wObject = self.reserveObject('Type 0 widths') + toUnicodeMapObject = self.reserveObject('ToUnicode map') cidFontDict = { 'Type' : Name('Font'), @@ -631,7 +653,8 @@ 'Subtype' : Name('Type0'), 'BaseFont' : ps_name, 'Encoding' : Name('Identity-H'), - 'DescendantFonts' : [cidFontDictObject] + 'DescendantFonts' : [cidFontDictObject], + 'ToUnicode' : toUnicodeMapObject } # Make fontfile stream @@ -652,9 +675,11 @@ self.endStream() self.writeObject(length1Object, length1) - # Make the 'W' (Widths) array and the CidToGidMap at the same time + # Make the 'W' (Widths) array, CidToGidMap and ToUnicode CMap + # at the same time cid_to_gid_map = [u'\u0000'] * 65536 cmap = font.get_charmap() + unicode_mapping = [] widths = [] max_ccode = 0 for c in characters: @@ -671,15 +696,28 @@ last_ccode = -2 w = [] max_width = 0 + unicode_groups = [] for ccode, width in widths: if ccode != last_ccode + 1: w.append(ccode) w.append([width]) + unicode_groups.append([ccode, ccode]) else: w[-1].append(width) + unicode_groups[-1][1] = ccode max_width = max(max_width, width) last_ccode = ccode + unicode_bfrange = [] + for start, end in unicode_groups: + unicode_bfrange.append( + "<%04x> <%04x> [%s]" % + (start, end, + " ".join(["<%04x>" % x for x in range(start, end+1)]))) + unicode_cmap = (self._identityToUnicodeCMap % + (len(unicode_groups), + "\n".join(unicode_bfrange))) + # CIDToGIDMap stream cid_to_gid_map = "".join(cid_to_gid_map).encode("utf-16be") self.beginStream(cidToGidMapObject.id, @@ -688,6 +726,13 @@ self.currentstream.write(cid_to_gid_map) self.endStream() + # ToUnicode CMap + self.beginStream(toUnicodeMapObject.id, + None, + {'Length': unicode_cmap}) + self.currentstream.write(unicode_cmap) + self.endStream() + descriptor['MaxWidth'] = max_width # Write everything out This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3707 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3707&view=rev Author: efiring Date: 2007年08月14日 00:07:45 -0700 (2007年8月14日) Log Message: ----------- Use pickle to cache entire fontManager instance. Call font_manager.findfont() instead of font_manager.fontManager.findfont(). Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/examples/fonts_demo.py trunk/matplotlib/examples/fonts_demo_kw.py trunk/matplotlib/lib/matplotlib/backends/backend_agg.py trunk/matplotlib/lib/matplotlib/backends/backend_agg2.py trunk/matplotlib/lib/matplotlib/backends/backend_emf.py trunk/matplotlib/lib/matplotlib/backends/backend_gd.py trunk/matplotlib/lib/matplotlib/backends/backend_paint.py trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py trunk/matplotlib/lib/matplotlib/backends/backend_ps.py trunk/matplotlib/lib/matplotlib/backends/backend_qt.py trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py trunk/matplotlib/lib/matplotlib/backends/backend_svg.py trunk/matplotlib/lib/matplotlib/font_manager.py trunk/matplotlib/lib/matplotlib/mathtext.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2007年08月13日 15:19:11 UTC (rev 3706) +++ trunk/matplotlib/CHANGELOG 2007年08月14日 07:07:45 UTC (rev 3707) @@ -1,3 +1,7 @@ +2007年08月13日 Use pickle to cache entire fontManager; change to using + font_manager module-level function findfont wrapper for + the fontManager.findfont method - EF + 2007年08月11日 Numpification and cleanup of mlab.py and some examples - EF 2007年08月06日 Removed mathtext2 Modified: trunk/matplotlib/examples/fonts_demo.py =================================================================== --- trunk/matplotlib/examples/fonts_demo.py 2007年08月13日 15:19:11 UTC (rev 3706) +++ trunk/matplotlib/examples/fonts_demo.py 2007年08月14日 07:07:45 UTC (rev 3707) @@ -3,9 +3,9 @@ Show how to set custom font properties. For interactive users, you can also use kwargs to the text command, -which requires less typing. See exampes/fonts_demo_kw.py +which requires less typing. See examples/fonts_demo_kw.py """ -from matplotlib.font_manager import fontManager, FontProperties +from matplotlib.font_manager import FontProperties from pylab import * subplot(111, axisbg='w') Modified: trunk/matplotlib/examples/fonts_demo_kw.py =================================================================== --- trunk/matplotlib/examples/fonts_demo_kw.py 2007年08月13日 15:19:11 UTC (rev 3706) +++ trunk/matplotlib/examples/fonts_demo_kw.py 2007年08月14日 07:07:45 UTC (rev 3707) @@ -4,7 +4,7 @@ style of coding, see examples/fonts_demo.py. """ -from matplotlib.font_manager import fontManager, FontProperties +from matplotlib.font_manager import FontProperties from pylab import * subplot(111, axisbg='w') Modified: trunk/matplotlib/lib/matplotlib/backends/backend_agg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007年08月13日 15:19:11 UTC (rev 3706) +++ trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007年08月14日 07:07:45 UTC (rev 3707) @@ -81,7 +81,7 @@ GraphicsContextBase, FigureManagerBase, FigureCanvasBase from matplotlib.cbook import enumerate, is_string_like, exception_to_str from matplotlib.figure import Figure -from matplotlib.font_manager import fontManager +from matplotlib.font_manager import findfont from matplotlib.ft2font import FT2Font, LOAD_DEFAULT from matplotlib.mathtext import math_parse_s_ft2font from matplotlib.transforms import lbwh_to_bbox @@ -175,7 +175,7 @@ 'debug-annoying') width, height, fonts, used_characters = math_parse_s_ft2font( s, self.dpi.get(), prop) - + if angle == 90: width, height = height, width for font in fonts: @@ -297,7 +297,7 @@ font = _fontd.get(key) if font is None: - fname = fontManager.findfont(prop) + fname = findfont(prop) font = FT2Font(str(fname)) _fontd[key] = font Modified: trunk/matplotlib/lib/matplotlib/backends/backend_agg2.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_agg2.py 2007年08月13日 15:19:11 UTC (rev 3706) +++ trunk/matplotlib/lib/matplotlib/backends/backend_agg2.py 2007年08月14日 07:07:45 UTC (rev 3707) @@ -15,7 +15,6 @@ from matplotlib.cbook import enumerate, is_string_like, exception_to_str from matplotlib.figure import Figure -from matplotlib.font_manager import fontManager from matplotlib.ft2font import FT2Font from matplotlib.mathtext import math_parse_s_ft2font Modified: trunk/matplotlib/lib/matplotlib/backends/backend_emf.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_emf.py 2007年08月13日 15:19:11 UTC (rev 3706) +++ trunk/matplotlib/lib/matplotlib/backends/backend_emf.py 2007年08月14日 07:07:45 UTC (rev 3707) @@ -23,7 +23,7 @@ from matplotlib.figure import Figure from matplotlib.transforms import Bbox -from matplotlib.font_manager import fontManager, FontProperties +from matplotlib.font_manager import findfont, FontProperties from matplotlib.ft2font import FT2Font, KERNING_UNFITTED, KERNING_DEFAULT, KERNING_UNSCALED # Font handling stuff snarfed from backend_ps, but only using TTF fonts @@ -473,7 +473,7 @@ key = hash(prop) font = _fontd.get(key) if font is None: - fname = fontManager.findfont(prop) + fname = findfont(prop) if debugText: print "_get_font_ttf: name=%s" % fname font = FT2Font(str(fname)) _fontd[key] = font Modified: trunk/matplotlib/lib/matplotlib/backends/backend_gd.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_gd.py 2007年08月13日 15:19:11 UTC (rev 3706) +++ trunk/matplotlib/lib/matplotlib/backends/backend_gd.py 2007年08月14日 07:07:45 UTC (rev 3707) @@ -22,7 +22,7 @@ from matplotlib.colors import colorConverter from matplotlib.figure import Figure from matplotlib.transforms import Bbox -from matplotlib.font_manager import fontManager +from matplotlib.font_manager import findfont # support old font names if (os.environ.has_key('GDFONTPATH') and not os.environ.has_key('TTFPATH')): @@ -66,7 +66,7 @@ """ size = prop.get_size_in_points() - font = fontManager.findfont(prop) + font = findfont(prop) scale = self.get_text_scale() try: @@ -176,7 +176,7 @@ """ size = prop.get_size_in_points() - font = fontManager.findfont(prop) + font = findfont(prop) x = int(x) y = int(y) Modified: trunk/matplotlib/lib/matplotlib/backends/backend_paint.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_paint.py 2007年08月13日 15:19:11 UTC (rev 3706) +++ trunk/matplotlib/lib/matplotlib/backends/backend_paint.py 2007年08月14日 07:07:45 UTC (rev 3707) @@ -28,7 +28,7 @@ from matplotlib.figure import Figure from matplotlib.text import Text, _process_text_args -from matplotlib.font_manager import fontManager +from matplotlib.font_manager import findfont """ @@ -106,7 +106,7 @@ Get the paint font for text instance t, cacheing for efficiency """ - fname = fontManager.findfont(prop) + fname = findfont(prop) size = self.get_text_scale() * prop.get_size_in_points() props = fname, size, angle Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007年08月13日 15:19:11 UTC (rev 3706) +++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007年08月14日 07:07:45 UTC (rev 3707) @@ -24,7 +24,7 @@ FigureManagerBase, FigureCanvasBase from matplotlib.cbook import Bunch, enumerate, is_string_like, reverse_dict, get_realpath_and_stat from matplotlib.figure import Figure -from matplotlib.font_manager import fontManager +from matplotlib.font_manager import findfont from matplotlib.afm import AFM from matplotlib.dviread import Dvi from matplotlib.ft2font import FT2Font, FIXED_WIDTH, ITALIC, LOAD_NO_SCALE, \ @@ -441,9 +441,9 @@ if is_string_like(fontprop): filename = fontprop elif rcParams['pdf.use14corefonts']: - filename = fontManager.findfont(fontprop, fontext='afm') + filename = findfont(fontprop, fontext='afm') else: - filename = fontManager.findfont(fontprop) + filename = findfont(fontprop) Fx = self.fontNames.get(filename) if Fx is None: @@ -484,7 +484,7 @@ return "%s-%s" % ( os.path.splitext(os.path.basename(filename))[0], symbol_name) - + def embedTTF(self, filename, characters): """Embed the TTF font from the named file into the document.""" @@ -499,7 +499,7 @@ # boxes and the like if value < 0: return floor(value) else: return ceil(value) - + def embedTTFType3(font, characters, descriptor): """The Type 3-specific part of embedding a Truetype font""" widthsObject = self.reserveObject('font widths') @@ -509,7 +509,7 @@ differencesArray = [] firstchar, lastchar = 0, 255 bbox = [cvt(x, nearest=False) for x in font.bbox] - + fontdict = { 'Type' : Name('Font'), 'BaseFont' : ps_name, @@ -667,7 +667,7 @@ max_ccode = max(ccode, max_ccode) widths.sort() cid_to_gid_map = cid_to_gid_map[:max_ccode + 1] - + last_ccode = -2 w = [] max_width = 0 @@ -689,7 +689,7 @@ self.endStream() descriptor['MaxWidth'] = max_width - + # Write everything out self.writeObject(cidFontDictObject, cidFontDict) self.writeObject(type0FontDictObject, type0FontDict) @@ -699,7 +699,7 @@ return type0FontDictObject # Beginning of main embedTTF function... - + # You are lost in a maze of TrueType tables, all different... ps_name = Name(font.get_sfnt()[(1,0,0,6)]) pclt = font.get_sfnt_table('pclt') \ @@ -737,7 +737,7 @@ return embedTTFType3(font, characters, descriptor) elif fonttype == 42: return embedTTFType42(font, characters, descriptor) - + def alphaState(self, alpha): """Return name of an ExtGState that sets alpha to the given value""" @@ -987,7 +987,7 @@ self.encode_string = self.encode_string_type3 else: self.encode_string = self.encode_string_type42 - + def finalize(self): self.gc.finalize() del self.truetype_font_cache @@ -1020,7 +1020,7 @@ used_characters = self.used_characters.setdefault( stat_key, (realpath, Set())) used_characters[1].update(set) - + def draw_arc(self, gcEdge, rgbFace, x, y, width, height, angle1, angle2, rotation): """ @@ -1187,7 +1187,7 @@ self.file.output(Op.gsave) self.file.output(cos(a), sin(a), -sin(a), cos(a), x, y, Op.concat_matrix) - + self.check_gc(gc, gc._rgb) self.file.output(Op.begin_text) prev_font = None, None @@ -1279,7 +1279,7 @@ def encode_string_type3(self, s): return s.encode('cp1252', 'replace') - + def encode_string_type42(self, s): return s.encode('utf-16be', 'replace') @@ -1296,7 +1296,7 @@ # use XObject command (Do). If using Type 42 fonts, all of # this complication is avoided, but of course, those fonts can # not be subsetted. - + if ismath: return self.draw_mathtext(gc, x, y, s, prop, angle) self.check_gc(gc, gc._rgb) @@ -1344,7 +1344,7 @@ Op.selectfont) self._setup_textpos(x, y, angle) self.file.output(self.encode_string(s), Op.show, Op.end_text) - + def draw_text_woven(chunks): """Outputs text using the woven method, alternating between chunks of 1-byte characters and 2-byte characters. @@ -1375,7 +1375,7 @@ self._setup_textpos(newx, 0, 0, oldx, 0, 0) self.file.output(self.encode_string(chunk), Op.show) oldx = newx - + lastgind = None for c in chunk: ccode = ord(c) @@ -1413,7 +1413,7 @@ return draw_text_simple() else: return draw_text_woven(chunks) - + def get_text_width_height(self, s, prop, ismath): # FT2Font can handle unicode, and so can we # if isinstance(s, unicode): @@ -1443,7 +1443,7 @@ key = hash(prop) font = self.afm_font_cache.get(key) if font is None: - filename = fontManager.findfont(prop, fontext='afm') + filename = findfont(prop, fontext='afm') fh = file(filename) font = AFM(fh) fh.close() @@ -1454,7 +1454,7 @@ key = hash(prop) font = self.truetype_font_cache.get(key) if font is None: - filename = fontManager.findfont(prop) + filename = findfont(prop) font = FT2Font(str(filename)) self.truetype_font_cache[key] = font font.clear() Modified: trunk/matplotlib/lib/matplotlib/backends/backend_ps.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2007年08月13日 15:19:11 UTC (rev 3706) +++ trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2007年08月14日 07:07:45 UTC (rev 3707) @@ -18,7 +18,7 @@ from matplotlib.cbook import is_string_like, izip, get_realpath_and_stat from matplotlib.figure import Figure -from matplotlib.font_manager import fontManager +from matplotlib.font_manager import findfont from matplotlib.ft2font import FT2Font, KERNING_DEFAULT, LOAD_NO_HINTING from matplotlib.ttconv import convert_ttf_to_ps from matplotlib.mathtext import math_parse_s_ps @@ -158,7 +158,7 @@ used_characters = self.used_characters.setdefault( stat_key, (realpath, Set())) used_characters[1].update(set) - + def set_color(self, r, g, b, store=1): if (r,g,b) != self.color: if r==g and r==b: @@ -307,7 +307,7 @@ key = hash(prop) font = self.afmfontd.get(key) if font is None: - font = AFM(file(fontManager.findfont(prop, fontext='afm'))) + font = AFM(file(findfont(prop, fontext='afm'))) self.afmfontd[key] = font return font @@ -315,7 +315,7 @@ key = hash(prop) font = self.fontd.get(key) if font is None: - fname = fontManager.findfont(prop) + fname = findfont(prop) font = FT2Font(str(fname)) self.fontd[key] = font font.clear() Modified: trunk/matplotlib/lib/matplotlib/backends/backend_qt.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_qt.py 2007年08月13日 15:19:11 UTC (rev 3706) +++ trunk/matplotlib/lib/matplotlib/backends/backend_qt.py 2007年08月14日 07:07:45 UTC (rev 3707) @@ -6,7 +6,6 @@ import matplotlib from matplotlib import verbose from matplotlib.cbook import is_string_like, enumerate, onetrue -from matplotlib.font_manager import fontManager from matplotlib.backend_bases import RendererBase, GraphicsContextBase, \ FigureManagerBase, FigureCanvasBase, NavigationToolbar2, cursors from matplotlib._pylab_helpers import Gcf Modified: trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py 2007年08月13日 15:19:11 UTC (rev 3706) +++ trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py 2007年08月14日 07:07:45 UTC (rev 3707) @@ -6,7 +6,6 @@ import matplotlib from matplotlib import verbose from matplotlib.cbook import is_string_like, enumerate, onetrue -from matplotlib.font_manager import fontManager from matplotlib.backend_bases import RendererBase, GraphicsContextBase, \ FigureManagerBase, FigureCanvasBase, NavigationToolbar2, cursors from matplotlib._pylab_helpers import Gcf Modified: trunk/matplotlib/lib/matplotlib/backends/backend_svg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2007年08月13日 15:19:11 UTC (rev 3706) +++ trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2007年08月14日 07:07:45 UTC (rev 3707) @@ -7,7 +7,7 @@ FigureManagerBase, FigureCanvasBase from matplotlib.colors import rgb2hex from matplotlib.figure import Figure -from matplotlib.font_manager import fontManager, FontProperties +from matplotlib.font_manager import findfont, FontProperties from matplotlib.ft2font import FT2Font, KERNING_DEFAULT, LOAD_NO_HINTING from matplotlib.mathtext import math_parse_s_ft2font_svg @@ -57,7 +57,7 @@ key = hash(prop) font = _fontd.get(key) if font is None: - fname = fontManager.findfont(prop) + fname = findfont(prop) font = FT2Font(str(fname)) _fontd[key] = font font.clear() @@ -275,9 +275,9 @@ lastgind = gind currx += kern/64.0 - svg.append('<use xlink:href="#%s" transform="translate(%s)"/>\n' + svg.append('<use xlink:href="#%s" transform="translate(%s)"/>\n' % (charid, currx)) - + currx += (glyph.linearHoriAdvance / 65536.0) svg.append('</g>\n') svg = ''.join(svg) @@ -309,17 +309,17 @@ currx, curry = 0.0, 0.0 for step in glyph.path: if step[0] == 0: # MOVE_TO - path_data.append("m%s %s" % + path_data.append("m%s %s" % (step[1] - currx, -step[2] - curry)) elif step[0] == 1: # LINE_TO - path_data.append("l%s %s" % + path_data.append("l%s %s" % (step[1] - currx, -step[2] - curry)) elif step[0] == 2: # CURVE3 - path_data.append("q%s %s %s %s" % + path_data.append("q%s %s %s %s" % (step[1] - currx, -step[2] - curry, step[3] - currx, -step[4] - curry)) elif step[0] == 3: # CURVE4 - path_data.append("c%s %s %s %s %s %s" % + path_data.append("c%s %s %s %s %s %s" % (step[1] - currx, -step[2] - curry, step[3] - currx, -step[4] - curry, step[5] - currx, -step[6] - curry)) @@ -356,8 +356,8 @@ for font, fontsize, thetext, new_x, new_y_mtc, metrics in svg_glyphs: charid = self._add_char_def(font, thetext) - - svg.append('<use xlink:href="#%s" transform="translate(%s, %s) scale(%s)"/>\n' % + + svg.append('<use xlink:href="#%s" transform="translate(%s, %s) scale(%s)"/>\n' % (charid, new_x, -new_y_mtc, fontsize / self.FONT_SCALE)) svg.append('</g>\n') else: # not rcParams['svg.embed_char_paths'] @@ -373,7 +373,7 @@ for font, fontsize, thetext, new_x, new_y_mtc, metrics in svg_glyphs: new_y = - new_y_mtc - svg.append('<tspan style="font-size: %f; font-family: %s"' % + svg.append('<tspan style="font-size: %f; font-family: %s"' % (fontsize, font.family_name)) xadvance = metrics.advance svg.append(' textLength="%f"' % xadvance) @@ -387,7 +387,7 @@ svg.append(' dy="%f"' % dy) thetext = escape_xml_text(thetext) - + svg.append('>%s</tspan>\n' % thetext) curr_x = new_x + xadvance @@ -407,7 +407,7 @@ for x, y, width, height in svg_rects: svg.append('<rect x="%s" y="%s" width="%s" height="%s" fill="black" stroke="none" />' % (x, -y + height, width, height)) svg.append("</g>") - + self._svgwriter.write (''.join(svg)) self.close_group("mathtext") Modified: trunk/matplotlib/lib/matplotlib/font_manager.py =================================================================== --- trunk/matplotlib/lib/matplotlib/font_manager.py 2007年08月13日 15:19:11 UTC (rev 3706) +++ trunk/matplotlib/lib/matplotlib/font_manager.py 2007年08月14日 07:07:45 UTC (rev 3707) @@ -2,7 +2,7 @@ A module for finding, managing, and using fonts across-platforms. This module provides a single FontManager that can be shared across -backends and platforms. The findfont() method returns the best +backends and platforms. The findfont() function returns the best TrueType (TTF) font file in the local or system font path that matches the specified FontProperties. The FontManager also handles Adobe Font Metrics (AFM) font files for use by the PostScript backend. @@ -231,10 +231,10 @@ if sys.platform == 'darwin': for f in OSXInstalledFonts(): fontfiles[f] = 1 - + for f in get_fontconfig_fonts(fontext): fontfiles[f] = 1 - + elif isinstance(fontpaths, (str, unicode)): fontpaths = [fontpaths] @@ -654,7 +654,7 @@ def get_name(self): """Return the name of the font that best matches the font properties.""" - return ft2font.FT2Font(str(fontManager.findfont(self))).family_name + return ft2font.FT2Font(str(findfont(self))).family_name def get_style(self): """Return the font style. Values are: normal, italic or oblique.""" @@ -849,42 +849,23 @@ # use anything self.defaultFont = self.ttffiles[0] - cache_message = \ -"""Saving TTF font cache for non-PS backends to %s. -Delete this file to have matplotlib rebuild the cache.""" + self.ttfdict = createFontDict(self.ttffiles) - oldcache = os.path.join(get_home(), 'ttffont.cache') - ttfcache = os.path.join(get_configdir(), 'ttffont.cache') - if os.path.exists(oldcache): - print >> sys.stderr, 'Moving old ttfcache location "%s" to new location "%s"'%(oldcache, ttfcache) - shutil.move(oldcache, ttfcache) - - def rebuild(): - self.ttfdict = createFontDict(self.ttffiles) - pickle_dump(self.ttfdict, ttfcache) - verbose.report(cache_message % ttfcache) - - try: - self.ttfdict = pickle_load(ttfcache) - except: - rebuild() + if rcParams['pdf.use14corefonts']: + # Load only the 14 PDF core fonts. These fonts do not need to be + # embedded; every PDF viewing application is required to have them: + # Helvetica, Helvetica-Bold, Helvetica-Oblique, Helvetica-BoldOblique, + # Courier, Courier-Bold, Courier-Oblique, Courier-BoldOblique, + # Times-Roman, Times-Bold, Times-Italic, Times-BoldItalic, Symbol, + # ZapfDingbats. + afmpath = os.path.join(rcParams['datapath'],'fonts','pdfcorefonts') + afmfiles = findSystemFonts(afmpath, fontext='afm') + self.afmdict = createFontDict(afmfiles, fontext='afm') else: - # verify all the cached fnames still exist; if not rebuild - for fname in ttfdict_to_fnames(self.ttfdict): - if not os.path.exists(fname): - rebuild() - break - verbose.report('loaded ttfcache file %s'%ttfcache) + self.afmfiles = findSystemFonts(paths, fontext='afm') + \ + findSystemFonts(fontext='afm') + self.afmdict = createFontDict(self.afmfiles, fontext='afm') - #self.ttfdict = createFontDict(self.ttffiles) - - # Load AFM fonts for PostScript - # Only load file names at this stage, the font dictionary will be - # created when needed. - self.afmfiles = findSystemFonts(paths, fontext='afm') + \ - findSystemFonts(fontext='afm') - self.afmdict = {} - def get_default_weight(self): "Return the default font weight." return self.__default_weight @@ -930,8 +911,6 @@ return fname if fontext == 'afm': - if len(self.afmdict) == 0: - self.afmdict = self._get_afm_font_dict() fontdict = self.afmdict else: fontdict = self.ttfdict @@ -1009,7 +988,7 @@ return fname font_family_aliases = ['serif', 'sans-serif', 'cursive', 'fantasy', 'monospace'] - + for name in prop.get_family(): if name in font_family_aliases: for name2 in rcParams['font.' + name]: @@ -1028,37 +1007,29 @@ return self.defaultFont return fname - def _get_afm_font_dict(self): - cache_message = "Saving AFM font cache for PS and PDF backends to %s.\n" \ - "Delete this file to have matplotlib rebuild the cache." - if rcParams['pdf.use14corefonts']: - # Load only the 14 PDF core fonts. These fonts do not need to be - # embedded; every PDF viewing application is required to have them: - # Helvetica, Helvetica-Bold, Helvetica-Oblique, Helvetica-BoldOblique, - # Courier, Courier-Bold, Courier-Oblique, Courier-BoldOblique, - # Times-Roman, Times-Bold, Times-Italic, Times-BoldItalic, Symbol, - # ZapfDingbats. - afmcache = os.path.join(get_configdir(), 'pdfcorefont.cache') - try: - fontdict = pickle_load(afmcache) - except: - afmpath = os.path.join(rcParams['datapath'],'fonts','pdfcorefonts') - afmfiles = findSystemFonts(afmpath, fontext='afm') - fontdict = createFontDict(afmfiles, fontext='afm') - pickle_dump(fontdict, afmcache) - verbose.report(cache_message % afmcache) - else: - # Load all available AFM fonts - afmcache = os.path.join(get_configdir(), '.afmfont.cache') - try: - fontdict = pickle_load(afmcache) - except: - fontdict = createFontDict(self.afmfiles, fontext='afm') - pickle_dump(fontdict, afmcache) - verbose.report(cache_message % afmcache) +_fmcache = os.path.join(get_configdir(), 'fontManager.cache') - return fontdict +fontManager = None +def _rebuild(): + global fontManager + fontManager = FontManager() + pickle_dump(fontManager, _fmcache) + verbose.report("generated new fontManager") -fontManager = FontManager() +try: + fontManager = pickle_load(_fmcache) + verbose.report("Using fontManager instance from %s" % _fmcache) +except: + _rebuild() + +def findfont(prop, **kw): + global fontManager + font = fontManager.findfont(prop, **kw) + if not os.path.exists(font): + verbose.report("%s returned by pickled fontManager does not exist" % font) + _rebuild() + font = fontManager.findfont(prop, **kw) + return font + Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2007年08月13日 15:19:11 UTC (rev 3706) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2007年08月14日 07:07:45 UTC (rev 3707) @@ -71,7 +71,7 @@ Allowed TeX symbols: [MGDTODO: This list is no longer exhaustive and needs to be updated] - + \/ \Delta \Downarrow \Gamma \Im \LEFTangle \LEFTbrace \LEFTbracket \LEFTparen \Lambda \Leftarrow \Leftbrace \Leftbracket \Leftparen \Leftrightarrow \Omega \P \Phi \Pi \Psi \RIGHTangle \RIGHTbrace @@ -120,7 +120,7 @@ The *Unicode* classes were incomplete when I found them, and have not been refactored to support intermingling of regular text and math text yet. They are most likely broken. -- Michael Droettboom, July 2007 - + Author : John Hunter <jdh...@ac...> Michael Droettboom <md...@st...> (rewrite based on TeX box layout algorithms) @@ -149,14 +149,14 @@ from matplotlib.cbook import enumerate, iterable, Bunch, get_realpath_and_stat, \ is_string_like from matplotlib.ft2font import FT2Font, KERNING_DEFAULT, LOAD_DEFAULT, LOAD_NO_HINTING -from matplotlib.font_manager import fontManager, FontProperties +from matplotlib.font_manager import findfont, FontProperties from matplotlib._mathtext_data import latex_to_bakoma, \ latex_to_standard, tex2uni, type12uni, tex2type1, uni2type1 from matplotlib import get_data_path, rcParams #################### - + # a character over another character charOverChars = { # The first 2 entires in the tuple are (font, char, sizescale) for @@ -240,7 +240,7 @@ def get_hinting_type(self): return LOAD_NO_HINTING - + class MathtextBackendAgg(MathtextBackend): def set_canvas_size(self, w, h): MathtextBackend.set_canvas_size(self, w, h) @@ -263,17 +263,17 @@ def get_hinting_type(self): return LOAD_DEFAULT - + class MathtextBackendPs(MathtextBackend): def __init__(self): self.pswriter = StringIO() - + def render_glyph(self, ox, oy, info): oy = self.height - oy + info.offset postscript_name = info.postscript_name fontsize = info.fontsize symbol_name = info.symbol_name - + ps = """/%(postscript_name)s findfont %(fontsize)s scalefont setfont @@ -291,12 +291,12 @@ self.height, self.pswriter, self.fonts_object.get_used_characters()) - + class MathtextBackendPdf(MathtextBackend): def __init__(self): self.glyphs = [] self.rects = [] - + def render_glyph(self, ox, oy, info): filename = info.font.fname oy = self.height - oy + info.offset @@ -318,7 +318,7 @@ def __init__(self): self.svg_glyphs = [] self.svg_rects = [] - + def render_glyph(self, ox, oy, info): oy = self.height - oy + info.offset thetext = unichr(info.num) @@ -341,7 +341,7 @@ def __init__(self): self.glyphs = [] self.rects = [] - + def render_glyph(self, ox, oy, info): oy = oy - info.offset - self.height thetext = unichr(info.num) @@ -357,7 +357,7 @@ self.height, self.glyphs, self.rects) - + class Fonts(object): """ An abstract base class for fonts that want to render mathtext @@ -378,7 +378,7 @@ # Make these classes doubly-linked self.mathtext_backend.fonts_object = self self.used_characters = {} - + def get_kern(self, font1, sym1, fontsize1, font2, sym2, fontsize2, dpi): """ @@ -389,7 +389,7 @@ symX: a symbol in raw TeX form. e.g. '1', 'x' or '\sigma' fontsizeX: the fontsize in points dpi: the current dots-per-inch - + sym is a single symbol(alphanum, punct) or a special symbol like \sigma. @@ -435,7 +435,7 @@ def get_underline_thickness(self, font, fontsize, dpi): raise NotImplementedError() - + def get_used_characters(self): return self.used_characters @@ -446,7 +446,7 @@ """Override if your font provides multiple sizes of the same symbol.""" return [(fontname, sym)] - + class TruetypeFonts(Fonts): """ A generic base class for all font setups that use Truetype fonts @@ -467,17 +467,17 @@ def __repr__(self): return repr(self.font) - + def __init__(self, default_font_prop, mathtext_backend): Fonts.__init__(self, default_font_prop, mathtext_backend) self.glyphd = {} self.fonts = {} - filename = fontManager.findfont(default_font_prop) + filename = findfont(default_font_prop) default_font = self.CachedFont(FT2Font(str(filename))) - + self.fonts['default'] = default_font - + def _get_font(self, font): """Looks up a CachedFont with its charmap and inverse charmap. font may be a TeX font name (cal, rm, it etc.), or postscript name.""" @@ -500,7 +500,7 @@ def _get_offset(self, cached_font, glyph, fontsize, dpi): return 0. - + def _get_info (self, fontname, sym, fontsize, dpi, mark_as_used=True): 'load the cmfont, metrics and glyph with caching' key = fontname, sym, fontsize, dpi @@ -567,7 +567,7 @@ font = info1.font return font.get_kerning(info1.num, info2.num, KERNING_DEFAULT) / 64.0 return 0.0 - + class BakomaFonts(TruetypeFonts): """ Use the Bakoma true type fonts for rendering @@ -581,7 +581,7 @@ 'ex' : 'cmex10' } fontmap = {} - + def __init__(self, *args, **kwargs): TruetypeFonts.__init__(self, *args, **kwargs) if not len(self.fontmap): @@ -589,14 +589,14 @@ fullpath = os.path.join(self.basepath, val + ".ttf") self.fontmap[key] = fullpath self.fontmap[val] = fullpath - + def _get_offset(self, cached_font, glyph, fontsize, dpi): if cached_font.font.postscript_name == 'Cmex10': return glyph.height/64.0/2.0 + 256.0/64.0 * dpi/72.0 return 0. _slanted_symbols = Set(r"\int \oint".split()) - + def _get_glyph(self, fontname, sym, fontsize): if fontname in self.fontmap and latex_to_bakoma.has_key(sym): basename, num = latex_to_bakoma[sym] @@ -664,19 +664,19 @@ ('\leftbracket', '['), ('\rightbracket', ']')]: _size_alternatives[alias] = _size_alternatives[target] - + def get_sized_alternatives_for_symbol(self, fontname, sym): alternatives = self._size_alternatives.get(sym) if alternatives: return alternatives return [(fontname, sym)] - + class UnicodeFonts(TruetypeFonts): """An abstract base class for handling Unicode fonts. """ fontmap = {} - + def __init__(self, *args, **kwargs): # This must come first so the backend's owner is set correctly if rcParams['mathtext.fallback_to_cm']: @@ -689,15 +689,15 @@ setting = rcParams['mathtext.' + texfont] family, weight, style = setting prop = FontProperties(family=family, weight=weight, style=style) - font = fontManager.findfont(prop) + font = findfont(prop) self.fontmap[texfont] = font - + def _get_offset(self, cached_font, glyph, fontsize, dpi): return 0. def _get_glyph(self, fontname, sym, fontsize): found_symbol = False - + try: uniindex = get_unicode_index(sym) found_symbol = True @@ -743,7 +743,7 @@ uniindex = 0xA4 # currency character, for lack of anything better glyphindex = cached_font.charmap[uniindex] slanted = False - + symbol_name = cached_font.font.get_glyph_name(glyphindex) return cached_font, uniindex, symbol_name, fontsize, slanted @@ -752,7 +752,7 @@ TruetypeFonts.set_canvas_size(self, w, h) if self.cm_fallback: self.cm_fallback.set_canvas_size(w, h) - + def get_used_characters(self): used_characters = dict(self.used_characters) if self.cm_fallback: @@ -766,7 +766,7 @@ if self.cm_fallback: fonts.extend(self.cm_fallback.get_fonts()) return list(set(fonts)) - + class StandardPsFonts(Fonts): """ Use the standard postscript fonts for rendering to backend_ps @@ -778,7 +778,7 @@ fontmap = { 'cal' : 'pzcmi8a', # Zapf Chancery 'rm' : 'pncr8a', # New Century Schoolbook - 'tt' : 'pcrr8a', # Courier + 'tt' : 'pcrr8a', # Courier 'it' : 'pncri8a', # New Century Schoolbook Italic 'sf' : 'phvr8a', # Helvetica 'bf' : 'pncb8a', # New Century Schoolbook Bold @@ -790,13 +790,13 @@ self.glyphd = {} self.fonts = {} - filename = fontManager.findfont(default_font_prop, fontext='afm') + filename = findfont(default_font_prop, fontext='afm') default_font = AFM(file(filename, 'r')) default_font.fname = filename - + self.fonts['default'] = default_font self.pswriter = StringIO() - + def _get_font(self, font): if font in self.fontmap: basename = self.fontmap[font] @@ -814,7 +814,7 @@ def get_fonts(self): return list(set(self.fonts.values())) - + def _get_info (self, fontname, sym, fontsize, dpi): 'load the cmfont, metrics and glyph with caching' key = fontname, sym, fontsize, dpi @@ -831,7 +831,7 @@ fontname = 'rm' found_symbol = False - + if latex_to_standard.has_key(sym): fontname, num = latex_to_standard[sym] glyph = chr(num) @@ -845,7 +845,7 @@ MathTextWarning) slanted = (fontname == 'it') - font = self._get_font(fontname) + font = self._get_font(fontname) if found_symbol: try: @@ -860,7 +860,7 @@ glyph = sym = '?' num = ord(glyph) symbol_name = font.get_name_char(glyph) - + offset = 0 scale = 0.001 * fontsize @@ -890,7 +890,7 @@ glyph = glyph, offset = offset ) - + return self.glyphd[key] def get_kern(self, font1, sym1, fontsize1, @@ -910,7 +910,7 @@ def get_underline_thickness(self, font, fontsize, dpi): cached_font = self._get_font(font) return cached_font.get_underline_thickness() * 0.001 * fontsize - + ############################################################################## # TeX-LIKE BOX MODEL @@ -951,17 +951,17 @@ SUB1 = 0.0 # Percentage of x-height that superscripts are offset relative to the subscript DELTA = 0.18 - + class MathTextWarning(Warning): pass - + class Node(object): """A node in the TeX box model @133 """ def __init__(self): self.size = 0 - + def __repr__(self): return self.__internal_repr__() @@ -980,7 +980,7 @@ """Grows one level larger. There is no limit to how big something can get.""" self.size -= 1 - + def render(self, x, y): pass @@ -1005,7 +1005,7 @@ self.width *= GROW_FACTOR self.height *= GROW_FACTOR self.depth *= GROW_FACTOR - + def render(self, x1, y1, x2, y2): pass @@ -1016,7 +1016,7 @@ class Hbox(Box): def __init__(self, width): Box.__init__(self, width, 0., 0.) - + class Char(Node): """Represents a single character. Unlike TeX, the font information and metrics are stored with each Char to make it @@ -1038,7 +1038,7 @@ # The real width, height and depth will be set during the # pack phase, after we know the real fontsize self._update_metrics() - + def __internal_repr__(self): return '`%s`' % self.c @@ -1054,7 +1054,7 @@ def is_slanted(self): return self._metrics.slanted - + def get_kerning(self, next): """Return the amount of kerning between this and the given character. Called when characters are strung together into @@ -1067,7 +1067,7 @@ next.font, next.c, next.fontsize, self.dpi) return advance + kern - + def render(self, x, y): """Render the character to the canvas""" self.font_output.render_glyph( @@ -1088,7 +1088,7 @@ self.width *= GROW_FACTOR self.height *= GROW_FACTOR self.depth *= GROW_FACTOR - + class Accent(Char): """The font metrics need to be dealt with differently for accents, since they are already offset correctly from the baseline in TrueType fonts.""" @@ -1102,17 +1102,17 @@ def shrink(self): Char.shrink(self) self._update_metrics() - + def grow(self): Char.grow(self) self._update_metrics() - + def render(self, x, y): """Render the character to the canvas""" self.font_output.render_glyph( x - self._metrics.xmin, y + self._metrics.ymin, self.font, self.c, self.fontsize, self.dpi) - + class List(Box): """A list of nodes (either horizontal or vertical). @135""" @@ -1170,7 +1170,7 @@ Box.grow(self) self.shift_amount *= GROW_FACTOR self.glue_set *= GROW_FACTOR - + class Hlist(List): """A horizontal list of boxes. @135""" @@ -1260,7 +1260,7 @@ self._set_glue(x, 1, total_stretch, "Overfull") else: self._set_glue(x, -1, total_shrink, "Underfull") - + class Vlist(List): """A vertical list of boxes. @137""" @@ -1308,7 +1308,7 @@ d = 0. elif isinstance(p, Char): raise RuntimeError("Internal mathtext error: Char node found in Vlist.") - + self.width = w if d > l: x += d - l @@ -1331,7 +1331,7 @@ self._set_glue(x, 1, total_stretch, "Overfull") else: self._set_glue(x, -1, total_shrink, "Underfull") - + class Rule(Box): """A Rule node stands for a solid black rectangle; it has width, depth, and height fields just as in an Hlist. However, if any of these @@ -1343,10 +1343,10 @@ def __init__(self, width, height, depth, state): Box.__init__(self, width, height, depth) self.font_output = state.font_output - + def render(self, x, y, w, h): self.font_output.render_rect_filled(x, y, x + w, y + h) - + class Hrule(Rule): """Convenience class to create a horizontal rule.""" def __init__(self, state): @@ -1361,7 +1361,7 @@ thickness = state.font_output.get_underline_thickness( state.font, state.fontsize, state.dpi) Rule.__init__(self, thickness, inf, inf, state) - + class Glue(Node): """Most of the information in this object is stored in the underlying GlueSpec class, which is shared between multiple glue objects. (This @@ -1393,7 +1393,7 @@ if self.glue_spec.width != 0.: self.glue_spec = self.glue_spec.copy() self.glue_spec.width *= GROW_FACTOR - + class GlueSpec(object): """@150, @151""" def __init__(self, width=0., stretch=0., stretch_order=0, shrink=0., shrink_order=0): @@ -1410,11 +1410,11 @@ self.stretch_order, self.shrink, self.shrink_order) - + def factory(cls, glue_type): return cls._types[glue_type] factory = classmethod(factory) - + GlueSpec._types = { 'fil': GlueSpec(0., 1., 1, 0., 0), 'fill': GlueSpec(0., 1., 2, 0., 0), @@ -1451,24 +1451,24 @@ class NegFilll(Glue): def __init__(self): Glue.__init__(self, 'neg_filll') - + class SsGlue(Glue): def __init__(self): Glue.__init__(self, 'ss') - + class HCentered(Hlist): """A convenience class to create an Hlist whose contents are centered within its enclosing box.""" def __init__(self, elements): Hlist.__init__(self, [SsGlue()] + elements + [SsGlue()], do_kern=False) - + class VCentered(Hlist): """A convenience class to create an Vlist whose contents are centered within its enclosing box.""" def __init__(self, elements): Vlist.__init__(self, [SsGlue()] + elements + [SsGlue()]) - + class Kern(Node): """A Kern node has a width field to specify a (normally negative) amount of spacing. This spacing correction appears in horizontal lists @@ -1483,7 +1483,7 @@ def __repr__(self): return "k%.02f" % self.width - + def shrink(self): Node.shrink(self) if self.size < NUM_SIZE_LEVELS: @@ -1492,7 +1492,7 @@ def grow(self): Node.grow(self) self.width *= GROW_FACTOR - + class SubSuperCluster(Hlist): """This class is a sort of hack to get around that fact that this code doesn't parse to an mlist and then an hlist, but goes directly @@ -1526,7 +1526,7 @@ factor = target_total / (char.height + char.depth) state.fontsize *= factor char = Char(sym, state) - + shift = (depth - char.depth) Hlist.__init__(self, [char]) self.shift_amount = shift @@ -1551,9 +1551,9 @@ factor = width / char.width state.fontsize *= factor char = char_class(sym, state) - + Hlist.__init__(self, [char]) - + class Ship(object): """Once the boxes have been set up, this sends them to output. Since boxes can be inside of boxes inside of boxes, the main @@ -1578,7 +1578,7 @@ return 1000000000. return value clamp = staticmethod(clamp) - + def hlist_out(self, box): cur_g = 0 cur_glue = 0. @@ -1697,7 +1697,7 @@ elif isinstance(p, Char): raise RuntimeError("Internal mathtext error: Char node found in vlist") self.cur_s -= 1 - + ship = Ship() ############################################################################## @@ -1760,7 +1760,7 @@ ) _dropsub_symbols = Set(r'''\int \oint'''.split()) - + def __init__(self): # All forward declarations are here font = Forward().setParseAction(self.font).setName("font") @@ -1873,7 +1873,7 @@ ).setParseAction(self.sqrt).setName("sqrt") placeable <<(accent - ^ function + ^ function ^ symbol ^ rightBracket ^ group @@ -1888,7 +1888,7 @@ subsuperop =(Literal("_") | Literal("^") - ) + ) subsuper << Group( ( Optional(placeable) @@ -1911,9 +1911,9 @@ autoDelim ^ OneOrMore(simple)) + Suppress(Literal(r"\right")) - + (rightDelim | ambiDelim) + + (rightDelim | ambiDelim) ) - + math = OneOrMore( autoDelim | simple @@ -1941,7 +1941,7 @@ self._expr = None self._state_stack = None self._em_width_cache = {} - + def parse(self, s, fonts_object, fontsize, dpi): self._state_stack = [self.State(fonts_object, 'default', fontsize, dpi)] self._expression.parseString(s) @@ -1964,7 +1964,7 @@ self.font, self.fontsize, self.dpi) - + def get_state(self): return self._state_stack[-1] @@ -1973,11 +1973,11 @@ def push_state(self): self._state_stack.append(self.get_state().copy()) - + def finish(self, s, loc, toks): self._expr = Hlist(toks) return [self._expr] - + def math(self, s, loc, toks): #~ print "math", toks hlist = Hlist(toks) @@ -2056,7 +2056,7 @@ } _wide_accents = Set(r"\widehat \widetilde".split()) - + def accent(self, s, loc, toks): assert(len(toks)==1) state = self.get_state() @@ -2087,14 +2087,14 @@ self.pop_state() hlist.function_name = toks[0] return hlist - + def start_group(self, s, loc, toks): self.push_state() # Deal with LaTeX-style font tokens if len(toks): self.get_state().font = toks[0][4:] return [] - + def group(self, s, loc, toks): grp = Hlist(toks[0]) return [grp] @@ -2102,7 +2102,7 @@ def end_group(self, s, loc, toks): self.pop_state() return [] - + def font(self, s, loc, toks): assert(len(toks)==1) name = toks[0] @@ -2125,7 +2125,7 @@ if isinstance(nucleus, Char): return nucleus.is_slanted() return False - + def subsuperscript(self, s, loc, toks): assert(len(toks)==1) # print 'subsuperscript', toks @@ -2133,7 +2133,7 @@ nucleus = None sub = None super = None - + if len(toks[0]) == 1: return toks[0].asList() elif len(toks[0]) == 2: @@ -2164,13 +2164,13 @@ sub = next2 else: raise ParseFatalException("Subscript/superscript sequence is too long.") - + state = self.get_state() rule_thickness = state.font_output.get_underline_thickness( state.font, state.fontsize, state.dpi) xHeight = state.font_output.get_xheight( state.font, state.fontsize, state.dpi) - + if self.is_overunder(nucleus): vlist = [] shift = 0. @@ -2181,7 +2181,7 @@ if sub is not None: sub.shrink() width = max(width, sub.width) - + if super is not None: hlist = HCentered([super]) hlist.hpack(width, 'exactly') @@ -2248,7 +2248,7 @@ state = self.get_state() thickness = state.font_output.get_underline_thickness( state.font, state.fontsize, state.dpi) - + num, den = toks[0] num.shrink() den.shrink() @@ -2316,14 +2316,14 @@ # The value of 0.6 is a hard-coded hack ;) root_vlist = Vlist([Hlist([root])]) root_vlist.shift_amount = -height * 0.6 - + hlist = Hlist([root_vlist, # Root # Negative kerning to put root over tick - Kern(-check.width * 0.5), + Kern(-check.width * 0.5), check, # Check rightside]) # Body return [hlist] - + def auto_sized_delimiter(self, s, loc, toks): #~ print "auto_sized_delimiter", toks front, middle, back = toks @@ -2339,12 +2339,12 @@ parts.append(AutoHeightChar(back, height, depth, state)) hlist = Hlist(parts) return hlist - + #### ############################################################################## # MAIN - + class math_parse_s_ft2font_common: """ Parse the math expression s, return the (bbox, fonts) tuple needed @@ -2367,7 +2367,7 @@ 'SVG' : MathtextBackendSvg, 'Cairo' : MathtextBackendCairo } - + def __init__(self, output): self.output = output self.cache = {} @@ -2404,7 +2404,7 @@ font_output.mathtext_backend.fonts_object = None return result - + math_parse_s_ft2font = math_parse_s_ft2font_common('Agg') math_parse_s_ft2font_svg = math_parse_s_ft2font_common('SVG') math_parse_s_ps = math_parse_s_ft2font_common('PS') This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3706 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3706&view=rev Author: mdboom Date: 2007年08月13日 08:19:11 -0700 (2007年8月13日) Log Message: ----------- Make horizontal line drawing more consistent across all backends. Fix but in ft2font glyph rendering for glyphs with a left offset. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/mathtext.py trunk/matplotlib/src/ft2font.cpp Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2007年08月13日 14:32:15 UTC (rev 3705) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2007年08月13日 15:19:11 UTC (rev 3706) @@ -253,9 +253,7 @@ def render_rect_filled(self, x1, y1, x2, y2): font = self.fonts_object.get_fonts()[0] - font.draw_rect_filled( - int(x1 + 0.5), int(y1 + 0.5) - 1, - int(x2 - 0.5), int(y2 - 0.5) - 1) + font.draw_rect_filled(x1, y1, x2, y2 - 1) def get_results(self): return (self.width, @@ -329,7 +327,7 @@ def render_rect_filled(self, x1, y1, x2, y2): self.svg_rects.append( - (x1, self.height - y2, x2 - x1, y2 - y1)) + (x1, self.height - y1 + 1, x2 - x1, y2 - y1)) def get_results(self): svg_elements = Bunch(svg_glyphs = self.svg_glyphs, @@ -559,8 +557,7 @@ def get_underline_thickness(self, font, fontsize, dpi): cached_font = self._get_font(font) - cached_font.font.set_size(fontsize, dpi) - return max(1.0, cached_font.font.underline_thickness / 64.0) + return max(1.0, cached_font.font.underline_thickness / 64.0 / fontsize * 10.0) def get_kern(self, font1, sym1, fontsize1, font2, sym2, fontsize2, dpi): @@ -1102,10 +1099,18 @@ self.height = metrics.ymax - metrics.ymin self.depth = 0 + def shrink(self): + Char.shrink(self) + self._update_metrics() + + def grow(self): + Char.grow(self) + self._update_metrics() + def render(self, x, y): """Render the character to the canvas""" self.font_output.render_glyph( - x, y + (self._metrics.ymax - self.height), + x - self._metrics.xmin, y + self._metrics.ymin, self.font, self.c, self.fontsize, self.dpi) class List(Box): @@ -2264,8 +2269,8 @@ metrics = state.font_output.get_metrics( state.font, '=', state.fontsize, state.dpi) shift = (cden.height - - (metrics.ymax + metrics.ymin) / 2 + - thickness * 2.5) + ((metrics.ymax + metrics.ymin) / 2 - + thickness * 3.0)) vlist.shift_amount = shift hlist = Hlist([vlist, Hbox(thickness * 2.)]) @@ -2316,7 +2321,6 @@ # Negative kerning to put root over tick Kern(-check.width * 0.5), check, # Check - Kern(-thickness * 0.3), # Push check into rule slightly rightside]) # Body return [hlist] Modified: trunk/matplotlib/src/ft2font.cpp =================================================================== --- trunk/matplotlib/src/ft2font.cpp 2007年08月13日 14:32:15 UTC (rev 3705) +++ trunk/matplotlib/src/ft2font.cpp 2007年08月13日 15:19:11 UTC (rev 3706) @@ -1219,7 +1219,7 @@ FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyphs[glyph->glyphInd]; - draw_bitmap( &bitmap->bitmap, x, y); + draw_bitmap( &bitmap->bitmap, x + bitmap->left, y); return Py::Object(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3705 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3705&view=rev Author: mdboom Date: 2007年08月13日 07:32:15 -0700 (2007年8月13日) Log Message: ----------- Fix typo. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/mathtext.py Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2007年08月13日 14:29:49 UTC (rev 3704) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2007年08月13日 14:32:15 UTC (rev 3705) @@ -1455,7 +1455,6 @@ """A convenience class to create an Hlist whose contents are centered within its enclosing box.""" def __init__(self, elements): - self.is_accent = is_accent Hlist.__init__(self, [SsGlue()] + elements + [SsGlue()], do_kern=False) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3704 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3704&view=rev Author: mdboom Date: 2007年08月13日 07:29:49 -0700 (2007年8月13日) Log Message: ----------- Fix spacing of operators (particularly with custom fonts). Fix positioning of accents. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/mathtext.py Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2007年08月13日 12:55:27 UTC (rev 3703) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2007年08月13日 14:29:49 UTC (rev 3704) @@ -1098,7 +1098,7 @@ def _update_metrics(self): metrics = self._metrics = self.font_output.get_metrics( self.font, self.c, self.fontsize, self.dpi) - self.width = metrics.width + self.width = metrics.xmax - metrics.xmin self.height = metrics.ymax - metrics.ymin self.depth = 0 @@ -1169,9 +1169,10 @@ class Hlist(List): """A horizontal list of boxes. @135""" - def __init__(self, elements, w=0., m='additional'): + def __init__(self, elements, w=0., m='additional', do_kern=True): List.__init__(self, elements) - self.kern() + if do_kern: + self.kern() self.hpack() def kern(self): @@ -1453,14 +1454,10 @@ class HCentered(Hlist): """A convenience class to create an Hlist whose contents are centered within its enclosing box.""" - def __init__(self, elements, is_accent = False): + def __init__(self, elements): self.is_accent = is_accent - Hlist.__init__(self, [SsGlue()] + elements + [SsGlue()]) - - def kern(self): - Hlist.kern(self) - if not self.is_accent and isinstance(self.children[-2], Kern): - self.children = self.children[:-2] + [SsGlue()] + Hlist.__init__(self, [SsGlue()] + elements + [SsGlue()], + do_kern=False) class VCentered(Hlist): """A convenience class to create an Vlist whose contents are centered @@ -2028,10 +2025,12 @@ if c in self._spaced_symbols: return [Hlist( [self._make_space(0.2), char, - self._make_space(0.2)] )] + self._make_space(0.2)] , + do_kern = False)] elif c in self._punctuation_symbols: return [Hlist( [char, - self._make_space(0.2)] )] + self._make_space(0.2)] , + do_kern = False)] return [char] _accent_map = { @@ -2065,13 +2064,10 @@ if accent in self._wide_accents: accent = AutoWidthChar( accent, sym.width, state, char_class=Accent) - shift_amount = 0. else: accent = Accent(self._accent_map[accent], state) - shift_amount = accent._metrics.xmin - centered = HCentered([accent], is_accent=True) + centered = HCentered([accent]) centered.hpack(sym.width, 'exactly') - centered.shift_amount = shift_amount return Vlist([ centered, Vbox(0., thickness * 2.0), This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3703 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3703&view=rev Author: mdboom Date: 2007年08月13日 05:55:27 -0700 (2007年8月13日) Log Message: ----------- Grab list of fonts from fontconfig if fontconfig is installed. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/font_manager.py Modified: trunk/matplotlib/lib/matplotlib/font_manager.py =================================================================== --- trunk/matplotlib/lib/matplotlib/font_manager.py 2007年08月13日 12:46:26 UTC (rev 3702) +++ trunk/matplotlib/lib/matplotlib/font_manager.py 2007年08月13日 12:55:27 UTC (rev 3703) @@ -51,8 +51,8 @@ 'xx-large': 1.728} weight_dict = {'light': 200, 'normal': 400, 'regular': 400, 'book': 400, - 'medium': 500, 'roman': 500, 'semibold': 600, 'demibold': 600, - 'demi': 600, 'bold': 700, 'heavy': 800, 'extra bold': 800, + 'medium': 500, 'roman': 500, 'semibold': 600, 'demibold': 600, + 'demi': 600, 'bold': 700, 'heavy': 800, 'extra bold': 800, 'black': 900} # OS Font paths @@ -185,16 +185,37 @@ pass return fontpaths +def get_fontconfig_fonts(fontext='ttf'): + """Grab a list of all the fonts that are being tracked by fontconfig. + This is an easy way to grab all of the fonts the user wants to be made + available to applications, without knowing where all of them reside.""" + try: + import commands + except ImportError: + return {} + + fontfiles = {} + status, output = commands.getstatusoutput("fc-list file") + if status == 0: + for line in output.split('\n'): + fname = line.split(':')[0] + if (os.path.splitext(fname)[1] == "." + fontext and + os.path.exists(fname)): + fontfiles[fname] = 1 + + return fontfiles + def findSystemFonts(fontpaths=None, fontext='ttf'): """ - Search for fonts in the specified font paths, or use the system - paths if none given. A list of TrueType fonts are returned by default - with AFM fonts as an option. + Search for fonts in the specified font paths. If no paths are + given, will use a standard set of system paths, as well as the + list of fonts tracked by fontconfig if fontconfig is installed and + available. A list of TrueType fonts are returned by default with + AFM fonts as an option. """ fontfiles = {} if fontpaths is None: - if sys.platform == 'win32': fontdir = win32FontDirectory() @@ -210,7 +231,10 @@ if sys.platform == 'darwin': for f in OSXInstalledFonts(): fontfiles[f] = 1 - + + for f in get_fontconfig_fonts(fontext): + fontfiles[f] = 1 + elif isinstance(fontpaths, (str, unicode)): fontpaths = [fontpaths] @@ -447,12 +471,12 @@ seen = {} for fpath in fontfiles: verbose.report('createFontDict: %s' % (fpath), 'debug') - fname = fpath.split('/')[-1] + fname = os.path.split(fpath)[1] if seen.has_key(fname): continue else: seen[fname] = 1 if fontext == 'afm': try: - fh = open(fpath) + fh = open(fpath, 'r') except: verbose.report("Could not open font file %s" % fpath) continue This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3702 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3702&view=rev Author: mdboom Date: 2007年08月13日 05:46:26 -0700 (2007年8月13日) Log Message: ----------- Removed obsolete comment. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py Modified: trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py 2007年08月12日 07:21:47 UTC (rev 3701) +++ trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py 2007年08月13日 12:46:26 UTC (rev 3702) @@ -302,7 +302,6 @@ def _draw_mathtext(self, gc, x, y, s, prop, angle): if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) - # mathtext using the gtk/gdk method ctx = gc.ctx width, height, glyphs, rects = math_parse_s_cairo( This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3701 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3701&view=rev Author: efiring Date: 2007年08月12日 00:21:47 -0700 (2007年8月12日) Log Message: ----------- numpification of mlab Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/examples/axes_demo.py trunk/matplotlib/examples/colours.py trunk/matplotlib/examples/psd_demo.py trunk/matplotlib/examples/scatter_demo.py trunk/matplotlib/lib/matplotlib/art3d.py trunk/matplotlib/lib/matplotlib/mlab.py trunk/matplotlib/lib/matplotlib/pylab.py trunk/matplotlib/lib/matplotlib/ticker.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2007年08月12日 06:08:36 UTC (rev 3700) +++ trunk/matplotlib/CHANGELOG 2007年08月12日 07:21:47 UTC (rev 3701) @@ -1,24 +1,26 @@ +2007年08月11日 Numpification and cleanup of mlab.py and some examples - EF + 2007年08月06日 Removed mathtext2 -2007年07月31日 Refactoring of distutils scripts. - - Will not fail on the entire build if an optional Python +2007年07月31日 Refactoring of distutils scripts. + - Will not fail on the entire build if an optional Python package (e.g. Tkinter) is installed but its development headers are not (e.g. tk-devel). Instead, it will continue to build all other extensions. - - Provide an overview at the top of the output to display - what dependencies and their versions were found, and (by + - Provide an overview at the top of the output to display + what dependencies and their versions were found, and (by extension) what will be built. - Use pkg-config, when available, to find freetype2, since this was broken on Mac OS-X when using MacPorts in a non- standard location. 2007年07月30日 Reorganized configuration code to work with traited config - objects. The new config system is located in the + objects. The new config system is located in the matplotlib.config package, but it is disabled by default. To enable it, set NEWCONFIG=True in matplotlib.__init__.py. - The new configuration system will still use the old + The new configuration system will still use the old matplotlibrc files by default. To switch to the experimental, - traited configuration, set USE_TRAITED_CONFIG=True in + traited configuration, set USE_TRAITED_CONFIG=True in config.__init__.py. 2007年07月29日 Changed default pcolor shading to flat; added aliases Modified: trunk/matplotlib/examples/axes_demo.py =================================================================== --- trunk/matplotlib/examples/axes_demo.py 2007年08月12日 06:08:36 UTC (rev 3700) +++ trunk/matplotlib/examples/axes_demo.py 2007年08月12日 07:21:47 UTC (rev 3701) @@ -7,7 +7,7 @@ t = arange(0.0, 10.0, dt) r = exp(-t[:1000]/0.05) # impulse response x = randn(len(t)) -s = conv(x,r)[:len(x)]*dt # colored noise +s = convolve(x,r)[:len(x)]*dt # colored noise # the main axes is subplot(111) by default plot(t, s) Modified: trunk/matplotlib/examples/colours.py =================================================================== --- trunk/matplotlib/examples/colours.py 2007年08月12日 06:08:36 UTC (rev 3700) +++ trunk/matplotlib/examples/colours.py 2007年08月12日 07:21:47 UTC (rev 3701) @@ -2,14 +2,12 @@ """ Some simple functions to generate colours. """ -from matplotlib.numerix import asarray, asum -from matplotlib.mlab import linspace +import numpy as npy from matplotlib.colors import colorConverter -from matplotlib.numerix import sum def pastel(colour, weight=2.4): """ Convert colour into a nice pastel shade""" - rgb = asarray(colorConverter.to_rgb(colour)) + rgb = npy.asarray(colorConverter.to_rgb(colour)) # scale colour maxc = max(rgb) if maxc < 1.0 and maxc > 0: @@ -17,7 +15,7 @@ scale = 1.0 / maxc rgb = rgb * scale # now decrease saturation - total = asum(rgb) + total = rgb.sum() slack = 0 for x in rgb: slack += 1.0 - x @@ -33,7 +31,7 @@ def get_colours(n): """ Return n pastel colours. """ - base = asarray([[1,0,0], [0,1,0], [0,0,1]]) + base = npy.asarray([[1,0,0], [0,1,0], [0,0,1]]) if n <= 3: return base[0:n] @@ -44,7 +42,7 @@ colours = [] for start in (0, 1): - for x in linspace(0, 1, needed[start]+2): + for x in npy.linspace(0, 1, needed[start]+2): colours.append((base[start] * (1.0 - x)) + (base[start+1] * x)) Modified: trunk/matplotlib/examples/psd_demo.py =================================================================== --- trunk/matplotlib/examples/psd_demo.py 2007年08月12日 06:08:36 UTC (rev 3700) +++ trunk/matplotlib/examples/psd_demo.py 2007年08月12日 07:21:47 UTC (rev 3701) @@ -8,7 +8,7 @@ nse = randn(len(t)) r = exp(-t/0.05) -cnse = conv(nse, r)*dt +cnse = convolve(nse, r)*dt cnse = cnse[:len(t)] s = 0.1*sin(2*pi*t) + cnse Modified: trunk/matplotlib/examples/scatter_demo.py =================================================================== --- trunk/matplotlib/examples/scatter_demo.py 2007年08月12日 06:08:36 UTC (rev 3700) +++ trunk/matplotlib/examples/scatter_demo.py 2007年08月12日 07:21:47 UTC (rev 3701) @@ -6,6 +6,5 @@ y = 0.9*rand(N) area = pi*(10 * rand(N))**2 # 0 to 10 point radiuses scatter(x,y,s=area, marker='^', c='r') -savefig('scatter_demo') show() Modified: trunk/matplotlib/lib/matplotlib/art3d.py =================================================================== --- trunk/matplotlib/lib/matplotlib/art3d.py 2007年08月12日 06:08:36 UTC (rev 3700) +++ trunk/matplotlib/lib/matplotlib/art3d.py 2007年08月12日 07:21:47 UTC (rev 3701) @@ -327,7 +327,7 @@ source = image._A w,h,p = source.shape X,Y = meshgrid(arange(w),arange(h)) - Z = zeros((w,h)) + Z = npy.zeros((w,h)) tX,tY,tZ = proj3d.transform(X.flat,Y.flat,Z.flat,M) tX = reshape(tX,(w,h)) tY = reshape(tY,(w,h)) Modified: trunk/matplotlib/lib/matplotlib/mlab.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mlab.py 2007年08月12日 06:08:36 UTC (rev 3700) +++ trunk/matplotlib/lib/matplotlib/mlab.py 2007年08月12日 07:21:47 UTC (rev 3701) @@ -7,41 +7,41 @@ * cohere - Coherence (normalized cross spectral density) - * conv - convolution - - * corrcoef - The matrix of correlation coefficients - * csd - Cross spectral density uing Welch's average periodogram * detrend -- Remove the mean or best fit line from an array - * find - Return the indices where some condition is true + * find - Return the indices where some condition is true; + numpy.nonzero is similar but more general. - * linspace -- Linear spaced array from min to max - - * hist -- Histogram - * polyfit - least squares best polynomial fit of x to y * polyval - evaluate a vector for a vector of polynomial coeffs * prctile - find the percentiles of a sequence - * prepca - Principal Component's Analysis + * prepca - Principal Component Analysis * psd - Power spectral density uing Welch's average periodogram * rk4 - A 4th order runge kutta integrator for 1D or ND systems + + The following are deprecated; please import directly from numpy + (with care--function signatures may differ): + * conv - convolution (numpy.convolve) + * corrcoef - The matrix of correlation coefficients + * hist -- Histogram (numpy.histogram) + * linspace -- Linear spaced array from min to max + * meshgrid + * trapz - trapeziodal integration (trapz(x,y) -> numpy.trapz(y,x)) * vander - the Vandermonde matrix - * trapz - trapeziodal integration - Functions that don't exist in matlab(TM), but are useful anyway: * cohere_pairs - Coherence over all pairs. This is not a matlab function, but we compute coherence a lot in my lab, and we - compute it for alot of pairs. This function is optimized to do + compute it for a lot of pairs. This function is optimized to do this efficiently by caching the direct FFTs. Credits: @@ -55,63 +55,54 @@ """ from __future__ import division -import sys, random, datetime, csv +import sys, datetime, csv, warnings import numpy as npy -from numpy import linspace, meshgrid -from matplotlib import verbose +from matplotlib import nxutils +from matplotlib import cbook -import numerix -import numerix as nx -import numerix.mlab -from numerix import linear_algebra -import nxutils - -from numerix import array, asarray, arange, divide, exp, arctan2, \ - multiply, transpose, ravel, repeat, resize, reshape, floor, ceil,\ - absolute, matrixmultiply, power, take, where, Float, Int, asum,\ - dot, convolve, pi, Complex, ones, zeros, diagonal, Matrix, nonzero, \ - log, searchsorted, concatenate, sort, ArrayType, clip, size, indices,\ - conjugate, typecode, iscontiguous - - -from numerix.mlab import hanning, cov, diff, svd, rand, std -from numerix.fft import fft, inverse_fft - -from cbook import iterable, is_string_like, to_filehandle, reversed - +# set is a new builtin function in 2.4; delete the following when +# support for 2.3 is dropped. try: set except NameError: from sets import Set as set +def linspace(*args, **kw): + warnings.warn("use numpy.linspace", DeprecationWarning) + return npy.linspace(*args, **kw) +def meshgrid(x,y): + warnings.warn("use numpy.meshgrid", DeprecationWarning) + return npy.meshgrid(x,y) + def mean(x, dim=None): - if len(x)==0: return None - elif dim is None: - return numerix.mlab.mean(x) - else: return numerix.mlab.mean(x, dim) + warnings.warn("Use numpy.mean(x) or x.mean()", DeprecationWarning) + if len(x)==0: return None + return npy.mean(x, axis=dim) def logspace(xmin,xmax,N): - return exp(linspace(log(xmin), log(xmax),Nh)) + return npy.exp(npy.linspace(npy.log(xmin), npy.log(xmax), N)) def _norm(x): "return sqrt(x dot x)" - return numerix.mlab.sqrt(dot(x,x)) + return npy.sqrt(npy.dot(x,x)) def window_hanning(x): "return x times the hanning window of len(x)" - return hanning(len(x))*x + return npy.hanning(len(x))*x def window_none(x): "No window function; simply return x" return x +#from numpy import convolve as conv def conv(x, y, mode=2): 'convolve x with y' - return convolve(x,y,mode) + warnings.warn("Use numpy.convolve(x, y, mode='full')", DeprecationWarning) + return npy.convolve(x,y,mode) def detrend(x, key=None): if key is None or key=='constant': @@ -119,27 +110,34 @@ elif key=='linear': return detrend_linear(x) +def demean(x, axis=0): + "Return x minus its mean along the specified axis" + x = npy.asarray(x) + if axis: + ind = [slice(None)] * axis + ind.append(npy.newaxis) + return x - x.mean(axis)[ind] + return x - x.mean(axis) + def detrend_mean(x): "Return x minus the mean(x)" - return x - mean(x) + return x - x.mean() def detrend_none(x): "Return x: no detrending" return x -def detrend_linear(x): - "Return x minus best fit line; 'linear' detrending " - - # I'm going to regress x on xx=range(len(x)) and return x - - # (b*xx+a). Now that I have polyfit working, I could convert the - # code here, but if it ain't broke, don't fix it! - xx = arange(float(len(x))) - X = transpose(array([xx]+[x])) - C = cov(X) +def detrend_linear(y): + "Return y minus best fit line; 'linear' detrending " + # This is faster than an algorithm based on linalg.lstsq. + x = npy.arange(len(y), dtype=npy.float_) + C = npy.cov(x, y, bias=1) b = C[0,1]/C[0,0] - a = mean(x) - b*mean(xx) - return x-(b*xx+a) + a = y.mean() - b*x.mean() + return y - (b*x + a) + + def psd(x, NFFT=256, Fs=2, detrend=detrend_none, window=window_hanning, noverlap=0): """ @@ -148,10 +146,13 @@ is detrended by function detrend and windowed by function window. noperlap gives the length of the overlap between segments. The absolute(fft(segment))**2 of each segment are averaged to compute Pxx, - with a scaling to correct for power loss due to windowing. Fs is - the sampling frequency. + with a scaling to correct for power loss due to windowing. - -- NFFT must be a power of 2 + Fs is the sampling frequency (samples per time unit). It is used + to calculate the Fourier frequencies, freqs, in cycles per time + unit. + + -- NFFT must be even; a power 2 is most efficient. -- detrend is a functions, unlike in matlab where it is a vector. -- window can be a function or a vector of length NFFT. To create window vectors see numpy.blackman, numpy.hamming, numpy.bartlett, @@ -166,46 +167,45 @@ Procedures, John Wiley & Sons (1986) """ - + # I think we could remove this condition without hurting anything. if NFFT % 2: - raise ValueError, 'NFFT must be a power of 2' + raise ValueError('NFFT must be even') - x = asarray(x) # make sure we're dealing with a numpy array + x = npy.asarray(x) # make sure we're dealing with a numpy array # zero pad x up to NFFT if it is shorter than NFFT if len(x)<NFFT: n = len(x) - x = resize(x, (NFFT,)) + x = npy.resize(x, (NFFT,)) # Can't use resize method. x[n:] = 0 - # for real x, ignore the negative frequencies if npy.iscomplexobj(x): numFreqs = NFFT else: numFreqs = NFFT//2+1 - if iterable(window): - assert(len(window) == NFFT) - windowVals = window + if cbook.iterable(window): + assert(len(window) == NFFT) + windowVals = window else: - windowVals = window(ones((NFFT,),typecode(x))) + windowVals = window(npy.ones((NFFT,),x.dtype)) step = NFFT-noverlap ind = range(0,len(x)-NFFT+1,step) n = len(ind) - Pxx = zeros((numFreqs,n), float) + Pxx = npy.zeros((numFreqs,n), npy.float_) # do the ffts of the slices for i in range(n): thisX = x[ind[i]:ind[i]+NFFT] - thisX = windowVals*detrend(thisX) - fx = absolute(fft(thisX))**2 - Pxx[:,i] = divide(fx[:numFreqs], norm(windowVals)**2) + thisX = windowVals * detrend(thisX) + fx = npy.absolute(npy.fft.fft(thisX))**2 + Pxx[:,i] = fx[:numFreqs] + if n>1: + Pxx = Pxx.mean(axis=1) # Scale the spectrum by the norm of the window to compensate for # windowing loss; see Bendat & Piersol Sec 11.5.2 - if n>1: - Pxx = mean(Pxx,1) + Pxx /= (npy.abs(windowVals)**2).sum() - freqs = Fs/NFFT*arange(numFreqs) - Pxx.shape = len(freqs), + freqs = Fs/NFFT * npy.arange(numFreqs) return Pxx, freqs @@ -221,7 +221,7 @@ correct for power loss due to windowing. Fs is the sampling frequency. - NFFT must be a power of 2 + NFFT must be even; a power of 2 is most efficient window can be a function or a vector of length NFFT. To create window vectors see numpy.blackman, numpy.hamming, numpy.bartlett, @@ -229,8 +229,6 @@ Returns the tuple Pxy, freqs - - Refs: Bendat & Piersol -- Random Data: Analysis and Measurement Procedures, John Wiley & Sons (1986) @@ -238,34 +236,34 @@ """ if NFFT % 2: - raise ValueError, 'NFFT must be a power of 2' + raise ValueError, 'NFFT must be even' - x = asarray(x) # make sure we're dealing with a numpy array - y = asarray(y) # make sure we're dealing with a numpy array + x = npy.asarray(x) # make sure we're dealing with a numpy array + y = npy.asarray(y) # make sure we're dealing with a numpy array # zero pad x and y up to NFFT if they are shorter than NFFT if len(x)<NFFT: n = len(x) - x = resize(x, (NFFT,)) + x = npy.resize(x, (NFFT,)) x[n:] = 0 if len(y)<NFFT: n = len(y) - y = resize(y, (NFFT,)) + y = npy.resize(y, (NFFT,)) y[n:] = 0 # for real x, ignore the negative frequencies if npy.iscomplexobj(x): numFreqs = NFFT else: numFreqs = NFFT//2+1 - if iterable(window): - assert(len(window) == NFFT) - windowVals = window + if cbook.iterable(window): + assert(len(window) == NFFT) + windowVals = window else: - windowVals = window(ones((NFFT,),typecode(x))) + windowVals = window(npy.ones((NFFT,), x.dtype)) step = NFFT-noverlap ind = range(0,len(x)-NFFT+1,step) n = len(ind) - Pxy = zeros((numFreqs,n), complex) + Pxy = npy.zeros((numFreqs,n), npy.complex_) # do the ffts of the slices for i in range(n): @@ -273,24 +271,107 @@ thisX = windowVals*detrend(thisX) thisY = y[ind[i]:ind[i]+NFFT] thisY = windowVals*detrend(thisY) - fx = fft(thisX) - fy = fft(thisY) - Pxy[:,i] = conjugate(fx[:numFreqs])*fy[:numFreqs] + fx = npy.fft.fft(thisX) + fy = npy.fft.fft(thisY) + Pxy[:,i] = npy.conjugate(fx[:numFreqs])*fy[:numFreqs] # Scale the spectrum by the norm of the window to compensate for # windowing loss; see Bendat & Piersol Sec 11.5.2 - if n>1: Pxy = mean(Pxy,1) - Pxy = divide(Pxy, norm(windowVals)**2) - freqs = Fs/NFFT*arange(numFreqs) - Pxy.shape = len(freqs), + if n>1: + Pxy = Pxy.mean(axis=1) + Pxy /= (npy.abs(windowVals)**2).sum() + freqs = Fs/NFFT*npy.arange(numFreqs) return Pxy, freqs +def specgram(x, NFFT=256, Fs=2, detrend=detrend_none, + window=window_hanning, noverlap=128): + """ + Compute a spectrogram of data in x. Data are split into NFFT + length segements and the PSD of each section is computed. The + windowing function window is applied to each segment, and the + amount of overlap of each segment is specified with noverlap. + + window can be a function or a vector of length NFFT. To create + window vectors see numpy.blackman, numpy.hamming, numpy.bartlett, + scipy.signal, scipy.signal.get_window etc. + + See psd for more info. (psd differs in the default overlap; + in returning the mean of the segment periodograms; and in not + returning times.) + + If x is real (i.e. non-Complex) only the positive spectrum is + given. If x is Complex then the complete spectrum is given. + + returns: + Pxx - 2-D array, columns are the periodograms of + successive segments + freqs - 1-D array of frequencies corresponding to + the rows in Pxx + t - 1-D array of times corresponding to midpoints of + segments. + + """ + x = npy.asarray(x) + assert(NFFT>noverlap) + #if npy.log(NFFT)/npy.log(2) != int(npy.log(NFFT)/npy.log(2)): + # raise ValueError, 'NFFT must be a power of 2' + if NFFT % 2: + raise ValueError('NFFT must be even') + + + # zero pad x up to NFFT if it is shorter than NFFT + if len(x)<NFFT: + n = len(x) + x = resize(x, (NFFT,)) + x[n:] = 0 + + + # for real x, ignore the negative frequencies + if npy.iscomplexobj(x): + numFreqs=NFFT + else: + numFreqs = NFFT//2+1 + + if cbook.iterable(window): + assert(len(window) == NFFT) + windowVals = npy.asarray(window) + else: + windowVals = window(npy.ones((NFFT,),x.dtype)) + step = NFFT-noverlap + ind = npy.arange(0,len(x)-NFFT+1,step) + n = len(ind) + Pxx = npy.zeros((numFreqs,n), npy.float_) + # do the ffts of the slices + + for i in range(n): + thisX = x[ind[i]:ind[i]+NFFT] + thisX = windowVals*detrend(thisX) + fx = npy.absolute(npy.fft.fft(thisX))**2 + Pxx[:,i] = fx[:numFreqs] + # Scale the spectrum by the norm of the window to compensate for + # windowing loss; see Bendat & Piersol Sec 11.5.2 + Pxx /= (npy.abs(windowVals)**2).sum() + t = 1/Fs*(ind+NFFT/2) + freqs = Fs/NFFT*npy.arange(numFreqs) + + if npy.iscomplexobj(x): + # center the frequency range at zero + freqs = npy.concatenate((freqs[NFFT/2:]-Fs,freqs[:NFFT/2])) + Pxx = npy.concatenate((Pxx[NFFT/2:,:],Pxx[:NFFT/2,:]),0) + + return Pxx, freqs, t + + + +_coh_error = """Coherence is calculated by averaging over NFFT +length segments. Your signal is too short for your choice of NFFT. +""" def cohere(x, y, NFFT=256, Fs=2, detrend=detrend_none, window=window_hanning, noverlap=0): """ - cohere the coherence between x and y. Coherence is the normalized + The coherence between x and y. Coherence is the normalized cross spectral density Cxy = |Pxy|^2/(Pxx*Pyy) @@ -305,59 +386,33 @@ """ if len(x)<2*NFFT: - raise RuntimeError('Coherence is calculated by averaging over NFFT length segments. Your signal is too short for your choice of NFFT') + raise ValueError(_coh_error) Pxx, f = psd(x, NFFT, Fs, detrend, window, noverlap) Pyy, f = psd(y, NFFT, Fs, detrend, window, noverlap) Pxy, f = csd(x, y, NFFT, Fs, detrend, window, noverlap) - Cxy = divide(absolute(Pxy)**2, Pxx*Pyy) - Cxy.shape = len(f), + Cxy = npy.divide(npy.absolute(Pxy)**2, Pxx*Pyy) + Cxy.shape = (len(f),) return Cxy, f def corrcoef(*args): """ corrcoef(X) where X is a matrix returns a matrix of correlation - coefficients for each numrows observations and numcols variables. + coefficients for the columns of X. - corrcoef(x,y) where x and y are vectors returns the matrix or + corrcoef(x,y) where x and y are vectors returns the matrix of correlation coefficients for x and y. - Numeric arrays can be real or complex + Numpy arrays can be real or complex The correlation matrix is defined from the covariance matrix C as r(i,j) = C[i,j] / sqrt(C[i,i]*C[j,j]) """ + warnings.warn("Use numpy.corrcoef", DeprecationWarning) + kw = dict(rowvar=False) + return npy.corrcoef(*args, **kw) - - if len(args)==2: - X = transpose(array([args[0]]+[args[1]])) - elif len(args)==1: - X = asarray(args[0]) - else: - raise RuntimeError, 'Only expecting 1 or 2 arguments' - - - C = cov(X) - - if len(args)==2: - d = resize(diagonal(C), (2,1)) - denom = numerix.mlab.sqrt(matrixmultiply(d,transpose(d))) - else: - dc = diagonal(C) - N = len(dc) - shape = N,N - vi = resize(dc, shape) - denom = numerix.mlab.sqrt(vi*transpose(vi)) # element wise multiplication - - - r = divide(C,denom) - try: return r.real - except AttributeError: return r - - - - def polyfit(x,y,N): """ @@ -385,6 +440,8 @@ p = (XT*X)^-1 * XT * y where XT is the transpose of X and -1 denotes the inverse. + Numerically, however, this is not a good method, so we use + numpy.linalg.lstsq. For more info, see http://mathworld.wolfram.com/LeastSquaresFittingPolynomial.html, @@ -394,19 +451,20 @@ See also polyval """ + x = npy.asarray(x, dtype=npy.float_) + #y = npy.asarray(y, dtype=npy.float_) + #y.shape = (len(y),1) + #X = npy.matrix(npy.vander(x, N+1)) + #Xt = npy.matrix(X.transpose()) + #c = npy.array(npy.linalg.inv(Xt*X)*Xt*y) # convert back to array + #c.shape = (N+1,) + #return c + X = npy.vander(x, N+1) + return npy.linalg.lstsq(X, y)[0] - x = asarray(x)+0. - y = asarray(y)+0. - y = reshape(y, (len(y),1)) - X = Matrix(vander(x, N+1)) - Xt = Matrix(transpose(X)) - c = array(linear_algebra.inverse(Xt*X)*Xt*y) # convert back to array - c.shape = (N+1,) - return c - def polyval(p,x): """ y = polyval(p,x) @@ -423,11 +481,11 @@ See also polyfit """ - x = asarray(x)+0. - p = reshape(p, (len(p),1)) - X = vander(x,len(p)) - y = matrixmultiply(X,p) - return reshape(y, x.shape) + x = npy.asarray(x, dtype=npy.float_) + p = npy.asarray(p, dtype=npy.float_).reshape((len(p),1)) + X = npy.vander(x,len(p)) + y = npy.dot(X,p) + return y.reshape(x.shape) def vander(x,N=None): @@ -439,14 +497,10 @@ None it defaults to len(x). """ - if N is None: N=len(x) - X = ones( (len(x),N), typecode(x)) - for i in range(N-1): - X[:,i] = x**(N-i-1) - return X + warnings.warn("Use numpy.vander()", DeprecationWarning) + return npy.vander(x, N) - def donothing_callback(*args): pass @@ -523,7 +577,7 @@ # zero pad if X is too short if numRows < NFFT: tmp = X - X = zeros( (NFFT, numCols), typecode(X)) + X = npy.zeros( (NFFT, numCols), X.dtype) X[:numRows,:] = tmp del tmp @@ -544,11 +598,11 @@ # cache the FFT of every windowed, detrended NFFT length segement # of every channel. If preferSpeedOverMemory, cache the conjugate # as well - if iterable(window): - assert(len(window) == NFFT) - windowVals = window + if cbook.iterable(window): + assert(len(window) == NFFT) + windowVals = window else: - windowVals = window(ones((NFFT,), typecode(X))) + windowVals = window(npy.ones((NFFT,), typecode(X))) ind = range(0, numRows-NFFT+1, NFFT-noverlap) numSlices = len(ind) FFTSlices = {} @@ -558,7 +612,7 @@ normVal = norm(windowVals)**2 for iCol in allColumns: progressCallback(i/Ncols, 'Cacheing FFTs') - Slices = zeros( (numSlices,numFreqs), complex) + Slices = npy.zeros( (numSlices,numFreqs), dtype=npy.complex_) for iSlice in slices: thisSlice = X[ind[iSlice]:ind[iSlice]+NFFT, iCol] thisSlice = windowVals*detrend(thisSlice) @@ -567,7 +621,7 @@ FFTSlices[iCol] = Slices if preferSpeedOverMemory: FFTConjSlices[iCol] = conjugate(Slices) - Pxx[iCol] = divide(mean(absolute(Slices)**2), normVal) + Pxx[iCol] = npy.divide(npy.mean(absolute(Slices)**2), normVal) del Slices, ind, windowVals # compute the coherences and phases for all pairs using the @@ -584,47 +638,45 @@ if preferSpeedOverMemory: Pxy = FFTSlices[i] * FFTConjSlices[j] else: - Pxy = FFTSlices[i] * conjugate(FFTSlices[j]) - if numSlices>1: Pxy = mean(Pxy) - Pxy = divide(Pxy, normVal) - Cxy[(i,j)] = divide(absolute(Pxy)**2, Pxx[i]*Pxx[j]) - Phase[(i,j)] = arctan2(Pxy.imag, Pxy.real) + Pxy = FFTSlices[i] * npy.conjugate(FFTSlices[j]) + if numSlices>1: Pxy = npy.mean(Pxy) + Pxy = npy.divide(Pxy, normVal) + Cxy[(i,j)] = npy.divide(npy.absolute(Pxy)**2, Pxx[i]*Pxx[j]) + Phase[(i,j)] = npy.arctan2(Pxy.imag, Pxy.real) - freqs = Fs/NFFT*arange(numFreqs) + freqs = Fs/NFFT*npy.arange(numFreqs) if returnPxx: - return Cxy, Phase, freqs, Pxx + return Cxy, Phase, freqs, Pxx else: - return Cxy, Phase, freqs + return Cxy, Phase, freqs def entropy(y, bins): - """ - Return the entropy of the data in y + """ + Return the entropy of the data in y - \sum p_i log2(p_i) where p_i is the probability of observing y in - the ith bin of bins. bins can be a number of bins or a range of - bins; see hist + \sum p_i log2(p_i) where p_i is the probability of observing y in + the ith bin of bins. bins can be a number of bins or a range of + bins; see numpy.histogram - Compare S with analytic calculation for a Gaussian - x = mu + sigma*randn(200000) - Sanalytic = 0.5 * ( 1.0 + log(2*pi*sigma**2.0) ) + Compare S with analytic calculation for a Gaussian + x = mu + sigma*randn(200000) + Sanalytic = 0.5 * ( 1.0 + log(2*pi*sigma**2.0) ) - """ + """ + n,bins = npy.histogram(y, bins) + n = n.astype(npy.float_) + n = npy.take(n, npy.nonzero(n)[0]) # get the positive - n,bins = hist(y, bins) - n = n.astype(float) + p = npy.divide(n, len(y)) - n = npy.take(n, npy.nonzero(n)[0]) # get the positive + delta = bins[1]-bins[0] + S = -1.0*npy.sum(p*log(p)) + log(delta) + #S = -1.0*npy.sum(p*log(p)) + return S - p = divide(n, len(y)) - - delta = bins[1]-bins[0] - S = -1.0*asum(p*log(p)) + log(delta) - #S = -1.0*asum(p*log(p)) - return S - def hist(y, bins=10, normed=0): """ Return the histogram of y with bins equally sized bins. If bins @@ -638,226 +690,174 @@ If y has rank>1, it will be raveled. If y is masked, only the unmasked values will be used. Credits: the Numeric 22 documentation - - - """ - if hasattr(y, 'compressed'): - y = y.compressed() - else: - y = asarray(y) - if len(y.shape)>1: y = ravel(y) + warnings.warn("Use numpy.histogram()", DeprecationWarning) + return npy.histogram(y, bins=bins, range=None, normed=normed) - if not iterable(bins): - ymin, ymax = min(y), max(y) - if ymin==ymax: - ymin -= 0.5 - ymax += 0.5 - - if bins==1: bins=ymax - dy = (ymax-ymin)/bins - bins = ymin + dy*arange(bins) - - - n = searchsorted(sort(y), bins) - n = diff(concatenate([n, [len(y)]])) - if normed: - db = bins[1]-bins[0] - return 1/(len(y)*db)*n, bins - else: - return n, bins - - def normpdf(x, *args): - "Return the normal pdf evaluated at x; args provides mu, sigma" - mu, sigma = args - return 1/(numerix.mlab.sqrt(2*pi)*sigma)*exp(-0.5 * (1/sigma*(x - mu))**2) + "Return the normal pdf evaluated at x; args provides mu, sigma" + mu, sigma = args + return 1/(npy.sqrt(2*npy.pi)*sigma)*npy.exp(-0.5 * (1/sigma*(x - mu))**2) def levypdf(x, gamma, alpha): - "Returm the levy pdf evaluated at x for params gamma, alpha" + "Returm the levy pdf evaluated at x for params gamma, alpha" - N = len(x) + N = len(x) - if N%2 != 0: - raise ValueError, 'x must be an event length array; try\n' + \ - 'x = linspace(minx, maxx, N), where N is even' + if N%2 != 0: + raise ValueError, 'x must be an event length array; try\n' + \ + 'x = npy.linspace(minx, maxx, N), where N is even' - dx = x[1]-x[0] + dx = x[1]-x[0] - f = 1/(N*dx)*arange(-N/2, N/2, float) + f = 1/(N*dx)*npy.arange(-N/2, N/2, npy.float_) - ind = concatenate([arange(N/2, N, int), - arange(0, N/2, int)]) - df = f[1]-f[0] - cfl = exp(-gamma*absolute(2*pi*f)**alpha) + ind = npy.concatenate([npy.arange(N/2, N, int), + npy.arange(0, N/2, int)]) + df = f[1]-f[0] + cfl = exp(-gamma*npy.absolute(2*pi*f)**alpha) - px = fft(take(cfl,ind)*df).astype(float) - return take(px, ind) + px = npy.fft.fft(npy.take(cfl,ind)*df).astype(npy.float_) + return npy.take(px, ind) - - - - def find(condition): - "Return the indices where condition is true" - res, = npy.nonzero(condition) - return res + "Return the indices where ravel(condition) is true" + res, = npy.nonzero(npy.ravel(condition)) + return res - - def trapz(x, y): - if len(x)!=len(y): - raise ValueError, 'x and y must have the same length' - if len(x)<2: - raise ValueError, 'x and y must have > 1 element' - return asum(0.5*diff(x)*(y[1:]+y[:-1])) - - - -def longest_contiguous_ones(x): """ - return the indicies of the longest stretch of contiguous ones in x, - assuming x is a vector of zeros and ones. + Trapezoidal integral of y(x). """ - if len(x)==0: return array([]) + warnings.warn("Use numpy.trapz(y,x) instead of trapz(x,y)", DeprecationWarning) + return npy.trapz(y, x) + #if len(x)!=len(y): + # raise ValueError, 'x and y must have the same length' + #if len(x)<2: + # raise ValueError, 'x and y must have > 1 element' + #return npy.sum(0.5*npy.diff(x)*(y[1:]+y[:-1])) - ind = find(x==0) - if len(ind)==0: return arange(len(x)) - if len(ind)==len(x): return array([]) - y = zeros( (len(x)+2,), typecode(x)) - y[1:-1] = x - dif = diff(y) - up = find(dif == 1); - dn = find(dif == -1); - ind = find( dn-up == max(dn - up)) - ind = arange(take(up, ind), take(dn, ind)) - return ind - - -def longest_ones(x): +def longest_contiguous_ones(x): """ - return the indicies of the longest stretch of contiguous ones in x, + return the indices of the longest stretch of contiguous ones in x, assuming x is a vector of zeros and ones. - If there are two equally long stretches, pick the first + """ - x = asarray(x) - if len(x)==0: return array([]) + x = npy.ravel(x) + if len(x)==0: + return npy.array([]) - #print 'x', x - ind = find(x==0) - if len(ind)==0: return arange(len(x)) - if len(ind)==len(x): return array([]) + ind = (x==0).nonzero()[0] + if len(ind)==0: + return npy.arange(len(x)) + if len(ind)==len(x): + return npy.array([]) - y = zeros( (len(x)+2,), int) + y = npy.zeros( (len(x)+2,), x.dtype) y[1:-1] = x - d = diff(y) - #print 'd', d - up = find(d == 1); - dn = find(d == -1); + dif = npy.diff(y) + up = (dif == 1).nonzero()[0]; + dn = (dif == -1).nonzero()[0]; + i = (dn-up == max(dn - up)).nonzero()[0][0] + ind = npy.arange(up[i], dn[i]) - #print 'dn', dn, 'up', up, - ind = find( dn-up == max(dn - up)) - # pick the first - if iterable(ind): ind = ind[0] - ind = arange(up[ind], dn[ind]) - return ind +def longest_ones(x): + '''alias for longest_contiguous_ones''' + return longest_contiguous_ones(x) + def prepca(P, frac=0): """ Compute the principal components of P. P is a numVars x - numObservations numeric array. frac is the minimum fraction of - variance that a component must contain to be included + numObs array. frac is the minimum fraction of + variance that a component must contain to be included. Return value are - Pcomponents : a num components x num observations numeric array + Pcomponents : a numVars x numObs array Trans : the weights matrix, ie, Pcomponents = Trans*P fracVar : the fraction of the variance accounted for by each component returned + + A similar function of the same name was in the Matlab (TM) + R13 Neural Network Toolbox but is not found in later versions; + its successor seems to be called "processpcs". """ - U,s,v = svd(P) + U,s,v = npy.linalg.svd(P) varEach = s**2/P.shape[1] - totVar = asum(varEach) - fracVar = divide(varEach,totVar) - ind = int(asum(fracVar>=frac)) - + totVar = varEach.sum() + fracVar = varEach/totVar + ind = slice((fracVar>=frac).sum()) # select the components that are greater - Trans = transpose(U[:,:ind]) + Trans = U[:,ind].transpose() # The transformed data - Pcomponents = matrixmultiply(Trans,P) - return Pcomponents, Trans, fracVar[:ind] + Pcomponents = npy.dot(Trans,P) + return Pcomponents, Trans, fracVar[ind] def prctile(x, p = (0.0, 25.0, 50.0, 75.0, 100.0)): """ Return the percentiles of x. p can either be a sequence of - percentil values or a scalar. If p is a sequence the i-th element - of the return sequence is the p(i)-th percentile of x - + percentile values or a scalar. If p is a sequence the i-th element + of the return sequence is the p(i)-th percentile of x. + If p is a scalar, the largest value of x less than or equal + to the p percentage point in the sequence is returned. """ - x = sort(ravel(x)) + x = npy.ravel(x) + x.sort() Nx = len(x) - if not iterable(p): + if not cbook.iterable(p): return x[int(p*Nx/100.0)] - p = multiply(array(p), Nx/100.0) + p = npy.asarray(p)* Nx/100.0 ind = p.astype(int) - ind = where(ind>=Nx, Nx-1, ind) - return take(x, ind) + ind = npy.where(ind>=Nx, Nx-1, ind) + return x.take(ind) def prctile_rank(x, p): - """ - return the for each element in x, return the rank 0..len(p) . Eg - if p=(25, 50, 75), the return value will be a len(x) array with - values in [0,1,2,3] where 0 indicates the value is less than the - 25th percentile, 1 indicates the value is >= the 25th and < 50th - percentile, ... and 3 indicates the value is above the 75th - percentile cutoff + """ + return the for each element in x, return the rank 0..len(p) . Eg + if p=(25, 50, 75), the return value will be a len(x) array with + values in [0,1,2,3] where 0 indicates the value is less than the + 25th percentile, 1 indicates the value is >= the 25th and < 50th + percentile, ... and 3 indicates the value is above the 75th + percentile cutoff - p is either an array of percentiles in [0..100] or a scalar which - indicates how many quantiles of data you want ranked - """ + p is either an array of percentiles in [0..100] or a scalar which + indicates how many quantiles of data you want ranked + """ - if not iterable(p): - p = nx.arange(100./p, 100., 100./p) + if not cbook.iterable(p): + p = npy.arange(100.0/p, 100.0, 100.0/p) + else: + p = npy.asarray(p) - if max(p)<=1 or min(p)<0 or max(p)>100: - raise ValueError('percentiles should be in range 0..100, not 0..1') + if p.max()<=1 or p.min()<0 or p.max()>100: + raise ValueError('percentiles should be in range 0..100, not 0..1') - ptiles = prctile(x, p) - return nx.searchsorted(ptiles, x) + ptiles = prctile(x, p) + return npy.searchsorted(ptiles, x) def center_matrix(M, dim=0): """ Return the matrix M with each row having zero mean and unit std - if dim=1, center columns rather than rows + if dim=1 operate on columns instead of rows. (dim is opposite + to the numpy axis kwarg.) """ - # todo: implement this w/o loop. Allow optional arg to specify - # dimension to remove the mean from - if dim==1: M = transpose(M) - M = array(M, float) - if len(M.shape)==1 or M.shape[0]==1 or M.shape[1]==1: - M = M-mean(M) - sigma = std(M) - if sigma>0: - M = divide(M, sigma) - if dim==1: M=transpose(M) - return M - - for i in range(M.shape[0]): - M[i] -= mean(M[i]) - sigma = std(M[i]) - if sigma>0: - M[i] = divide(M[i], sigma) - if dim==1: M=transpose(M) + M = npy.asarray(M, npy.float_) + if dim: + M = (M - M.mean(axis=0)) / M.std(axis=0) + else: + M = (M - M.mean(axis=1)[:,npy.newaxis]) + M = M / M.std(axis=1)[:,npy.newaxis] return M @@ -895,101 +895,35 @@ If you have access to scipy, you should probably be using the - scipy.integrate tools rather than this function + scipy.integrate tools rather than this function. """ try: Ny = len(y0) except TypeError: - yout = zeros( (len(t),), float) + yout = npy.zeros( (len(t),), npy.float_) else: - yout = zeros( (len(t), Ny), float) + yout = npy.zeros( (len(t), Ny), npy.float_) yout[0] = y0 i = 0 - for i in arange(len(t)-1): + for i in npy.arange(len(t)-1): thist = t[i] dt = t[i+1] - thist dt2 = dt/2.0 y0 = yout[i] - k1 = asarray(derivs(y0, thist)) - k2 = asarray(derivs(y0 + dt2*k1, thist+dt2)) - k3 = asarray(derivs(y0 + dt2*k2, thist+dt2)) - k4 = asarray(derivs(y0 + dt*k3, thist+dt)) + k1 = npy.asarray(derivs(y0, thist)) + k2 = npy.asarray(derivs(y0 + dt2*k1, thist+dt2)) + k3 = npy.asarray(derivs(y0 + dt2*k2, thist+dt2)) + k4 = npy.asarray(derivs(y0 + dt*k3, thist+dt)) yout[i+1] = y0 + dt/6.0*(k1 + 2*k2 + 2*k3 + k4) return yout - - -def specgram(x, NFFT=256, Fs=2, detrend=detrend_none, - window=window_hanning, noverlap=128): - """ - Compute a spectrogram of data in x. Data are split into NFFT - length segements and the PSD of each section is computed. The - windowing function window is applied to each segment, and the - amount of overlap of each segment is specified with noverlap. - - window can be a function or a vector of length NFFT. To create - window vectors see numpy.blackman, numpy.hamming, numpy.bartlett, - scipy.signal, scipy.signal.get_window etc. - - - See pdf for more info. - - If x is real (i.e. non-Complex) only the positive spectrum is - given. If x is Complex then the complete spectrum is given. - - The returned times are the midpoints of the intervals over which - the ffts are calculated - """ - x = asarray(x) - assert(NFFT>noverlap) - if log(NFFT)/log(2) != int(log(NFFT)/log(2)): - raise ValueError, 'NFFT must be a power of 2' - - # zero pad x up to NFFT if it is shorter than NFFT - if len(x)<NFFT: - n = len(x) - x = resize(x, (NFFT,)) - x[n:] = 0 - - - # for real x, ignore the negative frequencies - if npy.iscomplexobj(x): numFreqs=NFFT - else: numFreqs = NFFT//2+1 - - if iterable(window): - assert(len(window) == NFFT) - windowVals = window - else: - windowVals = window(ones((NFFT,),typecode(x))) - step = NFFT-noverlap - ind = arange(0,len(x)-NFFT+1,step) - n = len(ind) - Pxx = zeros((numFreqs,n), float) - # do the ffts of the slices - - for i in range(n): - thisX = x[ind[i]:ind[i]+NFFT] - thisX = windowVals*detrend(thisX) - fx = absolute(fft(thisX))**2 - # Scale the spectrum by the norm of the window to compensate for - # windowing loss; see Bendat & Piersol Sec 11.5.2 - Pxx[:,i] = divide(fx[:numFreqs], norm(windowVals)**2) - t = 1/Fs*(ind+NFFT/2) - freqs = Fs/NFFT*arange(numFreqs) - - if npy.iscomplexobj(x): - freqs = concatenate((freqs[NFFT/2:]-Fs,freqs[:NFFT/2])) - Pxx = concatenate((Pxx[NFFT/2:,:],Pxx[:NFFT/2,:]),0) - - return Pxx, freqs, t - def bivariate_normal(X, Y, sigmax=1.0, sigmay=1.0, mux=0.0, muy=0.0, sigmaxy=0.0): """ @@ -1002,7 +936,8 @@ rho = sigmaxy/(sigmax*sigmay) z = Xmu**2/sigmax**2 + Ymu**2/sigmay**2 - 2*rho*Xmu*Ymu/(sigmax*sigmay) - return 1.0/(2*pi*sigmax*sigmay*numerix.mlab.sqrt(1-rho**2)) * exp( -z/(2*(1-rho**2))) + denom = 2*npy.pi*sigmax*sigmay*npy.sqrt(1-rho**2) + return npy.exp( -z/(2*(1-rho**2))) / denom @@ -1014,37 +949,22 @@ where x and y are the indices into Z and z are the values of Z at those indices. x,y,z are 1D arrays """ + X,Y = npy.indices(z.shape) + return X[Cond], Y[Cond], Z[Cond] - M,N = Z.shape - z = ravel(Z) - ind, = npy.nonzero( ravel(Cond) ) - - x = arange(M); x.shape = M,1 - X = repeat(x, N, 1) - x = ravel(X) - - y = arange(N); y.shape = 1,N - Y = repeat(y, M) - y = ravel(Y) - - x = take(x, ind) - y = take(y, ind) - z = take(z, ind) - return x,y,z - def get_sparse_matrix(M,N,frac=0.1): 'return a MxN sparse matrix with frac elements randomly filled' - data = zeros((M,N))*0. + data = npy.zeros((M,N))*0. for i in range(int(M*N*frac)): - x = random.randint(0,M-1) - y = random.randint(0,N-1) - data[x,y] = rand() + x = npy.random.randint(0,M-1) + y = npy.random.randint(0,N-1) + data[x,y] = npy.random.rand() return data def dist(x,y): 'return the distance between two points' d = x-y - return numerix.mlab.sqrt(dot(d,d)) + return npy.sqrt(npy.dot(d,d)) def dist_point_to_segment(p, s0, s1): """ @@ -1055,17 +975,17 @@ This algorithm from http://softsurfer.com/Archive/algorithm_0102/algorithm_0102.htm#Distance%20to%20Ray%20or%20Segment """ - p = asarray(p, float) - s0 = asarray(s0, float) - s1 = asarray(s1, float) + p = npy.asarray(p, npy.float_) + s0 = npy.asarray(s0, npy.float_) + s1 = npy.asarray(s1, npy.float_) v = s1 - s0 w = p - s0 - c1 = dot(w,v); + c1 = npy.dot(w,v); if ( c1 <= 0 ): return dist(p, s0); - c2 = dot(v,v) + c2 = npy.dot(v,v) if ( c2 <= c1 ): return dist(p, s1); @@ -1076,7 +996,7 @@ def segments_intersect(s1, s2): """ Return True if s1 and s2 intersect. - s1 and s2 are defines as + s1 and s2 are defined as s1: (x1, y1), (x2, y2) s2: (x3, y3), (x4, y4) @@ -1104,29 +1024,33 @@ """ Compute an FFT phase randomized surrogate of x """ - if iterable(window): - x=window*detrend(x) + if cbook.iterable(window): + x=window*detrend(x) else: - x = window(detrend(x)) - z = fft(x) - a = 2.*pi*1j - phase = a*rand(len(x)) - z = z*exp(phase) - return inverse_fft(z).real + x = window(detrend(x)) + z = npy.fft.fft(x) + a = 2.*npy.pi*1j + phase = a * npy.random.rand(len(x)) + z = z*npy.exp(phase) + return npy.fft.ifft(z).real def liaupunov(x, fprime): - """ - x is a very long trajectory from a map, and fprime returns the - derivative of x. Return lambda = 1/n\sum ln|fprime(x_i)|. See Sec - 10.5 Strogatz (1994)"Nonlinear Dynamics and Chaos". - """ - return mean(log(fprime(x))) + """ + x is a very long trajectory from a map, and fprime returns the + derivative of x. Return lambda = 1/n\sum ln|fprime(x_i)|. See Sec + 10.5 Strogatz (1994)"Nonlinear Dynamics and Chaos". + See also http://en.wikipedia.org/wiki/Lyapunov_exponent. + What the function here calculates may not be what you really want; + caveat emptor. + It also seems that this function's name is badly misspelled. + """ + return npy.mean(npy.log(npy.absolute(fprime(x)))) class FIFOBuffer: """ A FIFO queue to hold incoming x, y data in a rotating buffer using - numerix arrrays under the hood. It is assumed that you will call + numpy arrays under the hood. It is assumed that you will call asarrays much less frequently than you add data to the queue -- otherwise another data structure will be faster @@ -1138,13 +1062,15 @@ the dataLim will be updated as new data come in TODI: add a grow method that will extend nmax + + mlab seems like the wrong place for this class. """ def __init__(self, nmax): 'buffer up to nmax points' - self._xa = nx.zeros((nmax,), typecode=float) - self._ya = nx.zeros((nmax,), typecode=float) - self._xs = nx.zeros((nmax,), typecode=float) - self._ys = nx.zeros((nmax,), typecode=float) + self._xa = npy.zeros((nmax,), npy.float_) + self._ya = npy.zeros((nmax,), npy.float_) + self._xs = npy.zeros((nmax,), npy.float_) + self._ys = npy.zeros((nmax,), npy.float_) self._ind = 0 self._nmax = nmax self.dataLim = None @@ -1157,17 +1083,17 @@ def add(self, x, y): 'add scalar x and y to the queue' if self.dataLim is not None: - xys = ((x,y),) - self.dataLim.update(xys, -1) #-1 means use the default ignore setting + xys = ((x,y),) + self.dataLim.update(xys, -1) #-1 means use the default ignore setting ind = self._ind % self._nmax #print 'adding to fifo:', ind, x, y self._xs[ind] = x self._ys[ind] = y for N,funcs in self.callbackd.items(): - if (self._ind%N)==0: - for func in funcs: - func(self) + if (self._ind%N)==0: + for func in funcs: + func(self) self._ind += 1 @@ -1202,14 +1128,9 @@ def movavg(x,n): 'compute the len(n) moving average of x' - n = int(n) - N = len(x) - assert(N>n) - y = zeros(N-(n-1),float) - for i in range(n): - y += x[i:N-(n-1)+i] - y /= float(n) - return y + w = npy.empty((n,), dtype=npy.float_) + w[:] = 1.0/n + return npy.convolve(x, w, mode='valid') def save(fname, X, fmt='%.18e',delimiter=' '): """ @@ -1231,7 +1152,7 @@ comma-separated values """ - if is_string_like(fname): + if cbook.is_string_like(fname): if fname.endswith('.gz'): import gzip fh = gzip.open(fname,'wb') @@ -1243,9 +1164,9 @@ raise ValueError('fname must be a string or file handle') - X = asarray(X) + X = npy.asarray(X) origShape = None - if len(X.shape)==1: + if X.ndim == 1: origShape = X.shape X.shape = len(X), 1 for row in X: @@ -1267,8 +1188,7 @@ fname can be a filename or a file handle. Support for gzipped files is automatic, if the filename ends in .gz - matfile data is not currently supported, but see - Nigel Wade's matfile ftp://ion.le.ac.uk/matfile/matfile.tar.gz + matfile data is not supported; use scipy.io.mio module Example usage: @@ -1308,7 +1228,7 @@ """ if converters is None: converters = {} - fh = to_filehandle(fname) + fh = cbook.to_filehandle(fname) X = [] converterseq = None @@ -1317,20 +1237,22 @@ line = line[:line.find(comments)].strip() if not len(line): continue if converterseq is None: - converterseq = [converters.get(j,float) for j,val in enumerate(line.split(delimiter))] + converterseq = [converters.get(j,float) + for j,val in enumerate(line.split(delimiter))] if usecols is not None: vals = line.split(delimiter) row = [converterseq[j](vals[j]) for j in usecols] else: - row = [converterseq[j](val) for j,val in enumerate(line.split(delimiter))] + row = [converterseq[j](val) + for j,val in enumerate(line.split(delimiter))] thisLen = len(row) X.append(row) - X = array(X, float) + X = npy.array(X, npy.float_) r,c = X.shape if r==1 or c==1: - X.shape = max([r,c]), - if unpack: return transpose(X) + X.shape = max(r,c), + if unpack: X.transpose() else: return X def csv2rec(fname, comments='#', skiprows=0, checkrows=5, delimiter=',', @@ -1360,20 +1282,16 @@ converterd, if not None, is a dictionary mapping column number or munged column name to a converter function - See examples/loadrec.py """ - - if converterd is None: converterd = dict() import dateutil.parser parsedate = dateutil.parser.parse - - fh = to_filehandle(fname) + fh = cbook.to_filehandle(fname) reader = csv.reader(fh, delimiter=delimiter) def process_skiprows(reader): @@ -1386,8 +1304,6 @@ process_skiprows(reader) - - def get_func(item, func): # promote functions in this order funcmap = {int:float, float:dateutil.parser.parse, dateutil.parser.parse:str} @@ -1420,9 +1336,7 @@ converters[j] = func return converters - # Get header and remove invalid characters - needheader = names is None if needheader: headers = reader.next() @@ -1445,8 +1359,6 @@ names.append(item) seen[item] = cnt+1 - - # get the converter functions by inspecting checkrows converters = get_converters(reader) if converters is None: @@ -1497,10 +1409,10 @@ Icelandic Meteorological Office, March 2006 halldor at vedur.is) """ # Cast key variables as float. - x=nx.asarray(x, float) - y=nx.asarray(y, float) + x=npy.asarray(x, npy.float_) + y=npy.asarray(y, npy.float_) - yp=nx.zeros(y.shape, float) + yp=npy.zeros(y.shape, npy.float_) dx=x[1:] - x[:-1] dy=y[1:] - y[:-1] @@ -1529,7 +1441,7 @@ The interpolation method is described in the article A CONSISTENTLY WELL BEHAVED METHOD OF INTERPOLATION by Russell W. Stineman. The article appeared in the July 1980 issue of - Creative computing with a note from the editor stating that while + Creative Computing with a note from the editor stating that while they were not an academic journal but once in a while something serious @@ -1555,18 +1467,18 @@ """ # Cast key variables as float. - x=nx.asarray(x, float) - y=nx.asarray(y, float) + x=npy.asarray(x, npy.float_) + y=npy.asarray(y, npy.float_) assert x.shape == y.shape N=len(y) if yp is None: yp = slopes(x,y) else: - yp=nx.asarray(yp, float) + yp=npy.asarray(yp, npy.float_) - xi=nx.asarray(xi, float) - yi=nx.zeros(xi.shape, float) + xi=npy.asarray(xi, npy.float_) + yi=npy.zeros(xi.shape, npy.float_) # calculate linear slopes dx = x[1:] - x[:-1] @@ -1575,83 +1487,39 @@ # find the segment each xi is in # this line actually is the key to the efficiency of this implementation - idx = nx.searchsorted(x[1:-1], xi) + idx = npy.searchsorted(x[1:-1], xi) # now we have generally: x[idx[j]] <= xi[j] <= x[idx[j]+1] # except at the boundaries, where it may be that xi[j] < x[0] or xi[j] > x[-1] # the y-values that would come out from a linear interpolation: - sidx = nx.take(s, idx) - xidx = nx.take(x, idx) - yidx = nx.take(y, idx) - xidxp1 = nx.take(x, idx+1) + sidx = s.take(idx) + xidx = x.take(idx) + yidx = y.take(idx) + xidxp1 = x.take(idx+1) yo = yidx + sidx * (xi - xidx) # the difference that comes when using the slopes given in yp - dy1 = (nx.take(yp, idx)- sidx) * (xi - xidx) # using the yp slope of the left point - dy2 = (nx.take(yp, idx+1)-sidx) * (xi - xidxp1) # using the yp slope of the right point + dy1 = (yp.take(idx)- sidx) * (xi - xidx) # using the yp slope of the left point + dy2 = (yp.take(idx+1)-sidx) * (xi - xidxp1) # using the yp slope of the right point dy1dy2 = dy1*dy2 # The following is optimized for Python. The solution actually # does more calculations than necessary but exploiting the power # of numpy, this is far more efficient than coding a loop by hand # in Python - yi = yo + dy1dy2 * nx.choose(nx.array(nx.sign(dy1dy2), nx.int32)+1, + yi = yo + dy1dy2 * npy.choose(npy.array(npy.sign(dy1dy2), npy.int32)+1, ((2*xi-xidx-xidxp1)/((dy1-dy2)*(xidxp1-xidx)), 0.0, 1/(dy1+dy2),)) - return yi -def _inside_poly_deprecated(points, verts): - """ - # use nxutils.points_inside_poly instead - points is a sequence of x,y points - verts is a sequence of x,y vertices of a poygon - - return value is a sequence on indices into points for the points - that are inside the polygon - """ - xys = nx.asarray(points) - Nxy = xys.shape[0] - Nv = len(verts) - - def angle(x1, y1, x2, y2): - twopi = 2*nx.pi - theta1 = nx.arctan2(y1, x1) - theta2 = nx.arctan2(y2, x2) - dtheta = theta2-theta1 - d = dtheta%twopi - d = nx.where(nx.less(d, 0), twopi + d, d) - return nx.where(nx.greater(d,nx.pi), d-twopi, d) - - angles = nx.zeros((Nxy,), float) - x1 = nx.zeros((Nxy,), float) - y1 = nx.zeros((Nxy,), float) - x2 = nx.zeros((Nxy,), float) - y2 = nx.zeros((Nxy,), float) - x = xys[:,0] - y = xys[:,1] - for i in range(Nv): - thisx, thisy = verts[i] - x1 = thisx - x - y1 = thisy - y - thisx, thisy = verts[(i+1)%Nv] - x2 = thisx - x - y2 = thisy - y - - a = angle(x1, y1, x2, y2) - angles += a - res, = npy.nonzero(nx.greater_equal(nx.absolute(angles), nx.pi)) - return res - - def inside_poly(points, verts): """ points is a sequence of x,y points verts is a sequence of x,y vertices of a poygon - return value is a sequence on indices into points for the points + return value is a sequence of indices into points for the points that are inside the polygon """ res, = npy.nonzero(nxutils.points_inside_poly(points, verts)) @@ -1689,10 +1557,10 @@ return value is x, y arrays for use with Axes.fill """ Nx = len(x) - if not iterable(ylower): + if not cbook.iterable(ylower): ylower = ylower*npy.ones(Nx) - if not iterable(yupper): + if not cbook.iterable(yupper): yupper = yupper*npy.ones(Nx) x = npy.concatenate( (x, x[::-1]) ) @@ -1757,12 +1625,12 @@ def exp_safe(x): """Compute exponentials which safely underflow to zero. - Slow but convenient to use. Note that NumArray will introduce proper + Slow but convenient to use. Note that numpy provides proper floating point exception handling with access to the underlying hardware.""" if type(x) is npy.ndarray: - return exp(clip(x,exp_safe_MIN,exp_safe_MAX)) + return exp(npy.clip(x,exp_safe_MIN,exp_safe_MAX)) else: return math.exp(x) @@ -1770,66 +1638,68 @@ """amap(function, sequence[, sequence, ...]) -> array. Works like map(), but it returns an array. This is just a convenient - shorthand for Numeric.array(map(...))""" - return array(map(fn,*args)) + shorthand for numpy.array(map(...)) + """ + return npy.array(map(fn,*args)) +#from numpy import zeros_like def zeros_like(a): """Return an array of zeros of the shape and typecode of a.""" + warnings.warn("Use numpy.zeros_like(a)", DeprecationWarning) + return npy.zeros_like(a) - return zeros(a.shape,typecode(a)) - +#from numpy import sum as sum_flat def sum_flat(a): """Return the sum of all the elements of a, flattened out. It uses a.flat, and if a is not contiguous, a call to ravel(a) is made.""" + warnings.warn("Use numpy.sum(a) or a.sum()", DeprecationWarning) + return npy.sum(a) - if iscontiguous(a): - return asum(a.flat) - else: - return asum(ravel(a)) - +#from numpy import mean as mean_flat def mean_flat(a): """Return the mean of all the elements of a, flattened out.""" + warnings.warn("Use numpy.mean(a) or a.mean()", DeprecationWarning) + return npy.mean(a) - return sum_flat(a)/float(size(a)) - def rms_flat(a): """Return the root mean square of all the elements of a, flattened out.""" - return numerix.mlab.sqrt(sum_flat(absolute(a)**2)/float(size(a))) + return npy.sqrt(npy.mean(npy.absolute(a)**2)) def l1norm(a): """Return the l1 norm of a, flattened out. Implemented as a separate function (not a call to norm() for speed).""" - return sum_flat(absolute(a)) + return npy.sum(npy.absolute(a)) def l2norm(a): """Return the l2 norm of a, flattened out. Implemented as a separate function (not a call to norm() for speed).""" - return numerix.mlab.sqrt(sum_flat(absolute(a)**2)) + return npy.sqrt(npy.sum(npy.absolute(a)**2)) -def norm(a,p=2): +def norm_flat(a,p=2): """norm(a,p=2) -> l-p norm of a.flat Return the l-p norm of a, considered as a flat array. This is NOT a true matrix norm, since arrays of arbitrary rank are always flattened. p can be a number or the string 'Infinity' to get the L-infinity norm.""" - + # This function was being masked by a more general norm later in + # the file. We may want to simply delete it. if p=='Infinity': - return max(absolute(a).flat) + return npy.amax(npy.absolute(a)) else: - return (sum_flat(absolute(a)**p))**(1.0/p) + return (npy.sum(npy.absolute(a)**p))**(1.0/p) def frange(xini,xfin=None,delta=None,**kw): """frange([start,] stop[, step, keywords]) -> array of floats - Return a Numeric array() containing a progression of floats. Similar to + Return a numpy ndarray containing a progression of floats. Similar to arange(), but defaults to a closed interval. frange(x0, x1) returns [x0, x0+1, x0+2, ..., x1]; start defaults to 0, and @@ -1855,7 +1725,7 @@ >>> frange(3,closed=0) array([ 0., 1., 2.]) >>> frange(1,6,2) - array([1, 3, 5]) + array([1, 3, 5]) or 1,3,5,7, depending on floating point vagueries >>> frange(1,6.5,npts=5) array([ 1. , 2.375, 3.75 , 5.125, 6.5 ]) """ @@ -1879,19 +1749,22 @@ npts=kw['npts'] delta=(xfin-xini)/float(npts-endpoint) except KeyError: - # round() gets npts right even with the vagaries of floating point... [truncated message content]
Revision: 3700 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3700&view=rev Author: efiring Date: 2007年08月11日 23:08:36 -0700 (2007年8月11日) Log Message: ----------- Minor numpifications Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/axes.py trunk/matplotlib/lib/matplotlib/axes3d.py trunk/matplotlib/lib/matplotlib/collections.py Modified: trunk/matplotlib/lib/matplotlib/axes.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axes.py 2007年08月10日 18:49:41 UTC (rev 3699) +++ trunk/matplotlib/lib/matplotlib/axes.py 2007年08月12日 06:08:36 UTC (rev 3700) @@ -4364,7 +4364,7 @@ if len(args)==1: C = args[0] numRows, numCols = C.shape - X, Y = mlab.meshgrid(npy.arange(numCols+1), npy.arange(numRows+1) ) + X, Y = npy.meshgrid(npy.arange(numCols+1), npy.arange(numRows+1) ) elif len(args)==3: X, Y, C = args numRows, numCols = C.shape @@ -4517,7 +4517,7 @@ if len(args)==1: C = args[0] numRows, numCols = C.shape - X, Y = mlab.meshgrid(npy.arange(numCols+1), npy.arange(numRows+1) ) + X, Y = npy.meshgrid(npy.arange(numCols+1), npy.arange(numRows+1) ) elif len(args)==3: X, Y, C = args numRows, numCols = C.shape @@ -4630,9 +4630,8 @@ you can verify that with # trapezoidal integration of the probability density function - from matplotlib.mlab import trapz pdf, bins, patches = ax.hist(...) - print trapz(bins, pdf) + print npy.trapz(pdf, bins) align = 'edge' | 'center'. Interprets bins either as edge or center values @@ -4650,7 +4649,7 @@ %(Rectangle)s """ if not self._hold: self.cla() - n, bins = mlab.hist(x, bins, normed) + n, bins = npy.histogram(x, bins, range=None, normed=normed) if width is None: width = 0.9*(bins[1]-bins[0]) if orientation == 'horizontal': patches = self.barh(bins, n, height=width, left=bottom, @@ -5266,7 +5265,7 @@ self._set_artist_props(self.title) - self.thetas = mlab.linspace(0, 2*math.pi, self.RESOLUTION) + self.thetas = npy.linspace(0, 2*math.pi, self.RESOLUTION) verts = zip(self.thetas, npy.ones(self.RESOLUTION)) self.axesPatch = mpatches.Polygon( @@ -5352,7 +5351,7 @@ for t in self.thetagridlabels: t.set_y(1.05*rmax) - r = mlab.linspace(0, rmax, self.RESOLUTION) + r = npy.linspace(0, rmax, self.RESOLUTION) for l in self.thetagridlines: l.set_ydata(r) @@ -5396,7 +5395,7 @@ rpad = rpad * max(radii) cbook.popall(self.rgridlines) - theta = mlab.linspace(0., 2*math.pi, self.RESOLUTION) + theta = npy.linspace(0., 2*math.pi, self.RESOLUTION) ls = rcParams['grid.linestyle'] color = rcParams['grid.color'] lw = rcParams['grid.linewidth'] @@ -5462,7 +5461,7 @@ lw = rcParams['grid.linewidth'] rmax = self.get_rmax() - r = mlab.linspace(0., rmax, self.RESOLUTION) + r = npy.linspace(0., rmax, self.RESOLUTION) for a in angles: theta = npy.ones(self.RESOLUTION)*a/180.*math.pi line = mlines.Line2D( Modified: trunk/matplotlib/lib/matplotlib/axes3d.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axes3d.py 2007年08月10日 18:49:41 UTC (rev 3699) +++ trunk/matplotlib/lib/matplotlib/axes3d.py 2007年08月12日 06:08:36 UTC (rev 3700) @@ -718,9 +718,9 @@ ax.set_zlabel('------------ Z Label --------------------') def get_test_data(delta=0.05): - from mlab import meshgrid, bivariate_normal + from mlab import bivariate_normal x = y = npy.arange(-3.0, 3.0, delta) - X, Y = meshgrid(x,y) + X, Y = npy.meshgrid(x,y) Z1 = bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) Z2 = bivariate_normal(X, Y, 1.5, 0.5, 1, 1) Modified: trunk/matplotlib/lib/matplotlib/collections.py =================================================================== --- trunk/matplotlib/lib/matplotlib/collections.py 2007年08月10日 18:49:41 UTC (rev 3699) +++ trunk/matplotlib/lib/matplotlib/collections.py 2007年08月12日 06:08:36 UTC (rev 3700) @@ -437,8 +437,8 @@ Example: see examples/dynamic_collection.py for complete example - offsets = nx.mlab.rand(20,2) - facecolors = [cm.jet(x) for x in nx.mlab.rand(20)] + offsets = npy.random.rand(20,2) + facecolors = [cm.jet(x) for x in npy.random.rand(20)] black = (0,0,0,1) collection = RegularPolyCollection( This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3699 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3699&view=rev Author: mdboom Date: 2007年08月10日 11:49:41 -0700 (2007年8月10日) Log Message: ----------- Don't pass "angle" into mathtext parser since it was always ignored anyway. (Any rotation should be performed on the mathtext after it's done.) Support scalable fonts for mathtext in Cairo backend. Simplify passing of mathtext layout back to Pdf backend. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py trunk/matplotlib/lib/matplotlib/backends/backend_ps.py trunk/matplotlib/lib/matplotlib/mathtext.py Modified: trunk/matplotlib/lib/matplotlib/backends/backend_agg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007年08月10日 18:45:44 UTC (rev 3698) +++ trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007年08月10日 18:49:41 UTC (rev 3699) @@ -174,7 +174,7 @@ if __debug__: verbose.report('RendererAgg.draw_mathtext', 'debug-annoying') width, height, fonts, used_characters = math_parse_s_ft2font( - s, self.dpi.get(), prop, angle) + s, self.dpi.get(), prop) if angle == 90: width, height = height, width @@ -190,8 +190,6 @@ self.height-int(y), width, height) - - def draw_text(self, gc, x, y, s, prop, angle, ismath): """ Render the text Modified: trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py 2007年08月10日 18:45:44 UTC (rev 3698) +++ trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py 2007年08月10日 18:49:41 UTC (rev 3699) @@ -36,10 +36,11 @@ from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\ FigureManagerBase, FigureCanvasBase -from matplotlib.cbook import enumerate, izip -from matplotlib.figure import Figure -from matplotlib.mathtext import math_parse_s_ft2font -from matplotlib.transforms import Bbox +from matplotlib.cbook import enumerate, izip +from matplotlib.figure import Figure +from matplotlib.mathtext import math_parse_s_cairo +from matplotlib.transforms import Bbox +from matplotlib.font_manager import ttfFontProperty from matplotlib import rcParams _debug = False @@ -296,66 +297,47 @@ if angle: ctx.rotate (-angle * npy.pi / 180) ctx.set_font_size (size) - ctx.show_text (s) + ctx.show_text (s.encode("utf-8")) ctx.restore() - def _draw_mathtext(self, gc, x, y, s, prop, angle): if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) # mathtext using the gtk/gdk method - #if npy.which[0] == "numarray": - # warnings.warn("_draw_mathtext() currently works for numpy, but " - # "not numarray") - # return - - #if not HAVE_CAIRO_NUMPY: - # warnings.warn("cairo with Numeric support is required for " - # "_draw_mathtext()") - # return - - width, height, fonts, used_characters = math_parse_s_ft2font( + ctx = gc.ctx + width, height, glyphs, rects = math_parse_s_cairo( s, self.dpi.get(), prop) - if angle==90: - width, height = height, width - x -= width - y -= height + ctx.save() + ctx.translate(x, y) + if angle: + ctx.rotate (-angle * npy.pi / 180) + + for font, fontsize, s, ox, oy in glyphs: + ctx.new_path() + ctx.move_to(ox, oy) + + fontProp = ttfFontProperty(font) + ctx.save() + ctx.select_font_face (fontProp.name, + self.fontangles [fontProp.style], + self.fontweights[fontProp.weight]) - imw, imh, s = fonts[0].image_as_str() - N = imw*imh + # size = prop.get_size_in_points() * self.dpi.get() / 96.0 + size = fontsize * self.dpi.get() / 72.0 + ctx.set_font_size(size) + ctx.show_text(s.encode("utf-8")) + ctx.restore() - # a numpixels by num fonts array - Xall = npy.zeros((N,len(fonts)), npy.uint8) + for ox, oy, w, h in rects: + ctx.new_path() + ctx.rectangle (ox, oy, w, h) + ctx.set_source_rgb (0, 0, 0) + ctx.fill_preserve() - for i, font in enumerate(fonts): - if angle == 90: - font.horiz_image_to_vert_image() # <-- Rotate - imw, imh, s = font.image_as_str() - Xall[:,i] = npy.fromstring(s, npy.uint8) + ctx.restore() - # get the max alpha at each pixel - Xs = npy.max (Xall,1) - - # convert it to it's proper shape - Xs.shape = imh, imw - - pa = npy.zeros((imh,imw,4), npy.uint8) - rgb = gc.get_rgb() - pa[:,:,0] = int(rgb[0]*255) - pa[:,:,1] = int(rgb[1]*255) - pa[:,:,2] = int(rgb[2]*255) - pa[:,:,3] = Xs - - ## works for numpy pa, not a numarray pa - #surface = cairo.ImageSurface.create_for_array (pa) - surface = cairo.ImageSurface.create_for_data (pa, cairo.FORMAT_ARGB32, - imw, imh, imw*4) - gc.ctx.set_source_surface (surface, x, y) - gc.ctx.paint() - #gc.ctx.show_surface (surface, imw, imh) - - + def flipy(self): if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) return True @@ -371,7 +353,7 @@ def get_text_width_height(self, s, prop, ismath): if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) if ismath: - width, height, fonts, used_characters = math_parse_s_ft2font( + width, height, fonts, used_characters = math_parse_s_cairo( s, self.dpi.get(), prop) return width, height Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007年08月10日 18:45:44 UTC (rev 3698) +++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007年08月10日 18:49:41 UTC (rev 3699) @@ -1173,8 +1173,8 @@ def draw_mathtext(self, gc, x, y, s, prop, angle): # TODO: fix positioning and encoding - width, height, pswriter, used_characters = \ - math_parse_s_pdf(s, 72, prop, 0) + width, height, glyphs, rects, used_characters = \ + math_parse_s_pdf(s, 72, prop) self.merge_used_characters(used_characters) # When using Type 3 fonts, we can't use character codes higher @@ -1192,42 +1192,35 @@ self.file.output(Op.begin_text) prev_font = None, None oldx, oldy = 0, 0 - for record in pswriter: - if record[0] == 'glyph': - rec_type, ox, oy, fontname, fontsize, num, symbol_name = \ - record - if fonttype == 42 or num <= 255: - self._setup_textpos(ox, oy, 0, oldx, oldy) - oldx, oldy = ox, oy - if (fontname, fontsize) != prev_font: - self.file.output(self.file.fontName(fontname), fontsize, - Op.selectfont) - prev_font = fontname, fontsize - self.file.output(self.encode_string(unichr(num)), Op.show) + for ox, oy, fontname, fontsize, num, symbol_name in glyphs: + if fonttype == 42 or num <= 255: + self._setup_textpos(ox, oy, 0, oldx, oldy) + oldx, oldy = ox, oy + if (fontname, fontsize) != prev_font: + self.file.output(self.file.fontName(fontname), fontsize, + Op.selectfont) + prev_font = fontname, fontsize + self.file.output(self.encode_string(unichr(num)), Op.show) self.file.output(Op.end_text) # If using Type 3 fonts, render all of the two-byte characters # as XObjects using the 'Do' command. if fonttype == 3: - for record in pswriter: - if record[0] == 'glyph': - rec_type, ox, oy, fontname, fontsize, num, symbol_name = \ - record - if num > 255: - self.file.output(Op.gsave, - 0.001 * fontsize, 0, - 0, 0.001 * fontsize, - ox, oy, Op.concat_matrix) - name = self.file._get_xobject_symbol_name( - fontname, symbol_name) - self.file.output(Name(name), Op.use_xobject) - self.file.output(Op.grestore) + for ox, oy, fontname, fontsize, num, symbol_name in glyphs: + if num > 255: + self.file.output(Op.gsave, + 0.001 * fontsize, 0, + 0, 0.001 * fontsize, + ox, oy, Op.concat_matrix) + name = self.file._get_xobject_symbol_name( + fontname, symbol_name) + self.file.output(Name(name), Op.use_xobject) + self.file.output(Op.grestore) # Draw any horizontal lines in the math layout - for record in pswriter: - if record[0] == 'rect': - rec_type, ox, oy, width, height = record - self.file.output(Op.gsave, ox, oy, width, height, Op.rectangle, Op.fill, Op.grestore) + for ox, oy, width, height in rects: + self.file.output(Op.gsave, ox, oy, width, height, + Op.rectangle, Op.fill, Op.grestore) # Pop off the global transformation self.file.output(Op.grestore) @@ -1427,7 +1420,8 @@ # s = s.encode('cp1252', 'replace') if ismath: - w, h, pswriter, used_characters = math_parse_s_pdf(s, 72, prop, 0) + w, h, glyphs, rects, used_characters = \ + math_parse_s_pdf(s, 72, prop) elif rcParams['pdf.use14corefonts']: font = self._get_font_afm(prop) Modified: trunk/matplotlib/lib/matplotlib/backends/backend_ps.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2007年08月10日 18:45:44 UTC (rev 3698) +++ trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2007年08月10日 18:49:41 UTC (rev 3699) @@ -278,7 +278,7 @@ if ismath: width, height, pswriter, used_characters = math_parse_s_ps( - s, 72, prop, 0) + s, 72, prop) return width, height if rcParams['ps.useafm']: @@ -814,7 +814,7 @@ self._pswriter.write("% mathtext\n") width, height, pswriter, used_characters = \ - math_parse_s_ps(s, 72, prop, angle) + math_parse_s_ps(s, 72, prop) self.merge_used_characters(used_characters) self.set_color(*gc.get_rgb()) thetext = pswriter.getvalue() Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2007年08月10日 18:45:44 UTC (rev 3698) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2007年08月10日 18:49:41 UTC (rev 3699) @@ -296,22 +296,24 @@ class MathtextBackendPdf(MathtextBackend): def __init__(self): - self.pswriter = [] + self.glyphs = [] + self.rects = [] def render_glyph(self, ox, oy, info): filename = info.font.fname oy = self.height - oy + info.offset - self.pswriter.append( - ('glyph', ox, oy, filename, info.fontsize, + self.glyphs.append( + (ox, oy, filename, info.fontsize, info.num, info.symbol_name)) def render_rect_filled(self, x1, y1, x2, y2): - self.pswriter.append(('rect', x1, self.height - y2, x2 - x1, y2 - y1)) + self.rects.append((x1, self.height - y2, x2 - x1, y2 - y1)) def get_results(self): return (self.width, self.height, - self.pswriter, + self.glyphs, + self.rects, self.fonts_object.get_used_characters()) class MathtextBackendSvg(MathtextBackend): @@ -327,7 +329,7 @@ def render_rect_filled(self, x1, y1, x2, y2): self.svg_rects.append( - (x1, self.height - y1, x2 - x1, y2 - y1)) + (x1, self.height - y2, x2 - x1, y2 - y1)) def get_results(self): svg_elements = Bunch(svg_glyphs = self.svg_glyphs, @@ -336,7 +338,28 @@ self.height, svg_elements, self.fonts_object.get_used_characters()) - + +class MathtextBackendCairo(MathtextBackend): + def __init__(self): + self.glyphs = [] + self.rects = [] + + def render_glyph(self, ox, oy, info): + oy = oy - info.offset - self.height + thetext = unichr(info.num) + self.glyphs.append( + (info.font, info.fontsize, thetext, ox, oy)) + + def render_rect_filled(self, x1, y1, x2, y2): + self.rects.append( + (x1, y1 - self.height, x2 - x1, y2 - y1)) + + def get_results(self): + return (self.width, + self.height, + self.glyphs, + self.rects) + class Fonts(object): """ An abstract base class for fonts that want to render mathtext @@ -2339,21 +2362,22 @@ _parser = None _backend_mapping = { - 'Agg': MathtextBackendAgg, - 'PS' : MathtextBackendPs, - 'PDF': MathtextBackendPdf, - 'SVG': MathtextBackendSvg + 'Agg' : MathtextBackendAgg, + 'PS' : MathtextBackendPs, + 'PDF' : MathtextBackendPdf, + 'SVG' : MathtextBackendSvg, + 'Cairo' : MathtextBackendCairo } def __init__(self, output): self.output = output self.cache = {} - def __call__(self, s, dpi, prop, angle=0): - cacheKey = (s, dpi, hash(prop), angle) + def __call__(self, s, dpi, prop): + cacheKey = (s, dpi, hash(prop)) if self.cache.has_key(cacheKey): - w, h, fontlike, used_characters = self.cache[cacheKey] - return w, h, fontlike, used_characters + result = self.cache[cacheKey] + return result if self.output == 'PS' and rcParams['ps.useafm']: font_output = StandardPsFonts(prop) @@ -2373,14 +2397,17 @@ h += 4 font_output.set_canvas_size(w, h) ship(2, 2, box) - self.cache[cacheKey] = font_output.get_results() + result = font_output.get_results() + self.cache[cacheKey] = result # Free up the transient data structures self._parser.clear() # Remove a cyclical reference font_output.mathtext_backend.fonts_object = None - return self.cache[cacheKey] + + return result math_parse_s_ft2font = math_parse_s_ft2font_common('Agg') math_parse_s_ft2font_svg = math_parse_s_ft2font_common('SVG') math_parse_s_ps = math_parse_s_ft2font_common('PS') math_parse_s_pdf = math_parse_s_ft2font_common('PDF') +math_parse_s_cairo = math_parse_s_ft2font_common('Cairo') This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3698 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3698&view=rev Author: mdboom Date: 2007年08月10日 11:45:44 -0700 (2007年8月10日) Log Message: ----------- Add ~/.fonts as search directory on Linux Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/font_manager.py Modified: trunk/matplotlib/lib/matplotlib/font_manager.py =================================================================== --- trunk/matplotlib/lib/matplotlib/font_manager.py 2007年08月10日 18:06:16 UTC (rev 3697) +++ trunk/matplotlib/lib/matplotlib/font_manager.py 2007年08月10日 18:45:44 UTC (rev 3698) @@ -85,6 +85,8 @@ # user fonts on OSX path = os.path.join(home, 'Library', 'Fonts') OSXFontDirectories.append(path) + path = os.path.join(home, '.fonts') + X11FontDirectories.append(path) def win32FontDirectory(): """Return the user-specified font directory for Win32.""" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3697 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3697&view=rev Author: efiring Date: 2007年08月10日 11:06:16 -0700 (2007年8月10日) Log Message: ----------- Fixed bug in scatter3D Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/axes3d.py Modified: trunk/matplotlib/lib/matplotlib/axes3d.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axes3d.py 2007年08月10日 12:53:21 UTC (rev 3696) +++ trunk/matplotlib/lib/matplotlib/axes3d.py 2007年08月10日 18:06:16 UTC (rev 3697) @@ -679,8 +679,9 @@ def scatter(self, xs,ys,zs=None,dir='z',*args,**kwargs): patches = self.wrapped.scatter(xs,ys,*args,**kwargs) - zs = zs or [0]*len(xs) - patches = art3d.wrap_patch(patches, zs=[0]*len(xs),dir=dir) + if zs is None: + zs = [0]*len(xs) + patches = art3d.wrap_patch(patches, zs=zs, dir=dir) return patches def bar(self, left, height, z=0, dir='z', *args, **kwargs): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3696 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3696&view=rev Author: cmoad Date: 2007年08月10日 05:53:21 -0700 (2007年8月10日) Log Message: ----------- added win32 checks for vsnprintf which is _vsnprintf on windows Modified Paths: -------------- trunk/matplotlib/ttconv/ttutil.cpp Modified: trunk/matplotlib/ttconv/ttutil.cpp =================================================================== --- trunk/matplotlib/ttconv/ttutil.cpp 2007年08月09日 15:14:59 UTC (rev 3695) +++ trunk/matplotlib/ttconv/ttutil.cpp 2007年08月10日 12:53:21 UTC (rev 3696) @@ -32,10 +32,18 @@ va_start(arg_list, format); char buffer[PRINTF_BUFFER_SIZE]; +#ifdef WIN32 + int size = _vsnprintf(buffer, PRINTF_BUFFER_SIZE, format, arg_list); +#else int size = vsnprintf(buffer, PRINTF_BUFFER_SIZE, format, arg_list); +#endif if (size >= PRINTF_BUFFER_SIZE) { char* buffer2 = (char*)malloc(size); +#ifdef WIN32 + _vsnprintf(buffer2, size, format, arg_list); +#else vsnprintf(buffer2, size, format, arg_list); +#endif free(buffer2); } else { this->write(buffer); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3695 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3695&view=rev Author: mdboom Date: 2007年08月09日 08:14:59 -0700 (2007年8月09日) Log Message: ----------- Minor PDF filesize improvement. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007年08月09日 15:14:28 UTC (rev 3694) +++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007年08月09日 15:14:59 UTC (rev 3695) @@ -508,6 +508,7 @@ charprocsObject = self.reserveObject('character procs') differencesArray = [] firstchar, lastchar = 0, 255 + bbox = [cvt(x, nearest=False) for x in font.bbox] fontdict = { 'Type' : Name('Font'), @@ -517,7 +518,7 @@ 'FontDescriptor' : fontdescObject, 'Subtype' : Name('Type3'), 'Name' : descriptor['FontName'], - 'FontBBox' : [cvt(x, nearest=False) for x in font.bbox], + 'FontBBox' : bbox, 'FontMatrix' : [ .001, 0, 0, .001, 0, 0 ], 'CharProcs' : charprocsObject, 'Encoding' : { @@ -575,15 +576,18 @@ charprocs = {} charprocsRef = {} for charname, stream in rawcharprocs.items(): + charprocDict = { 'Length': len(stream) } + # The 2-byte characters are used as XObjects, so they + # need extra info in their dictionary + if charname in two_byte_chars: + charprocDict['Type'] = Name('XObject') + charprocDict['Subtype'] = Name('Form') + charprocDict['BBox'] = bbox charprocObject = self.reserveObject('charProc for %s' % name) - self.beginStream(charprocObject.id, - None, - {'Length': len(stream), - 'Type': Name('XObject'), - 'Subtype': Name('Form'), - 'BBox': [cvt(x, nearest=False) for x in font.bbox]}) + self.beginStream(charprocObject.id, None, charprocDict) self.currentstream.write(stream) self.endStream() + # Send the glyphs with ccode > 255 to the XObject dictionary, # and the others to the font itself if charname in two_byte_chars: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3694 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3694&view=rev Author: mdboom Date: 2007年08月09日 08:14:28 -0700 (2007年8月09日) Log Message: ----------- Remove "deprecated conversion from string constant to char*" warnings. Modified Paths: -------------- trunk/matplotlib/src/_ttconv.cpp trunk/matplotlib/src/ft2font.cpp trunk/matplotlib/ttconv/pprdrv_tt.cpp trunk/matplotlib/ttconv/truetype.h Modified: trunk/matplotlib/src/_ttconv.cpp =================================================================== --- trunk/matplotlib/src/_ttconv.cpp 2007年08月09日 15:13:50 UTC (rev 3693) +++ trunk/matplotlib/src/_ttconv.cpp 2007年08月09日 15:14:28 UTC (rev 3694) @@ -39,7 +39,7 @@ virtual void write(const char* a) { if (_write_method) - if (! PyObject_CallFunction(_write_method, "s", a)) + if (! PyObject_CallFunction(_write_method, (char *)"s", a)) throw PythonExceptionOccurred(); } }; @@ -83,10 +83,12 @@ int fonttype; std::vector<int> glyph_ids; - static char *kwlist[] = { "filename", "output", "fonttype", "glyph_ids", NULL }; + static const char *kwlist[] = { + "filename", "output", "fonttype", "glyph_ids", NULL }; if (! PyArg_ParseTupleAndKeywords (args, kwds, - "sO&i|O&:convert_ttf_to_ps", kwlist, + "sO&i|O&:convert_ttf_to_ps", + (char**)kwlist, &filename, fileobject_to_PythonFileWriter, &output, @@ -140,10 +142,11 @@ std::vector<int> glyph_ids; PyObject* result; - static char *kwlist[] = { "filename", "glyph_ids", NULL }; + static const char *kwlist[] = { "filename", "glyph_ids", NULL }; if (! PyArg_ParseTupleAndKeywords (args, kwds, - "s|O&:convert_ttf_to_ps", kwlist, + "s|O&:convert_ttf_to_ps", + (char **)kwlist, &filename, pyiterable_to_vector_int, &glyph_ids)) Modified: trunk/matplotlib/src/ft2font.cpp =================================================================== --- trunk/matplotlib/src/ft2font.cpp 2007年08月09日 15:13:50 UTC (rev 3693) +++ trunk/matplotlib/src/ft2font.cpp 2007年08月09日 15:14:28 UTC (rev 3694) @@ -1411,8 +1411,8 @@ std::string tagname = Py::String(args[0]); int tag; - char *tags[] = {"head", "maxp", "OS/2", "hhea", - "vhea", "post", "pclt", NULL}; + const char *tags[] = {"head", "maxp", "OS/2", "hhea", + "vhea", "post", "pclt", NULL}; for (tag=0; tags[tag] != NULL; tag++) if (strcmp(tagname.c_str(), tags[tag]) == 0) Modified: trunk/matplotlib/ttconv/pprdrv_tt.cpp =================================================================== --- trunk/matplotlib/ttconv/pprdrv_tt.cpp 2007年08月09日 15:13:50 UTC (rev 3693) +++ trunk/matplotlib/ttconv/pprdrv_tt.cpp 2007年08月09日 15:14:28 UTC (rev 3694) @@ -107,7 +107,7 @@ ** is always 4 characters, though the last characters may be ** padding spaces. -----------------------------------------------------------------------*/ -BYTE *GetTable(struct TTFONT *font, char *name) +BYTE *GetTable(struct TTFONT *font, const char *name) { BYTE *ptr; ULONG x; @@ -181,10 +181,10 @@ /* Set default values to avoid future references to */ /* undefined pointers. */ font->PostName = font->FullName = - font->FamilyName = font->Version = font->Style = "unknown"; + font->FamilyName = font->Version = font->Style = (char*)"unknown"; font->Copyright = font->Trademark = (char*)NULL; - table_ptr = GetTable(font,"name"); /* pointer to table */ + table_ptr = GetTable(font, "name"); /* pointer to table */ try { numrecords = getUSHORT( table_ptr + 2 ); /* number of names */ strings = table_ptr + getUSHORT( table_ptr + 4 ); /* start of string storage */ @@ -654,10 +654,10 @@ */ void ttfont_sfnts(TTStreamWriter& stream, struct TTFONT *font) { - char *table_names[]= /* The names of all tables */ - { /* which it is worth while */ - "cvt ", /* to include in a Type 42 */ - "fpgm", /* PostScript font. */ + static const char *table_names[] = /* The names of all tables */ + { /* which it is worth while */ + "cvt ", /* to include in a Type 42 */ + "fpgm", /* PostScript font. */ "glyf", "head", "hhea", @@ -828,7 +828,7 @@ ** this array will instead convert PostScript character names ** to executable proceedures. --------------------------------------------------------------*/ -char *Apple_CharStrings[]={ +const char *Apple_CharStrings[]={ ".notdef",".null","nonmarkingreturn","space","exclam","quotedbl","numbersign", "dollar","percent","ampersand","quotesingle","parenleft","parenright", "asterisk","plus", "comma","hyphen","period","slash","zero","one","two", @@ -871,7 +871,7 @@ ** This routine is called by the one below. ** It is also called from pprdrv_tt2.c */ -char *ttfont_CharStrings_getname(struct TTFONT *font, int charindex) +const char *ttfont_CharStrings_getname(struct TTFONT *font, int charindex) { int GlyphIndex; static char temp[80]; @@ -1227,7 +1227,7 @@ i != glyph_ids.end(); ++i) { StringStreamWriter writer; tt_type3_charproc(writer, &font, *i); - char* name = ttfont_CharStrings_getname(&font, *i); + const char* name = ttfont_CharStrings_getname(&font, *i); dict.add_pair(name, writer.str().c_str()); } } Modified: trunk/matplotlib/ttconv/truetype.h =================================================================== --- trunk/matplotlib/ttconv/truetype.h 2007年08月09日 15:13:50 UTC (rev 3693) +++ trunk/matplotlib/ttconv/truetype.h 2007年08月09日 15:14:28 UTC (rev 3694) @@ -98,7 +98,7 @@ /* This is the one routine in pprdrv_tt.c that is */ /* called from pprdrv_tt.c. */ -char *ttfont_CharStrings_getname(struct TTFONT *font, int charindex); +const char *ttfont_CharStrings_getname(struct TTFONT *font, int charindex); void tt_type3_charproc(TTStreamWriter& stream, struct TTFONT *font, int charindex); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3693 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3693&view=rev Author: mdboom Date: 2007年08月09日 08:13:50 -0700 (2007年8月09日) Log Message: ----------- Remove "variable may be used uninitialized in this function" warnings. Modified Paths: -------------- trunk/matplotlib/agg23/include/agg_conv_curve.h Modified: trunk/matplotlib/agg23/include/agg_conv_curve.h =================================================================== --- trunk/matplotlib/agg23/include/agg_conv_curve.h 2007年08月09日 15:13:12 UTC (rev 3692) +++ trunk/matplotlib/agg23/include/agg_conv_curve.h 2007年08月09日 15:13:50 UTC (rev 3693) @@ -117,10 +117,10 @@ return path_cmd_line_to; } - double ct2_x; - double ct2_y; - double end_x; - double end_y; + double ct2_x = 0; + double ct2_y = 0; + double end_x = 0; + double end_y = 0; unsigned cmd = m_source->vertex(x, y); switch(cmd) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 3692 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3692&view=rev Author: mdboom Date: 2007年08月09日 08:13:12 -0700 (2007年8月09日) Log Message: ----------- Removed "right-hand operand has no effect" warning in gcc. Modified Paths: -------------- trunk/matplotlib/CXX/Extensions.hxx Modified: trunk/matplotlib/CXX/Extensions.hxx =================================================================== --- trunk/matplotlib/CXX/Extensions.hxx 2007年08月09日 14:39:11 UTC (rev 3691) +++ trunk/matplotlib/CXX/Extensions.hxx 2007年08月09日 15:13:12 UTC (rev 3692) @@ -474,10 +474,10 @@ : PythonExtensionBase() { #ifdef PyObject_INIT - PyObject_INIT( this, type_object() ); + (void)PyObject_INIT( this, type_object() ); #else - ob_refcnt = 1; - ob_type = type_object(); + ob_refcnt = 1; + ob_type = type_object(); #endif // every object must support getattr This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.