From: <md...@us...> - 2007-12-05 21:13:59
|
Revision: 4634 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4634&view=rev Author: mdboom Date: 2007-12-05 13:13:46 -0800 (Wed, 05 Dec 2007) Log Message: ----------- Merged revisions 4621-4633 via svnmerge from http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib ........ r4622 | jdh2358 | 2007-12-05 12:11:28 -0500 (Wed, 05 Dec 2007) | 2 lines updated autofmt_xdate to work in more cases. it no longer raises if axes aren't subplots ........ r4629 | jdh2358 | 2007-12-05 14:27:14 -0500 (Wed, 05 Dec 2007) | 2 lines minor rec2excel enhancements ........ r4632 | pkienzle | 2007-12-05 14:36:36 -0500 (Wed, 05 Dec 2007) | 1 line docu update: coord reporting works in wx ........ r4633 | mdboom | 2007-12-05 15:28:28 -0500 (Wed, 05 Dec 2007) | 2 lines Fix bug where font files were opened many more times than they need to be. ........ Modified Paths: -------------- branches/transforms/examples/coords_report.py branches/transforms/examples/loadrec.py branches/transforms/lib/matplotlib/backends/backend_agg.py branches/transforms/lib/matplotlib/backends/backend_pdf.py branches/transforms/lib/matplotlib/backends/backend_ps.py branches/transforms/lib/matplotlib/backends/backend_svg.py branches/transforms/lib/matplotlib/figure.py branches/transforms/lib/matplotlib/font_manager.py branches/transforms/lib/matplotlib/mlab.py Property Changed: ---------------- branches/transforms/ Property changes on: branches/transforms ___________________________________________________________________ Name: svnmerge-integrated - /trunk/matplotlib:1-4620 + /trunk/matplotlib:1-4633 Modified: branches/transforms/examples/coords_report.py =================================================================== --- branches/transforms/examples/coords_report.py 2007-12-05 20:28:28 UTC (rev 4633) +++ branches/transforms/examples/coords_report.py 2007-12-05 21:13:46 UTC (rev 4634) @@ -1,7 +1,6 @@ #!/usr/bin/env python -# override the default reporting of coords (coords reporting not -# implemented yet on wx*) +# override the default reporting of coords from pylab import * Modified: branches/transforms/examples/loadrec.py =================================================================== --- branches/transforms/examples/loadrec.py 2007-12-05 20:28:28 UTC (rev 4633) +++ branches/transforms/examples/loadrec.py 2007-12-05 21:13:46 UTC (rev 4634) @@ -9,4 +9,6 @@ ax = fig.add_subplot(111) ax.plot(a.date, a.adj_close, '-') fig.autofmt_xdate() + +mlab.rec2excel(a, 'test.xls', colnum=4) show() Modified: branches/transforms/lib/matplotlib/backends/backend_agg.py =================================================================== --- branches/transforms/lib/matplotlib/backends/backend_agg.py 2007-12-05 20:28:28 UTC (rev 4633) +++ branches/transforms/lib/matplotlib/backends/backend_agg.py 2007-12-05 21:13:46 UTC (rev 4634) @@ -31,7 +31,8 @@ from matplotlib._pylab_helpers import Gcf from matplotlib.backend_bases import RendererBase,\ GraphicsContextBase, FigureManagerBase, FigureCanvasBase -from matplotlib.cbook import enumerate, is_string_like, exception_to_str +from matplotlib.cbook import enumerate, is_string_like, exception_to_str, \ + maxdict from matplotlib.figure import Figure from matplotlib.font_manager import findfont from matplotlib.ft2font import FT2Font, LOAD_FORCE_AUTOHINT @@ -49,7 +50,8 @@ context instance that controls the colors/styles """ debug=1 - texd = {} # a cache of tex image rasters + texd = maxdict(50) # a cache of tex image rasters + _fontd = maxdict(50) def __init__(self, width, height, dpi): if __debug__: verbose.report('RendererAgg.__init__', 'debug-annoying') RendererBase.__init__(self) @@ -70,7 +72,6 @@ self.restore_region = self._renderer.restore_region self.tostring_rgba_minimized = self._renderer.tostring_rgba_minimized self.mathtext_parser = MathTextParser('Agg') - self._fontd = {} self.bbox = Bbox.from_bounds(0, 0, self.width, self.height) if __debug__: verbose.report('RendererAgg.__init__ done', @@ -172,7 +173,10 @@ if font is None: fname = findfont(prop) - font = FT2Font(str(fname)) + font = self._fontd.get(fname) + if font is None: + font = FT2Font(str(fname)) + self._fontd[fname] = font self._fontd[key] = font font.clear() Modified: branches/transforms/lib/matplotlib/backends/backend_pdf.py =================================================================== --- branches/transforms/lib/matplotlib/backends/backend_pdf.py 2007-12-05 20:28:28 UTC (rev 4633) +++ branches/transforms/lib/matplotlib/backends/backend_pdf.py 2007-12-05 21:13:46 UTC (rev 4634) @@ -26,7 +26,7 @@ FigureManagerBase, FigureCanvasBase from matplotlib.backends.backend_mixed import MixedModeRenderer from matplotlib.cbook import Bunch, enumerate, is_string_like, reverse_dict, \ - get_realpath_and_stat, is_writable_file_like + get_realpath_and_stat, is_writable_file_like, maxdict from matplotlib.figure import Figure from matplotlib.font_manager import findfont, is_opentype_cff_font from matplotlib.afm import AFM @@ -1162,13 +1162,13 @@ self.write("\nstartxref\n%d\n%%%%EOF\n" % self.startxref) class RendererPdf(RendererBase): + truetype_font_cache = maxdict(50) + afm_font_cache = maxdict(50) def __init__(self, file, dpi): RendererBase.__init__(self) self.file = file self.gc = self.new_gc() - self.truetype_font_cache = {} - self.afm_font_cache = {} self.file.used_characters = self.used_characters = {} self.mathtext_parser = MathTextParser("Pdf") self.dpi = dpi @@ -1176,8 +1176,6 @@ def finalize(self): self.gc.finalize() - del self.truetype_font_cache - del self.afm_font_cache def check_gc(self, gc, fillcolor=None): orig_fill = gc._fillcolor @@ -1589,9 +1587,12 @@ font = self.afm_font_cache.get(key) if font is None: filename = findfont(prop, fontext='afm') - fh = file(filename) - font = AFM(fh) - fh.close() + font = self.afm_font_cache.get(filename) + if font is None: + fh = file(filename) + font = AFM(fh) + self.afm_font_cache[filename] = font + fh.close() self.afm_font_cache[key] = font return font @@ -1600,7 +1601,10 @@ font = self.truetype_font_cache.get(key) if font is None: filename = findfont(prop) - font = FT2Font(str(filename)) + font = self.truetype_font_cache.get(filename) + if font is None: + font = FT2Font(str(filename)) + self.truetype_font_cache[filename] = font self.truetype_font_cache[key] = font font.clear() font.set_size(prop.get_size_in_points(), self.dpi) Modified: branches/transforms/lib/matplotlib/backends/backend_ps.py =================================================================== --- branches/transforms/lib/matplotlib/backends/backend_ps.py 2007-12-05 20:28:28 UTC (rev 4633) +++ branches/transforms/lib/matplotlib/backends/backend_ps.py 2007-12-05 21:13:46 UTC (rev 4634) @@ -15,7 +15,7 @@ FigureManagerBase, FigureCanvasBase from matplotlib.cbook import is_string_like, izip, get_realpath_and_stat, \ - is_writable_file_like + is_writable_file_like, maxdict from matplotlib.figure import Figure from matplotlib.font_manager import findfont, is_opentype_cff_font @@ -122,6 +122,9 @@ context instance that controls the colors/styles. """ + fontd = maxdict(50) + afmfontd = maxdict(50) + def __init__(self, width, height, pswriter, dpi=72): RendererBase.__init__(self) self.width = width @@ -144,8 +147,6 @@ self._clip_paths = {} self._path_collection_id = 0 - self.fontd = {} - self.afmfontd = {} self.used_characters = {} self.mathtext_parser = MathTextParser("PS") @@ -316,7 +317,11 @@ key = hash(prop) font = self.afmfontd.get(key) if font is None: - font = AFM(file(findfont(prop, fontext='afm'))) + fname = findfont(prop, fontext='afm') + font = self.afmfontd.get(fname) + if font is None: + font = AFM(file(findfont(prop, fontext='afm'))) + self.afmfontd[fname] = font self.afmfontd[key] = font return font @@ -325,7 +330,10 @@ font = self.fontd.get(key) if font is None: fname = findfont(prop) - font = FT2Font(str(fname)) + font = self.fontd.get(fname) + if font is None: + font = FT2Font(str(fname)) + self.fontd[fname] = font self.fontd[key] = font font.clear() size = prop.get_size_in_points() Modified: branches/transforms/lib/matplotlib/backends/backend_svg.py =================================================================== --- branches/transforms/lib/matplotlib/backends/backend_svg.py 2007-12-05 20:28:28 UTC (rev 4633) +++ branches/transforms/lib/matplotlib/backends/backend_svg.py 2007-12-05 21:13:46 UTC (rev 4634) @@ -6,7 +6,7 @@ from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\ FigureManagerBase, FigureCanvasBase from matplotlib.backends.backend_mixed import MixedModeRenderer -from matplotlib.cbook import is_string_like, is_writable_file_like +from matplotlib.cbook import is_string_like, is_writable_file_like, maxdict from matplotlib.colors import rgb2hex from matplotlib.figure import Figure from matplotlib.font_manager import findfont, FontProperties @@ -30,6 +30,7 @@ _capstyle_d = {'projecting' : 'square', 'butt' : 'butt', 'round': 'round',} class RendererSVG(RendererBase): FONT_SCALE = 100.0 + fontd = maxdict(50) def __init__(self, width, height, svgwriter, basename=None): self.width=width @@ -46,7 +47,6 @@ self._markers = {} self._path_collection_id = 0 self.mathtext_parser = MathTextParser('SVG') - self.fontd = {} svgwriter.write(svgProlog%(width,height,width,height)) def _draw_svg_element(self, element, details, gc, rgbFace): @@ -59,13 +59,16 @@ style = self._get_style(gc, rgbFace) self._svgwriter.write ('<%s style="%s" %s %s/>\n' % ( element, style, clippath, details)) - + def _get_font(self, prop): key = hash(prop) font = self.fontd.get(key) if font is None: fname = findfont(prop) - font = FT2Font(str(fname)) + font = self.fontd.get(fname) + if font is None: + font = FT2Font(str(fname)) + self.fontd[fname] = font self.fontd[key] = font font.clear() size = prop.get_size_in_points() @@ -119,7 +122,7 @@ path = '<rect x="%(x)s" y="%(y)s" width="%(w)s" height="%(h)s"/>' % locals() else: return None - + id = self._clipd.get(path) if id is None: id = 'p%x' % len(self._clipd) @@ -154,7 +157,7 @@ Affine2D() .scale(1.0, -1.0) .translate(0.0, self.height)) - + def _convert_path(self, path, transform): tpath = transform.transform_path(path) @@ -174,7 +177,7 @@ appender(segment) currpos += len(segment) return ''.join(path_data) - + def draw_path(self, gc, path, transform, rgbFace=None): trans_and_flip = self._make_flip_transform(transform) path_data = self._convert_path(path, trans_and_flip) @@ -182,7 +185,7 @@ def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None): write = self._svgwriter.write - + key = self._convert_path(marker_path, marker_trans + Affine2D().scale(1.0, -1.0)) name = self._markers.get(key) if name is None: @@ -201,7 +204,7 @@ offsetTrans, facecolors, edgecolors, linewidths, linestyles, antialiaseds): write = self._svgwriter.write - + path_codes = [] write('<defs>\n') for i, (path, transform) in enumerate(self._iter_collection_raw_paths( @@ -212,7 +215,7 @@ write('<path id="%s" d="%s"/>\n' % (name, d)) path_codes.append(name) write('</defs>\n') - + for xo, yo, path_id, gc, rgbFace in self._iter_collection( path_codes, cliprect, clippath, clippath_trans, offsets, offsetTrans, facecolors, edgecolors, @@ -221,7 +224,7 @@ self._draw_svg_element('use', details, gc, rgbFace) self._path_collection_id += 1 - + def draw_image(self, x, y, im, bbox, clippath=None, clippath_trans=None): # MGDTODO: Support clippath here trans = [1,0,0,1,0,0] @@ -288,7 +291,7 @@ font = self._get_font(prop) font.set_text(s, 0.0, flags=LOAD_NO_HINTING) y -= font.get_descent() / 64.0 - + fontsize = prop.get_size_in_points() color = rgb2hex(gc.get_rgb()[:3]) @@ -429,7 +432,7 @@ for font, fontsize, thetext, new_x, new_y_mtc, metrics in svg_glyphs: new_y = - new_y_mtc style = "font-size: %f; font-family: %s" % (fontsize, font.family_name) - + svg.append('<tspan style="%s"' % style) xadvance = metrics.advance svg.append(' textLength="%s"' % xadvance) @@ -503,14 +506,20 @@ 'svgz': 'Scalable Vector Graphics'} def print_svg(self, filename, *args, **kwargs): - svgwriter = codecs.open(filename, 'w', 'utf-8') - return self._print_svg(filename, svgwriter) + if is_string_like(filename): + fh_to_close = svgwriter = codecs.open(filename, 'w', 'utf-8') + elif is_writable_file_like(filename): + svgwriter = codecs.EncodedFile(filename, 'utf-8') + fh_to_close = None + else: + raise ValueError("filename must be a path or a file-like object") + return self._print_svg(filename, svgwriter, fh_to_close) def print_svgz(self, filename, *args, **kwargs): gzipwriter = gzip.GzipFile(filename, 'w') svgwriter = codecs.EncodedFile(gzipwriter, 'utf-8') return self._print_svg(filename, svgwriter) - + def _print_svg(self, filename, svgwriter, fh_to_close=None): self.figure.set_dpi(72.0) width, height = self.figure.get_size_inches() @@ -522,10 +531,10 @@ renderer.finalize() if fh_to_close is not None: svgwriter.close() - + def get_default_filetype(self): return 'svg' - + class FigureManagerSVG(FigureManagerBase): pass Modified: branches/transforms/lib/matplotlib/figure.py =================================================================== --- branches/transforms/lib/matplotlib/figure.py 2007-12-05 20:28:28 UTC (rev 4633) +++ branches/transforms/lib/matplotlib/figure.py 2007-12-05 21:13:46 UTC (rev 4634) @@ -165,27 +165,36 @@ def autofmt_xdate(self, bottom=0.2, rotation=30, ha='right'): """ - A common use case is a number of subplots with shared xaxes - where the x-axis is date data. The ticklabels are often - long,and it helps to rotate them on the bottom subplot and - turn them off on other subplots. This function will raise a - RuntimeError if any of the Axes are not Subplots. + Date ticklabels often overlap, so it is useful to rotate them + and right align them. Also, a common use case is a number of + subplots with shared xaxes where the x-axis is date data. The + ticklabels are often long, and it helps to rotate them on the + bottom subplot and turn them off on other subplots, as well as + turn off xlabels. + bottom : the bottom of the subplots for subplots_adjust rotation: the rotation of the xtick labels ha : the horizontal alignment of the xticklabels """ - for ax in self.get_axes(): - if not hasattr(ax, 'is_last_row'): - raise RuntimeError('Axes must be subplot instances; found %s'%type(ax)) - if ax.is_last_row(): - for label in ax.get_xticklabels(): - label.set_ha(ha) - label.set_rotation(rotation) - else: - for label in ax.get_xticklabels(): - label.set_visible(False) - if not self._autoLayout: + allsubplots = npy.alltrue([hasattr(ax, 'is_last_row') for ax in self.axes]) + if len(self.axes)==1: + for label in ax.get_xticklabels(): + label.set_ha(ha) + label.set_rotation(rotation) + else: + if allsubplots: + for ax in self.get_axes(): + if ax.is_last_row(): + for label in ax.get_xticklabels(): + label.set_ha(ha) + label.set_rotation(rotation) + else: + for label in ax.get_xticklabels(): + label.set_visible(False) + ax.set_xlabel('') + + if allsubplots and not self._autoLayout: self.subplots_adjust(bottom=bottom) def get_children(self): Modified: branches/transforms/lib/matplotlib/font_manager.py =================================================================== --- branches/transforms/lib/matplotlib/font_manager.py 2007-12-05 20:28:28 UTC (rev 4633) +++ branches/transforms/lib/matplotlib/font_manager.py 2007-12-05 21:13:46 UTC (rev 4634) @@ -36,7 +36,7 @@ import os, sys, glob from sets import Set import matplotlib -from matplotlib import afm +from matplotlib import afm from matplotlib import ft2font from matplotlib import rcParams, get_configdir from matplotlib.cbook import is_string_like @@ -49,7 +49,7 @@ import pickle USE_FONTCONFIG = False - + verbose = matplotlib.verbose font_scalings = {'xx-small': 0.579, 'x-small': 0.694, 'small': 0.833, @@ -98,7 +98,7 @@ def get_fontext_synonyms(fontext): return {'ttf': ('ttf', 'otf'), 'afm': ('afm',)}[fontext] - + def win32FontDirectory(): """Return the user-specified font directory for Win32.""" @@ -126,7 +126,7 @@ directory = win32FontDirectory() fontext = get_fontext_synonyms(fontext) - + key, items = None, {} for fontdir in MSFontDirectories: try: @@ -178,7 +178,7 @@ directory = OSXFontDirectory() fontext = get_fontext_synonyms(fontext) - + files = [] for path in directory: if fontext is None: @@ -214,7 +214,7 @@ return {} fontext = get_fontext_synonyms(fontext) - + fontfiles = {} status, output = commands.getstatusoutput("fc-list file") if status == 0: @@ -236,7 +236,7 @@ """ fontfiles = {} fontexts = get_fontext_synonyms(fontext) - + if fontpaths is None: if sys.platform == 'win32': fontdir = win32FontDirectory() @@ -635,7 +635,7 @@ stretch = [rcParams['font.stretch']] size = [rcParams['font.size']] file = None - + def __init__(self, family = None, style = None, @@ -653,7 +653,7 @@ if _init is not None: self.__props.__dict__.update(_init) return - + if is_string_like(family): # Treat family as a fontconfig pattern if it is the only # parameter provided. @@ -674,16 +674,16 @@ self.set_stretch(stretch) self.set_file(fname) self.set_size(size) - + def _parse_fontconfig_pattern(self, pattern): return parse_fontconfig_pattern(pattern) def __hash__(self): - return hash(repr(self.__props)) + return hash(repr(self.__props.__dict__)) def __str__(self): return self.get_fontconfig_pattern() - + def get_family(self): """Return a list of font names that comprise the font family. """ @@ -727,7 +727,7 @@ def get_fontconfig_pattern(self): return generate_fontconfig_pattern(self.__props.__dict__) - + def set_family(self, family): """ Change the font family. May be either an alias (generic name @@ -741,7 +741,7 @@ family = [family] self.__props.family = family set_name = set_family - + def set_style(self, style): """Set the font style. Values are: normal, italic or oblique.""" if style is None: @@ -812,7 +812,7 @@ def add_property_pair(self, key, val): self.__props.setdefault(key, []).append(val) - + def copy(self): """Return a deep copy of self""" return FontProperties(_init = self.__props.__dict__) @@ -862,7 +862,7 @@ def __init__(self, size=None, weight='normal'): self.__default_weight = weight self.default_size = size - + paths = [os.path.join(rcParams['datapath'],'fonts','ttf'), os.path.join(rcParams['datapath'],'fonts','afm')] @@ -1076,8 +1076,8 @@ _is_opentype_cff_font_cache[filename] = result return result return False - - + + if USE_FONTCONFIG and sys.platform != 'win32': import re @@ -1095,7 +1095,7 @@ _fc_match_regex = re.compile(r'\sfile:\s+"([^"]*)"') _fc_match_cache = {} - + def findfont(prop, fontext='ttf'): if not is_string_like(prop): prop = prop.get_fontconfig_pattern() Modified: branches/transforms/lib/matplotlib/mlab.py =================================================================== --- branches/transforms/lib/matplotlib/mlab.py 2007-12-05 20:28:28 UTC (rev 4633) +++ branches/transforms/lib/matplotlib/mlab.py 2007-12-05 21:13:46 UTC (rev 4634) @@ -2367,7 +2367,7 @@ xlstyle.num_format_str = '#,##;[RED]-#,##' elif isinstance(format, FormatPercent): zeros = ''.join(['0']*format.precision) - xlstyle.num_format_str = '0.%s%;[RED]-0.%s%'%(zeros, zeros) + xlstyle.num_format_str = '0.%s%%;[RED]-0.%s%%'%(zeros, zeros) format.scale = 1. else: xlstyle = None @@ -2376,12 +2376,14 @@ return format - def rec2excel(r, ws, formatd=None, rownum=0): + def rec2excel(r, ws, formatd=None, rownum=0, colnum=0): """ save record array r to excel pyExcelerator worksheet ws starting at rownum. if ws is string like, assume it is a filename and save to it + start writing at rownum, colnum + formatd is a dictionary mapping dtype name -> FormatXL instances The next rownum after writing is returned @@ -2399,6 +2401,12 @@ formatd = dict() formats = [] + font = excel.Font() + font.bold = True + + stylehdr = excel.XFStyle() + stylehdr.font = font + for i, name in enumerate(r.dtype.names): dt = r.dtype[name] format = formatd.get(name) @@ -2406,7 +2414,7 @@ format = defaultformatd.get(dt.type, FormatObj()) format = xlformat_factory(format) - ws.write(rownum, i, name) + ws.write(rownum, colnum+i, name, stylehdr) formats.append(format) rownum+=1 @@ -2419,12 +2427,12 @@ format = formats[i] val = format.toval(val) if format.xlstyle is None: - ws.write(rownum, i, val) + ws.write(rownum, colnum+i, val) else: if safe_isnan(val): - ws.write(rownum, i, 'NaN') + ws.write(rownum, colnum+i, 'NaN') else: - ws.write(rownum, i, val, format.xlstyle) + ws.write(rownum, colnum+i, val, format.xlstyle) rownum += 1 if autosave: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |