From: <md...@us...> - 2007-10-26 17:01:30
|
Revision: 4012 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4012&view=rev Author: mdboom Date: 2007-10-26 10:01:28 -0700 (Fri, 26 Oct 2007) Log Message: ----------- Added BboxTransformFrom/To for more efficient bounding box transforms. Modified Paths: -------------- branches/transforms/lib/matplotlib/axes.py branches/transforms/lib/matplotlib/figure.py branches/transforms/lib/matplotlib/legend.py branches/transforms/lib/matplotlib/patches.py branches/transforms/lib/matplotlib/projections/polar.py branches/transforms/lib/matplotlib/quiver.py branches/transforms/lib/matplotlib/transforms.py Modified: branches/transforms/lib/matplotlib/axes.py =================================================================== --- branches/transforms/lib/matplotlib/axes.py 2007-10-26 15:58:50 UTC (rev 4011) +++ branches/transforms/lib/matplotlib/axes.py 2007-10-26 17:01:28 UTC (rev 4012) @@ -560,8 +560,7 @@ """ self.dataLim = mtransforms.Bbox.unit() self.viewLim = mtransforms.Bbox.unit() - self.transAxes = mtransforms.BboxTransform( - mtransforms.Bbox.unit(), self.bbox) + self.transAxes = mtransforms.BboxTransformTo(self.bbox) # Transforms the x and y axis separately by a scale factor # It is assumed that this part will have non-linear components @@ -569,8 +568,8 @@ # An affine transformation on the data, generally to limit the # range of the axes - self.transLimits = mtransforms.BboxTransform( - mtransforms.TransformedBbox(self.viewLim, self.transScale), mtransforms.Bbox.unit()) + self.transLimits = mtransforms.BboxTransformFrom( + mtransforms.TransformedBbox(self.viewLim, self.transScale)) # The parentheses are important for efficiency here -- they # group the last two (which are usually affines) separately Modified: branches/transforms/lib/matplotlib/figure.py =================================================================== --- branches/transforms/lib/matplotlib/figure.py 2007-10-26 15:58:50 UTC (rev 4011) +++ branches/transforms/lib/matplotlib/figure.py 2007-10-26 17:01:28 UTC (rev 4012) @@ -19,7 +19,7 @@ from legend import Legend from ticker import FormatStrFormatter -from transforms import Affine2D, Bbox, BboxTransform, TransformedBbox +from transforms import Affine2D, Bbox, BboxTransformTo, TransformedBbox from cm import ScalarMappable from contour import ContourSet from projections import projection_factory, get_projection_names, \ @@ -136,7 +136,7 @@ self.frameon = frameon - self.transFigure = BboxTransform(Bbox.unit(), self.bbox) + self.transFigure = BboxTransformTo(self.bbox) self.figurePatch = Rectangle( xy=(0,0), width=1, height=1, Modified: branches/transforms/lib/matplotlib/legend.py =================================================================== --- branches/transforms/lib/matplotlib/legend.py 2007-10-26 15:58:50 UTC (rev 4011) +++ branches/transforms/lib/matplotlib/legend.py 2007-10-26 17:01:28 UTC (rev 4012) @@ -34,7 +34,7 @@ from patches import Patch, Rectangle, RegularPolygon, Shadow, bbox_artist, draw_bbox from collections import LineCollection, RegularPolyCollection from text import Text -from transforms import Affine2D, Bbox, BboxTransform +from transforms import Affine2D, Bbox, BboxTransformTo def line_cuts_bbox(line, bbox): """ Return True if and only if line cuts bbox. """ @@ -165,7 +165,7 @@ raise TypeError("Legend needs either Axes or Figure as parent") self.parent = parent self._offsetTransform = Affine2D() - self._parentTransform = BboxTransform(Bbox.unit(), parent.bbox) + self._parentTransform = BboxTransformTo(parent.bbox) Artist.set_transform(self, self._offsetTransform + self._parentTransform) if loc is None: Modified: branches/transforms/lib/matplotlib/patches.py =================================================================== --- branches/transforms/lib/matplotlib/patches.py 2007-10-26 15:58:50 UTC (rev 4011) +++ branches/transforms/lib/matplotlib/patches.py 2007-10-26 17:01:28 UTC (rev 4012) @@ -346,8 +346,7 @@ left, right = self.convert_xunits((xy[0], xy[0] + width)) bottom, top = self.convert_yunits((xy[1], xy[1] + height)) self._bbox = transforms.Bbox.from_extents(left, bottom, right, top) - self._rect_transform = transforms.BboxTransform( - transforms.Bbox.unit(), self._bbox) + self._rect_transform = transforms.BboxTransformTo(self._bbox) __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd def get_path(self): Modified: branches/transforms/lib/matplotlib/projections/polar.py =================================================================== --- branches/transforms/lib/matplotlib/projections/polar.py 2007-10-26 15:58:50 UTC (rev 4011) +++ branches/transforms/lib/matplotlib/projections/polar.py 2007-10-26 17:01:28 UTC (rev 4012) @@ -10,8 +10,8 @@ from matplotlib.patches import Circle from matplotlib.path import Path from matplotlib.ticker import Formatter, Locator -from matplotlib.transforms import Affine2D, Affine2DBase, Bbox, BboxTransform, \ - IdentityTransform, Transform, TransformWrapper +from matplotlib.transforms import Affine2D, Affine2DBase, Bbox, \ + BboxTransformTo, IdentityTransform, Transform, TransformWrapper class PolarAxes(Axes): """ @@ -179,7 +179,7 @@ def _set_lim_and_transforms(self): self.dataLim = Bbox.unit() self.viewLim = Bbox.unit() - self.transAxes = BboxTransform(Bbox.unit(), self.bbox) + self.transAxes = BboxTransformTo(self.bbox) # Transforms the x and y axis separately by a scale factor # It is assumed that this part will have non-linear components Modified: branches/transforms/lib/matplotlib/quiver.py =================================================================== --- branches/transforms/lib/matplotlib/quiver.py 2007-10-26 15:58:50 UTC (rev 4011) +++ branches/transforms/lib/matplotlib/quiver.py 2007-10-26 17:01:28 UTC (rev 4012) @@ -239,7 +239,7 @@ elif self.coord == 'inches': dx = ax.figure.dpi bb = transforms.Bbox.from_extents(0, 0, dx, dy) - trans = transforms.BboxTransform(Bbox.unit(), bb) + trans = transforms.BboxTransformTo(bb) self.set_transform(trans) else: raise ValueError('unrecognized coordinates') Modified: branches/transforms/lib/matplotlib/transforms.py =================================================================== --- branches/transforms/lib/matplotlib/transforms.py 2007-10-26 15:58:50 UTC (rev 4011) +++ branches/transforms/lib/matplotlib/transforms.py 2007-10-26 17:01:28 UTC (rev 4012) @@ -211,6 +211,9 @@ def __array__(self, *args, **kwargs): return self.get_points() + def is_unit(self): + return list(self.get_points().flatten()) == [0., 0., 1., 1.] + def _get_x0(self): return self.get_points()[0, 0] x0 = property(_get_x0) @@ -1830,6 +1833,86 @@ self._invalid = 0 return self._mtx get_matrix.__doc__ = Affine2DBase.get_matrix.__doc__ + + +class BboxTransformTo(Affine2DBase): + """ + BboxTransformSimple linearly transforms points from the unit Bbox + to another Bbox. + """ + is_separable = True + + def __init__(self, boxout): + """ + Create a new BboxTransform that linearly transforms points + from the unit Bbox to boxout. + """ + assert boxout.is_bbox + + Affine2DBase.__init__(self) + self._boxout = boxout + self.set_children(boxout) + self._mtx = None + self._inverted = None + + def __repr__(self): + return "BboxTransformTo(%s)" % (self._boxout) + __str__ = __repr__ + + def get_matrix(self): + if self._invalid: + outl, outb, outw, outh = self._boxout.bounds + if DEBUG and (outw == 0 or outh == 0): + raise ValueError("Transforming to a singular bounding box.") + self._mtx = npy.array([[outw, 0.0, outl], + [ 0.0, outh, outb], + [ 0.0, 0.0, 1.0]], + npy.float_) + self._inverted = None + self._invalid = 0 + return self._mtx + get_matrix.__doc__ = Affine2DBase.get_matrix.__doc__ + + +class BboxTransformFrom(Affine2DBase): + """ + BboxTransform linearly transforms points from one Bbox to the unit + Bbox. + """ + is_separable = True + + def __init__(self, boxin): + """ + Create a new BboxTransform that linearly transforms points + from boxin to the unit Bbox. + """ + assert boxin.is_bbox + + Affine2DBase.__init__(self) + self._boxin = boxin + self.set_children(boxin) + self._mtx = None + self._inverted = None + + def __repr__(self): + return "BboxTransformFrom(%s)" % (self._boxin) + __str__ = __repr__ + + def get_matrix(self): + if self._invalid: + inl, inb, inw, inh = self._boxin.bounds + if DEBUG and (inw == 0 or inh == 0): + raise ValueError("Transforming from a singular bounding box.") + x_scale = 1.0 / inw + y_scale = 1.0 / inh + self._mtx = npy.array([[x_scale, 0.0 , (-inl*x_scale)], + [0.0 , y_scale, (-inb*y_scale)], + [0.0 , 0.0 , 1.0 ]], + npy.float_) + self._inverted = None + self._invalid = 0 + return self._mtx + get_matrix.__doc__ = Affine2DBase.get_matrix.__doc__ class TransformedPath(TransformNode): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-10-26 18:00:26
|
Revision: 4017 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4017&view=rev Author: mdboom Date: 2007-10-26 11:00:23 -0700 (Fri, 26 Oct 2007) Log Message: ----------- Removed unused imports. Modified Paths: -------------- branches/transforms/lib/matplotlib/_mathtext_data.py branches/transforms/lib/matplotlib/art3d.py branches/transforms/lib/matplotlib/artist.py branches/transforms/lib/matplotlib/axes.py branches/transforms/lib/matplotlib/axes3d.py branches/transforms/lib/matplotlib/axis.py branches/transforms/lib/matplotlib/backend_bases.py branches/transforms/lib/matplotlib/collections.py branches/transforms/lib/matplotlib/colorbar.py branches/transforms/lib/matplotlib/colors.py branches/transforms/lib/matplotlib/contour.py branches/transforms/lib/matplotlib/dates.py branches/transforms/lib/matplotlib/figure.py branches/transforms/lib/matplotlib/finance.py branches/transforms/lib/matplotlib/font_manager.py branches/transforms/lib/matplotlib/fontconfig_pattern.py branches/transforms/lib/matplotlib/image.py branches/transforms/lib/matplotlib/legend.py branches/transforms/lib/matplotlib/lines.py branches/transforms/lib/matplotlib/mathtext.py branches/transforms/lib/matplotlib/mlab.py branches/transforms/lib/matplotlib/patches.py branches/transforms/lib/matplotlib/proj3d.py branches/transforms/lib/matplotlib/scale.py branches/transforms/lib/matplotlib/table.py branches/transforms/lib/matplotlib/texmanager.py branches/transforms/lib/matplotlib/text.py branches/transforms/lib/matplotlib/ticker.py branches/transforms/lib/matplotlib/units.py Modified: branches/transforms/lib/matplotlib/_mathtext_data.py =================================================================== --- branches/transforms/lib/matplotlib/_mathtext_data.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/_mathtext_data.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -14,8 +14,6 @@ print charcode, glyphind """ -from sets import Set - latex_to_bakoma = { r'\oint' : ('cmex10', 45), r'\bigodot' : ('cmex10', 50), Modified: branches/transforms/lib/matplotlib/art3d.py =================================================================== --- branches/transforms/lib/matplotlib/art3d.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/art3d.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -10,7 +10,6 @@ import text from colors import Normalize -from cm import jet import numpy as npy import proj3d Modified: branches/transforms/lib/matplotlib/artist.py =================================================================== --- branches/transforms/lib/matplotlib/artist.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/artist.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -1,9 +1,7 @@ from __future__ import division -import sys, re, warnings +import re, warnings from cbook import iterable, flatten -from transforms import Affine2D, Bbox, IdentityTransform, TransformedBbox, \ - TransformedPath -import matplotlib.units as units +from transforms import Bbox, IdentityTransform, TransformedBbox, TransformedPath ## Note, matplotlib artists use the doc strings for set and get # methods to enable the introspection methods of setp and getp. Every Modified: branches/transforms/lib/matplotlib/axes.py =================================================================== --- branches/transforms/lib/matplotlib/axes.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/axes.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -1,5 +1,5 @@ from __future__ import division, generators -import math, sys, warnings, copy, new +import math, warnings, new import numpy as npy @@ -9,7 +9,6 @@ rcParams = matplotlib.rcParams from matplotlib import artist as martist -from matplotlib import agg from matplotlib import axis as maxis from matplotlib import cbook from matplotlib import collections as mcoll @@ -21,9 +20,7 @@ from matplotlib import legend as mlegend from matplotlib import lines as mlines from matplotlib import mlab -from matplotlib import cm from matplotlib import patches as mpatches -from matplotlib import path as mpath from matplotlib import quiver as mquiver from matplotlib import scale as mscale from matplotlib import table as mtable Modified: branches/transforms/lib/matplotlib/axes3d.py =================================================================== --- branches/transforms/lib/matplotlib/axes3d.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/axes3d.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -11,12 +11,10 @@ import random -import matplotlib from axes import Axes import cbook from transforms import unit_bbox -import figure import numpy as npy from colors import Normalize Modified: branches/transforms/lib/matplotlib/axis.py =================================================================== --- branches/transforms/lib/matplotlib/axis.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/axis.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -2,23 +2,19 @@ Classes for the ticks and x and y axis """ from __future__ import division -import copy -import math -import re -import sys from artist import Artist, setp from cbook import enumerate, silent_list, popall, CallbackRegistry from lines import Line2D, TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN from matplotlib import rcParams from patches import bbox_artist -from ticker import NullFormatter, FixedFormatter, ScalarFormatter, LogFormatter, LogFormatterMathtext -from ticker import NullLocator, FixedLocator, LinearLocator, LogLocator, AutoLocator +from ticker import NullFormatter, FixedFormatter, ScalarFormatter +from ticker import NullLocator, FixedLocator, AutoLocator from font_manager import FontProperties -from text import Text, TextWithDash, _process_text_args -from transforms import Affine2D, Bbox, blended_transform_factory, interval_contains, \ - interval_contains_open, IdentityTransform +from text import Text, TextWithDash +from transforms import Affine2D, Bbox, blended_transform_factory, \ + interval_contains from patches import bbox_artist from scale import scale_factory Modified: branches/transforms/lib/matplotlib/backend_bases.py =================================================================== --- branches/transforms/lib/matplotlib/backend_bases.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/backend_bases.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -4,10 +4,9 @@ """ from __future__ import division -import os, sys, warnings, copy, weakref +import os import numpy as npy -import matplotlib.numerix.npyma as ma import matplotlib.cbook as cbook import matplotlib.colors as colors import matplotlib.transforms as transforms Modified: branches/transforms/lib/matplotlib/collections.py =================================================================== --- branches/transforms/lib/matplotlib/collections.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/collections.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -16,7 +16,6 @@ import matplotlib.transforms as transforms import matplotlib.artist as artist import matplotlib.backend_bases as backend_bases -import matplotlib.nxutils as nxutils import matplotlib.path as path class Collection(artist.Artist, cm.ScalarMappable): Modified: branches/transforms/lib/matplotlib/colorbar.py =================================================================== --- branches/transforms/lib/matplotlib/colorbar.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/colorbar.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -21,7 +21,6 @@ import matplotlib.cm as cm import matplotlib.ticker as ticker import matplotlib.cbook as cbook -import matplotlib.transforms as transforms import matplotlib.lines as lines import matplotlib.patches as patches import matplotlib.collections as collections Modified: branches/transforms/lib/matplotlib/colors.py =================================================================== --- branches/transforms/lib/matplotlib/colors.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/colors.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -34,7 +34,6 @@ 'chartreuse' are supported. """ import re -import warnings import numpy as npy import matplotlib.numerix.npyma as ma import matplotlib.cbook as cbook Modified: branches/transforms/lib/matplotlib/contour.py =================================================================== --- branches/transforms/lib/matplotlib/contour.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/contour.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -10,7 +10,6 @@ import matplotlib._cntr as _cntr import matplotlib.path as path import matplotlib.ticker as ticker -import matplotlib.transforms as transforms import matplotlib.cm as cm import matplotlib.colors as colors import matplotlib.collections as collections Modified: branches/transforms/lib/matplotlib/dates.py =================================================================== --- branches/transforms/lib/matplotlib/dates.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/dates.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -76,8 +76,7 @@ DateIndexFormatter - date plots with implicit x indexing. """ -import sys, re, time, math, datetime -import locale +import re, time, math, datetime import pytz import matplotlib Modified: branches/transforms/lib/matplotlib/figure.py =================================================================== --- branches/transforms/lib/matplotlib/figure.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/figure.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -1,8 +1,6 @@ """ Figure class -- add docstring here! """ -import sys - import numpy as npy import artist @@ -11,20 +9,15 @@ from cbook import flatten, allequal, Stack, iterable, dedent import _image import colorbar as cbar -from colors import Normalize, rgb2hex from image import FigureImage from matplotlib import rcParams -from patches import Rectangle, Polygon +from patches import Rectangle from text import Text, _process_text_args from legend import Legend -from ticker import FormatStrFormatter from transforms import Affine2D, Bbox, BboxTransformTo, TransformedBbox -from cm import ScalarMappable -from contour import ContourSet from projections import projection_factory, get_projection_names, \ get_projection_class -import warnings class SubplotParams: """ Modified: branches/transforms/lib/matplotlib/finance.py =================================================================== --- branches/transforms/lib/matplotlib/finance.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/finance.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -15,8 +15,7 @@ import numpy as npy from matplotlib import verbose, get_configdir -from artist import Artist -from dates import date2num, num2date +from dates import date2num from matplotlib.cbook import Bunch from matplotlib.collections import LineCollection, PolyCollection from matplotlib.colors import colorConverter Modified: branches/transforms/lib/matplotlib/font_manager.py =================================================================== --- branches/transforms/lib/matplotlib/font_manager.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/font_manager.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -33,12 +33,12 @@ see license/LICENSE_TTFQUERY. """ -import os, sys, glob, shutil +import os, sys, glob from sets import Set import matplotlib from matplotlib import afm from matplotlib import ft2font -from matplotlib import rcParams, get_home, get_configdir +from matplotlib import rcParams, get_configdir from matplotlib.cbook import is_string_like from matplotlib.fontconfig_pattern import \ parse_fontconfig_pattern, generate_fontconfig_pattern Modified: branches/transforms/lib/matplotlib/fontconfig_pattern.py =================================================================== --- branches/transforms/lib/matplotlib/fontconfig_pattern.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/fontconfig_pattern.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -18,7 +18,7 @@ License : matplotlib license (PSF compatible) """ import re -from matplotlib.pyparsing import Literal, OneOrMore, ZeroOrMore, \ +from matplotlib.pyparsing import Literal, ZeroOrMore, \ Optional, Regex, StringEnd, ParseException, Suppress family_punc = r'\\\-:,' Modified: branches/transforms/lib/matplotlib/image.py =================================================================== --- branches/transforms/lib/matplotlib/image.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/image.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -4,7 +4,7 @@ """ from __future__ import division -import sys, os +import os import numpy as npy import numerix.ma as ma Modified: branches/transforms/lib/matplotlib/legend.py =================================================================== --- branches/transforms/lib/matplotlib/legend.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/legend.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -21,17 +21,17 @@ up the legend """ from __future__ import division -import copy, sys, warnings +import warnings import numpy as npy -from matplotlib import verbose, rcParams +from matplotlib import rcParams from artist import Artist -from cbook import enumerate, is_string_like, iterable, silent_list +from cbook import is_string_like, iterable, silent_list from font_manager import FontProperties from lines import Line2D from mlab import segments_intersect -from patches import Patch, Rectangle, RegularPolygon, Shadow, bbox_artist, draw_bbox +from patches import Patch, Rectangle, Shadow, bbox_artist from collections import LineCollection, RegularPolyCollection from text import Text from transforms import Affine2D, Bbox, BboxTransformTo Modified: branches/transforms/lib/matplotlib/lines.py =================================================================== --- branches/transforms/lib/matplotlib/lines.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/lines.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -6,14 +6,12 @@ # TODO: expose cap and join style attrs from __future__ import division -import sys, math, warnings - import numpy as npy import numerix.ma as ma from matplotlib import verbose import artist -from artist import Artist, setp +from artist import Artist from cbook import iterable, is_string_like, is_numlike from colors import colorConverter from path import Path Modified: branches/transforms/lib/matplotlib/mathtext.py =================================================================== --- branches/transforms/lib/matplotlib/mathtext.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/mathtext.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -124,29 +124,27 @@ """ from __future__ import division -import os, sys +import os from cStringIO import StringIO -from math import floor, ceil +from math import ceil from sets import Set import unicodedata from warnings import warn from numpy import inf, isinf -from matplotlib import verbose -from matplotlib.pyparsing import Literal, Word, OneOrMore, ZeroOrMore, \ - Combine, Group, Optional, Forward, NotAny, alphas, nums, alphanums, \ - StringStart, StringEnd, ParseFatalException, FollowedBy, Regex, \ - operatorPrecedence, opAssoc, ParseResults, Or, Suppress, oneOf, \ - ParseException, MatchFirst, NoMatch, Empty +from matplotlib.pyparsing import Combine, Group, Optional, Forward, \ + Literal, OneOrMore, ZeroOrMore, ParseException, Empty, \ + ParseResults, Suppress, oneOf, StringEnd, ParseFatalException, \ + FollowedBy, Regex from matplotlib.afm import AFM -from matplotlib.cbook import enumerate, iterable, Bunch, get_realpath_and_stat, \ +from matplotlib.cbook import Bunch, get_realpath_and_stat, \ is_string_like from matplotlib.ft2font import FT2Font, FT2Image, KERNING_DEFAULT, LOAD_DEFAULT, LOAD_NO_HINTING from matplotlib.font_manager import findfont, FontProperties from matplotlib._mathtext_data import latex_to_bakoma, \ - latex_to_standard, tex2uni, type12uni, tex2type1, uni2type1, \ + latex_to_standard, tex2uni, tex2type1, uni2type1, \ latex_to_cmex from matplotlib import get_data_path, rcParams Modified: branches/transforms/lib/matplotlib/mlab.py =================================================================== --- branches/transforms/lib/matplotlib/mlab.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/mlab.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -55,7 +55,7 @@ """ from __future__ import division -import sys, datetime, csv, warnings +import csv, warnings import numpy as npy Modified: branches/transforms/lib/matplotlib/patches.py =================================================================== --- branches/transforms/lib/matplotlib/patches.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/patches.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -6,10 +6,7 @@ import matplotlib.cbook as cbook import matplotlib.artist as artist import matplotlib.colors as colors -import matplotlib.lines as lines import matplotlib.transforms as transforms -import matplotlib.nxutils as nxutils -import matplotlib.mlab as mlab import matplotlib.artist as artist from matplotlib.path import Path Modified: branches/transforms/lib/matplotlib/proj3d.py =================================================================== --- branches/transforms/lib/matplotlib/proj3d.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/proj3d.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -9,7 +9,6 @@ from patches import Circle import numpy as npy import numpy.linalg as linalg -from math import sqrt def _hide_cross(a,b): """ Modified: branches/transforms/lib/matplotlib/scale.py =================================================================== --- branches/transforms/lib/matplotlib/scale.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/scale.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -1,12 +1,9 @@ import numpy as npy from numpy import ma -from numpy.linalg import inv -from ticker import NullFormatter, FixedFormatter, ScalarFormatter, \ - LogFormatter, LogFormatterMathtext -from ticker import NullLocator, FixedLocator, LinearLocator, LogLocator, \ - AutoLocator -from transforms import Transform, composite_transform_factory, IdentityTransform +from ticker import NullFormatter, ScalarFormatter, LogFormatterMathtext +from ticker import NullLocator, LogLocator, AutoLocator +from transforms import Transform, IdentityTransform class ScaleBase(object): def set_default_locators_and_formatters(self, axis): Modified: branches/transforms/lib/matplotlib/table.py =================================================================== --- branches/transforms/lib/matplotlib/table.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/table.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -20,14 +20,12 @@ """ from __future__ import division -import sys, warnings +import warnings -from matplotlib import verbose - import artist from artist import Artist from patches import Rectangle -from cbook import enumerate, is_string_like, flatten +from cbook import is_string_like from text import Text from transforms import Bbox Modified: branches/transforms/lib/matplotlib/texmanager.py =================================================================== --- branches/transforms/lib/matplotlib/texmanager.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/texmanager.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -33,7 +33,7 @@ """ -import copy, glob, md5, os, shutil, sys, warnings +import copy, glob, md5, os, shutil, sys import numpy as npy import matplotlib as mpl from matplotlib import rcParams Modified: branches/transforms/lib/matplotlib/text.py =================================================================== --- branches/transforms/lib/matplotlib/text.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/text.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -2,17 +2,15 @@ Figure and Axes text """ from __future__ import division -import re, math +import math import numpy as npy -import matplotlib -from matplotlib import verbose from matplotlib import cbook from matplotlib import rcParams import artist from artist import Artist -from cbook import enumerate, is_string_like, maxdict, is_numlike +from cbook import enumerate, is_string_like, maxdict from font_manager import FontProperties from patches import bbox_artist, YAArrow from transforms import Affine2D, Bbox Modified: branches/transforms/lib/matplotlib/ticker.py =================================================================== --- branches/transforms/lib/matplotlib/ticker.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/ticker.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -104,10 +104,9 @@ from __future__ import division -import sys, os, re, time, math, warnings +import math import numpy as npy -import matplotlib as mpl -from matplotlib import verbose, rcParams +from matplotlib import rcParams from matplotlib import cbook from matplotlib import transforms as mtransforms Modified: branches/transforms/lib/matplotlib/units.py =================================================================== --- branches/transforms/lib/matplotlib/units.py 2007-10-26 17:57:02 UTC (rev 4016) +++ branches/transforms/lib/matplotlib/units.py 2007-10-26 18:00:23 UTC (rev 4017) @@ -43,7 +43,6 @@ units.registry[datetime.date] = DateConverter() """ -import matplotlib from matplotlib.cbook import iterable, is_numlike class AxisInfo: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-10-29 18:37:24
|
Revision: 4060 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4060&view=rev Author: mdboom Date: 2007-10-29 11:37:17 -0700 (Mon, 29 Oct 2007) Log Message: ----------- Fix clip path in polar plot legend. Modified Paths: -------------- branches/transforms/lib/matplotlib/artist.py branches/transforms/lib/matplotlib/backend_bases.py Modified: branches/transforms/lib/matplotlib/artist.py =================================================================== --- branches/transforms/lib/matplotlib/artist.py 2007-10-29 18:23:24 UTC (rev 4059) +++ branches/transforms/lib/matplotlib/artist.py 2007-10-29 18:37:17 UTC (rev 4060) @@ -309,6 +309,7 @@ if transform is None: if isinstance(path, Rectangle): self.clipbox = TransformedBbox(Bbox.unit(), path.get_transform()) + self._clippath = None success = True elif isinstance(path, Patch): self._clippath = TransformedPath( Modified: branches/transforms/lib/matplotlib/backend_bases.py =================================================================== --- branches/transforms/lib/matplotlib/backend_bases.py 2007-10-29 18:23:24 UTC (rev 4059) +++ branches/transforms/lib/matplotlib/backend_bases.py 2007-10-29 18:37:17 UTC (rev 4060) @@ -326,13 +326,15 @@ def get_clip_rectangle(self): """ - Return the clip rectangle as (left, bottom, width, height) + Return the clip rectangle as a Bbox instance """ return self._cliprect def get_clip_path(self): """ - Return the clip path + Return the clip path in the form (path, transform), where path + is a path.Path instance, and transform as an affine transform + to apply to the path before clipping. """ if self._clippath is not None: return self._clippath.get_transformed_path_and_affine() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-11-06 15:38:04
|
Revision: 4122 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4122&view=rev Author: mdboom Date: 2007-11-06 07:37:44 -0800 (Tue, 06 Nov 2007) Log Message: ----------- Minor speed improvement (thanks to Eric Firing). Also use matplotlib.numerix.npyma instead of numpy.ma Modified Paths: -------------- branches/transforms/lib/matplotlib/path.py branches/transforms/lib/matplotlib/transforms.py Modified: branches/transforms/lib/matplotlib/path.py =================================================================== --- branches/transforms/lib/matplotlib/path.py 2007-11-06 13:14:08 UTC (rev 4121) +++ branches/transforms/lib/matplotlib/path.py 2007-11-06 15:37:44 UTC (rev 4122) @@ -7,7 +7,7 @@ import math import numpy as npy -from numpy import ma as ma +from matplotlib.numerix import npyma as ma from matplotlib._path import point_in_path, get_path_extents, \ point_in_path_collection @@ -86,7 +86,8 @@ resulting path will be compressed, with MOVETO codes inserted in the correct places to jump over the masked regions. """ - if not ma.isMaskedArray(vertices): + mask = ma.getmask(vertices) + if not mask: vertices = ma.asarray(vertices, npy.float_) if codes is None: @@ -112,7 +113,6 @@ # itself), are not expected to deal with masked arrays, so we # must remove them from the array (using compressed), and add # MOVETO commands to the codes array accordingly. - mask = ma.getmask(vertices) if mask is not ma.nomask: mask1d = ma.mask_or(mask[:, 0], mask[:, 1]) vertices = ma.compress(npy.invert(mask1d), vertices, 0) @@ -125,7 +125,6 @@ assert vertices.ndim == 2 assert vertices.shape[1] == 2 - assert codes.ndim == 1 self._codes = codes self._vertices = vertices Modified: branches/transforms/lib/matplotlib/transforms.py =================================================================== --- branches/transforms/lib/matplotlib/transforms.py 2007-11-06 13:14:08 UTC (rev 4121) +++ branches/transforms/lib/matplotlib/transforms.py 2007-11-06 15:37:44 UTC (rev 4122) @@ -24,7 +24,7 @@ """ import numpy as npy -from numpy import ma as ma +from matplotlib.numerix import npyma as ma from numpy.linalg import inv from weakref import WeakKeyDictionary This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-11-06 19:48:44
|
Revision: 4134 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4134&view=rev Author: mdboom Date: 2007-11-06 11:48:40 -0800 (Tue, 06 Nov 2007) Log Message: ----------- Use "from matplotlib.numerix import npyma as ma" Modified Paths: -------------- branches/transforms/lib/matplotlib/image.py branches/transforms/lib/matplotlib/lines.py branches/transforms/lib/matplotlib/scale.py Modified: branches/transforms/lib/matplotlib/image.py =================================================================== --- branches/transforms/lib/matplotlib/image.py 2007-11-06 19:46:45 UTC (rev 4133) +++ branches/transforms/lib/matplotlib/image.py 2007-11-06 19:48:40 UTC (rev 4134) @@ -7,7 +7,7 @@ import os import numpy as npy -import numerix.ma as ma +from matplotlib.numerix import npyma as ma from matplotlib import rcParams from artist import Artist Modified: branches/transforms/lib/matplotlib/lines.py =================================================================== --- branches/transforms/lib/matplotlib/lines.py 2007-11-06 19:46:45 UTC (rev 4133) +++ branches/transforms/lib/matplotlib/lines.py 2007-11-06 19:48:40 UTC (rev 4134) @@ -8,7 +8,7 @@ import numpy as npy -import numerix.ma as ma +from matplotlib.numerix import npyma as ma from matplotlib import verbose import artist from artist import Artist Modified: branches/transforms/lib/matplotlib/scale.py =================================================================== --- branches/transforms/lib/matplotlib/scale.py 2007-11-06 19:46:45 UTC (rev 4133) +++ branches/transforms/lib/matplotlib/scale.py 2007-11-06 19:48:40 UTC (rev 4134) @@ -1,5 +1,5 @@ import numpy as npy -from numpy import ma +from matplotlib.numerix import npyma as ma from ticker import NullFormatter, ScalarFormatter, LogFormatterMathtext from ticker import NullLocator, LogLocator, AutoLocator This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-11-06 21:33:39
|
Revision: 4136 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4136&view=rev Author: mdboom Date: 2007-11-06 13:33:37 -0800 (Tue, 06 Nov 2007) Log Message: ----------- Speed up pcolor_demo.py "benchmark" initialization by a factor of 2. Cache the automatically created path codes by their length. pcolor, quadmesh etc. create lots of polylines of the same length, and there is no need to create a new identical codes array each time. (Definite speed improvement, incredible memory improvement). Change the default behavior to create open paths (which don't result in a memory copy). Fix places that were relying on automatically-created closed paths to create closed paths themselves (and thus avoiding a copy). Modified Paths: -------------- branches/transforms/lib/matplotlib/axes.py branches/transforms/lib/matplotlib/collections.py branches/transforms/lib/matplotlib/contour.py branches/transforms/lib/matplotlib/lines.py branches/transforms/lib/matplotlib/patches.py branches/transforms/lib/matplotlib/path.py Modified: branches/transforms/lib/matplotlib/axes.py =================================================================== --- branches/transforms/lib/matplotlib/axes.py 2007-11-06 20:02:07 UTC (rev 4135) +++ branches/transforms/lib/matplotlib/axes.py 2007-11-06 21:33:37 UTC (rev 4136) @@ -4680,9 +4680,10 @@ xy = npy.concatenate((X1[:,newaxis], Y1[:,newaxis], X2[:,newaxis], Y2[:,newaxis], X3[:,newaxis], Y3[:,newaxis], - X4[:,newaxis], Y4[:,newaxis]), + X4[:,newaxis], Y4[:,newaxis], + X1[:,newaxis], Y1[:,newaxis]), axis=1) - verts = xy.reshape((npoly, 4, 2)) + verts = xy.reshape((npoly, 5, 2)) #verts = zip(zip(X1,Y1),zip(X2,Y2),zip(X3,Y3),zip(X4,Y4)) @@ -4696,6 +4697,7 @@ kwargs.setdefault('edgecolors', edgecolors) kwargs.setdefault('antialiaseds', (0,)) kwargs.setdefault('linewidths', (0.25,)) + kwargs['closed'] = False collection = mcoll.PolyCollection(verts, **kwargs) Modified: branches/transforms/lib/matplotlib/collections.py =================================================================== --- branches/transforms/lib/matplotlib/collections.py 2007-11-06 20:02:07 UTC (rev 4135) +++ branches/transforms/lib/matplotlib/collections.py 2007-11-06 21:33:37 UTC (rev 4136) @@ -390,14 +390,15 @@ paths = [] # We could let the Path constructor generate the codes for us, # but this is faster, since we know they'll always be the same - codes = npy.array([Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO]) + codes = npy.array([Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY]) for m in xrange(meshHeight): for n in xrange(meshWidth): paths.append(Path( [c[m , n], c[m , n+1], c[m+1, n+1], - c[m+1, n]], + c[m+1, n], + c[m , n]], codes)) self._paths = paths @@ -424,13 +425,14 @@ %(Collection)s """ + self.closed = kwargs.pop("closed", True) Collection.__init__(self,**kwargs) self.set_verts(verts) __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd def set_verts(self, verts): '''This allows one to delay initialization of the vertices.''' - self._paths = [mpath.Path(v, closed=True) for v in verts] + self._paths = [mpath.Path(v, closed=self.closed) for v in verts] def get_paths(self): return self._paths @@ -611,7 +613,7 @@ segments = [npy.asarray(seg, npy.float_) for seg in segments] if self._uniform_offsets is not None: segments = self._add_offsets(segments) - self._paths = [mpath.Path(seg, closed=False) for seg in segments] + self._paths = [mpath.Path(seg) for seg in segments] set_verts = set_segments # for compatibility with PolyCollection Modified: branches/transforms/lib/matplotlib/contour.py =================================================================== --- branches/transforms/lib/matplotlib/contour.py 2007-11-06 20:02:07 UTC (rev 4135) +++ branches/transforms/lib/matplotlib/contour.py 2007-11-06 21:33:37 UTC (rev 4136) @@ -360,9 +360,9 @@ if inline: new = self.break_linecontour(linecontour, rotation, lw, ind) if len(new[0]): - paths[segNum] = path.Path(new[0], closed=False) + paths[segNum] = path.Path(new[0]) if len(new[1]): - additions.append(path.Path(new[1], closed=False)) + additions.append(path.Path(new[1])) paths.extend(additions) Modified: branches/transforms/lib/matplotlib/lines.py =================================================================== --- branches/transforms/lib/matplotlib/lines.py 2007-11-06 20:02:07 UTC (rev 4135) +++ branches/transforms/lib/matplotlib/lines.py 2007-11-06 21:33:37 UTC (rev 4136) @@ -429,7 +429,7 @@ self._y = self._xy[:, 1] # just a view # Masked arrays are now handled by the Path class itself - self._path = Path(self._xy, closed=False) + self._path = Path(self._xy) self._transformed_path = TransformedPath(self._path, self.get_transform()) @@ -683,7 +683,7 @@ steps[0::2, 0], steps[1::2, 0] = vertices[:, 0], vertices[:-1, 0] steps[0::2, 1], steps[1:-1:2, 1] = vertices[:, 1], vertices[1:, 1] - path = Path(steps, closed=False) + path = Path(steps) self._draw_solid(renderer, gc, path, trans) @@ -694,7 +694,7 @@ steps[::2, 0], steps[1:-1:2, 0] = vertices[:, 0], vertices[1:, 0] steps[0::2, 1], steps[1::2, 1] = vertices[:, 1], vertices[:-1, 1] - path = Path(steps, closed=False) + path = Path(steps) self._draw_solid(renderer, gc, path, trans) @@ -708,7 +708,7 @@ steps[-1, 0] = vertices[-1, 0] steps[0::2, 1], steps[1::2, 1] = vertices[:, 1], vertices[:, 1] - path = Path(steps, closed=False) + path = Path(steps) self._draw_solid(renderer, gc, path, trans) @@ -756,7 +756,7 @@ rgbFace) - _triangle_path = Path([[0.0, 1.0], [-1.0, -1.0], [1.0, -1.0]]) + _triangle_path = Path([[0.0, 1.0], [-1.0, -1.0], [1.0, -1.0], [0.0, 1.0]]) def _draw_triangle_up(self, renderer, gc, path, path_trans): offset = 0.5*renderer.points_to_pixels(self._markersize) transform = Affine2D().scale(offset, offset) @@ -838,7 +838,7 @@ path, path_trans, rgbFace) - _line_marker_path = Path([[0.0, -1.0], [0.0, 1.0]], closed=False) + _line_marker_path = Path([[0.0, -1.0], [0.0, 1.0]]) def _draw_vline(self, renderer, gc, path, path_trans): offset = 0.5*renderer.points_to_pixels(self._markersize) transform = Affine2D().scale(offset) @@ -853,7 +853,7 @@ path, path_trans) - _tickhoriz_path = Path([[0.0, 0.5], [1.0, 0.5]], closed=False) + _tickhoriz_path = Path([[0.0, 0.5], [1.0, 0.5]]) def _draw_tickleft(self, renderer, gc, path, path_trans): offset = renderer.points_to_pixels(self._markersize) marker_transform = Affine2D().scale(-offset, 1.0) @@ -868,7 +868,7 @@ path, path_trans) - _tickvert_path = Path([[-0.5, 0.0], [-0.5, 1.0]], closed=False) + _tickvert_path = Path([[-0.5, 0.0], [-0.5, 1.0]]) def _draw_tickup(self, renderer, gc, path, path_trans): offset = renderer.points_to_pixels(self._markersize) marker_transform = Affine2D().scale(1.0, offset) Modified: branches/transforms/lib/matplotlib/patches.py =================================================================== --- branches/transforms/lib/matplotlib/patches.py 2007-11-06 20:02:07 UTC (rev 4135) +++ branches/transforms/lib/matplotlib/patches.py 2007-11-06 21:33:37 UTC (rev 4136) @@ -578,7 +578,7 @@ [ 0.0, 0.1 ], [ 0.0, -0.1], [ 0.8, -0.1 ], [ 0.8, -0.3], [ 1.0, 0.0 ], [ 0.8, 0.3], - [ 0.8, 0.1 ] ] ) + [ 0.8, 0.1 ], [ 0.0, 0.1] ] ) def __init__( self, x, y, dx, dy, width=1.0, **kwargs ): """Draws an arrow, starting at (x,y), direction and length @@ -727,8 +727,8 @@ xc1, yc1, xc2, yc2 = self.getpoints(x1, y1, xm, ym, k1) xd1, yd1, xd2, yd2 = self.getpoints(x1, y1, xm, ym, k2) - xs = self.convert_xunits([xb1, xb2, xc2, xd2, x1, xd1, xc1]) - ys = self.convert_yunits([yb1, yb2, yc2, yd2, y1, yd1, yc1]) + xs = self.convert_xunits([xb1, xb2, xc2, xd2, x1, xd1, xc1, xb1]) + ys = self.convert_yunits([yb1, yb2, yc2, yd2, y1, yd1, yc1, yb1]) return Path(zip(xs, ys)) Modified: branches/transforms/lib/matplotlib/path.py =================================================================== --- branches/transforms/lib/matplotlib/path.py 2007-11-06 20:02:07 UTC (rev 4135) +++ branches/transforms/lib/matplotlib/path.py 2007-11-06 21:33:37 UTC (rev 4136) @@ -5,6 +5,7 @@ """ import math +from weakref import WeakValueDictionary import numpy as npy from matplotlib.numerix import npyma as ma @@ -65,8 +66,11 @@ NUM_VERTICES = [1, 1, 1, 2, 3, 1] code_type = npy.uint8 + + _open_codes_cache = WeakValueDictionary() + _closed_codes_cache = WeakValueDictionary() - def __init__(self, vertices, codes=None, closed=True): + def __init__(self, vertices, codes=None, closed=False): """ Create a new path with the given vertices and codes. @@ -88,25 +92,37 @@ resulting path will be compressed, with MOVETO codes inserted in the correct places to jump over the masked regions. """ - mask = ma.nomask if ma.isMaskedArray(vertices): mask = ma.getmask(vertices) else: vertices = npy.asarray(vertices, npy.float_) - + mask = ma.nomask + if codes is None: - if len(vertices) == 0: - codes = npy.zeros((0, ), self.code_type) - elif closed: - codes = self.LINETO * npy.ones( - vertices.shape[0] + 1, self.code_type) - codes[0] = self.MOVETO - codes[-1] = self.CLOSEPOLY + if closed: + # MGDTODO: Remove me once efficiency concerns are + # taken care of. + warnings.warn(""" +EFFICIENCY CONCERN: Having the Path constructor create a closed +polyline automatically is not always the most efficient way to do +things, since it causes a memory copy of the vertices array. If the +caller can easily close the polygon itself it should do so. +""") + codes = self._closed_codes_cache.get(len(vertices)) + if codes is None: + codes = self.LINETO * npy.ones( + vertices.shape[0] + 1, self.code_type) + codes[0] = self.MOVETO + codes[-1] = self.CLOSEPOLY + self._closed_codes_cache[len(vertices)] = codes vertices = npy.concatenate((vertices, [vertices[0]])) - else: - codes = self.LINETO * npy.ones( - vertices.shape[0], self.code_type) - codes[0] = self.MOVETO + else: + codes = self._open_codes_cache.get(len(vertices)) + if codes is None: + codes = self.LINETO * npy.ones( + vertices.shape[0], self.code_type) + codes[0] = self.MOVETO + self._open_codes_cache[len(vertices)] = codes else: codes = npy.asarray(codes, self.code_type) assert codes.ndim == 1 @@ -222,7 +238,7 @@ """ if cls._unit_rectangle is None: cls._unit_rectangle = \ - Path([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]]) + Path([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0], [0.0, 0.0]]) return cls._unit_rectangle unit_rectangle = classmethod(unit_rectangle) @@ -308,7 +324,7 @@ [-1.0, 0.0]], npy.float_) - codes = cls.CURVE4 * npy.ones((len(vertices))) + codes = cls.CURVE4 * npy.ones(14) codes[0] = cls.MOVETO codes[-1] = cls.CLOSEPOLY This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-11-07 21:21:33
|
Revision: 4154 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4154&view=rev Author: mdboom Date: 2007-11-07 13:20:45 -0800 (Wed, 07 Nov 2007) Log Message: ----------- First pass at Cairo support on the branch. Modified Paths: -------------- branches/transforms/lib/matplotlib/backend_bases.py branches/transforms/lib/matplotlib/backends/backend_cairo.py branches/transforms/lib/matplotlib/path.py Modified: branches/transforms/lib/matplotlib/backend_bases.py =================================================================== --- branches/transforms/lib/matplotlib/backend_bases.py 2007-11-07 20:38:46 UTC (rev 4153) +++ branches/transforms/lib/matplotlib/backend_bases.py 2007-11-07 21:20:45 UTC (rev 4154) @@ -62,7 +62,7 @@ that path multiple times with the different offsets, colors, styles etc. The methods _iter_collection_raw_paths and _iter_collection are provided to help with (and standardize) - the implementation that in each backend. + the implementation across backends. """ path_ids = [] for path, transform in self._iter_collection_raw_paths( @@ -91,10 +91,9 @@ if showedges: edgecolors = npy.array([[0.0, 0.0, 0.0, 1.0]], npy.float_) - linewidths = npy.array([1.0], npy.float_) else: - edgecolors = linewidths = npy.array([], npy.float_) - linewidths = npy.array([0.0], npy.float_) + edgecolors = facecolors + linewidths = npy.array([1.0], npy.float_) return self.draw_path_collection( master_transform, cliprect, clippath, clippath_trans, @@ -195,8 +194,10 @@ rgbFace = facecolors[i % Nfacecolors] if Nedgecolors: gc.set_foreground(edgecolors[i % Nedgecolors]) - gc.set_linewidth(linewidths[i % Nlinewidths]) - gc.set_dashes(*linestyles[i % Nlinestyles]) + if Nlinewidths: + gc.set_linewidth(linewidths[i % Nlinewidths]) + if Nlinestyles: + gc.set_dashes(*linestyles[i % Nlinestyles]) gc.set_antialiased(antialiaseds[i % Naa]) yield xo, yo, path_id, gc, rgbFace @@ -466,7 +467,7 @@ if isRGB: self._rgb = fg else: - self._rgb = colors.colorConverter.to_rgb(fg) + self._rgb = colors.colorConverter.to_rgba(fg) def set_graylevel(self, frac): """ Modified: branches/transforms/lib/matplotlib/backends/backend_cairo.py =================================================================== --- branches/transforms/lib/matplotlib/backends/backend_cairo.py 2007-11-07 20:38:46 UTC (rev 4153) +++ branches/transforms/lib/matplotlib/backends/backend_cairo.py 2007-11-07 21:20:45 UTC (rev 4154) @@ -39,7 +39,8 @@ from matplotlib.cbook import enumerate, izip, is_string_like from matplotlib.figure import Figure from matplotlib.mathtext import MathTextParser -from matplotlib.transforms import Bbox +from matplotlib.path import Path +from matplotlib.transforms import Bbox, Affine2D from matplotlib.font_manager import ttfFontProperty from matplotlib import rcParams @@ -48,9 +49,9 @@ # Image::color_conv(format) for draw_image() if sys.byteorder == 'little': - BYTE_FORMAT = 0 # BGRA + BYTE_FORMAT = 0 # BGRA else: - BYTE_FORMAT = 1 # ARGB + BYTE_FORMAT = 1 # ARGB class RendererCairo(RendererBase): @@ -91,10 +92,10 @@ self.mathtext_parser = MathTextParser('Cairo') def set_ctx_from_surface (self, surface): - self.ctx = cairo.Context (surface) - self.ctx.save() # restore, save - when call new_gc() + self.ctx = cairo.Context (surface) + self.ctx.save() # restore, save - when call new_gc() + - def set_width_height(self, width, height): self.width = width self.height = height @@ -109,9 +110,12 @@ #_.ctx.save() - if fill_c: + if fill_c is not None: ctx.save() - ctx.set_source_rgb (*fill_c) + if len(fill_c) == 3: + ctx.set_source_rgb (*fill_c) + else: + ctx.set_source_rgba (*fill_c) #if stroke_c: # always (implicitly) set at the moment ctx.fill_preserve() #else: @@ -124,22 +128,48 @@ #_.ctx.restore() # revert to the default attributes - - def draw_arc(self, gc, rgbFace, x, y, width, height, angle1, angle2, - rotation): - if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) + #@staticmethod + def convert_path(ctx, tpath): + for points, code in tpath.iter_segments(): + if code == Path.MOVETO: + ctx.move_to(*points) + elif code == Path.LINETO: + ctx.line_to(*points) + elif code == Path.CURVE3: + ctx.curve_to(points[0], points[1], + points[0], points[1], + points[2], points[3]) + elif code == Path.CURVE4: + ctx.curve_to(*points) + elif code == Path.CLOSEPOLY: + ctx.close_path() + convert_path = staticmethod(convert_path) + + def draw_path(self, gc, path, transform, rgbFace=None): ctx = gc.ctx - ctx.save() - ctx.translate(x, self.height - y) - ctx.rotate(rotation) - ctx.scale(width / 2.0, height / 2.0) - ctx.new_sub_path() - ctx.arc(0.0, 0.0, 1.0, npy.pi * angle1 / 180., - npy.pi * angle2 / 180.) - ctx.restore() + ctx.new_path() + transform = transform + \ + Affine2D().scale(1.0, -1.0).translate(0, self.height) + tpath = transform.transform_path(path) + + self.convert_path(ctx, tpath) - self._fill_and_stroke (ctx, rgbFace) + self._fill_and_stroke(ctx, rgbFace) + def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None): + ctx = gc.ctx + ctx.new_path() + marker_trans = marker_trans + Affine2D().scale(1.0, -1.0) + tmarker_path = marker_trans.transform_path(marker_path) + + trans = trans + Affine2D().scale(1.0, -1.0).translate(0, self.height) + tpath = trans.transform_path(path) + for x, y in tpath.vertices: + ctx.save() + ctx.translate(x, y) + self.convert_path(ctx, tmarker_path) + self._fill_and_stroke(ctx, rgbFace) + ctx.restore() def draw_image(self, x, y, im, bbox): # bbox - not currently used @@ -158,118 +188,6 @@ im.flipud_out() - - def draw_line(self, gc, x1, y1, x2, y2): - if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) - ctx = gc.ctx - ctx.new_path() - ctx.move_to (x1, self.height - y1) - ctx.line_to (x2, self.height - y2) - self._fill_and_stroke (ctx, None) - - - def draw_lines(self, gc, x, y, transform=None): - if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) - - if transform: - if transform.need_nonlinear(): - x, y = transform.nonlinear_only_numerix(x, y) - x, y = transform.numerix_x_y(x, y) - - ctx = gc.ctx - matrix_old = ctx.get_matrix() - ctx.set_matrix (self.matrix_flipy) - - points = izip(x,y) - x, y = points.next() - ctx.new_path() - ctx.move_to (x, y) - - for x,y in points: - ctx.line_to (x, y) - self._fill_and_stroke (ctx, None) - - ctx.set_matrix (matrix_old) - - - def draw_markers_OLD(self, gc, path, rgbFace, x, y, transform): - if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) - - ctx = gc.ctx - - if transform.need_nonlinear(): - x,y = transform.nonlinear_only_numerix(x, y) - - x, y = transform.numerix_x_y(x, y) # do nonlinear and affine transform - - # TODO - use cairo transform - # matrix worked for dotted lines, but not markers in line_styles.py - # it upsets/transforms generate_path() ? - # need to flip y too, and update generate_path() ? - # the a,b,c,d,tx,ty affine which transforms x and y - #vec6 = transform.as_vec6_val() # not used (yet) - #matrix_old = ctx.get_matrix() - #ctx.set_matrix (cairo.Matrix (*vec6)) - - path_list = [path.vertex() for i in range(path.total_vertices())] - - def generate_path (path_list): - for code, xp, yp in path_list: - if code == agg.path_cmd_move_to: - ctx.move_to (xp, -yp) - elif code == agg.path_cmd_line_to: - ctx.line_to (xp, -yp) - elif code == agg.path_cmd_end_poly: - ctx.close_path() - - for x,y in izip(x,y): - ctx.save() - ctx.new_path() - ctx.translate(x, self.height - y) - generate_path (path_list) - - self._fill_and_stroke (ctx, rgbFace) - - ctx.restore() # undo translate() - - #ctx.set_matrix(matrix_old) - - - def draw_point(self, gc, x, y): - if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) - # render by drawing a 0.5 radius circle - ctx = gc.ctx - ctx.new_path() - ctx.arc (x, self.height - y, 0.5, 0, 2*npy.pi) - self._fill_and_stroke (ctx, gc.get_rgb()) - - - def draw_polygon(self, gc, rgbFace, points): - if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) - - ctx = gc.ctx - matrix_old = ctx.get_matrix() - ctx.set_matrix (self.matrix_flipy) - - ctx.new_path() - x, y = points[0] - ctx.move_to (x, y) - for x,y in points[1:]: - ctx.line_to (x, y) - ctx.close_path() - - self._fill_and_stroke (ctx, rgbFace) - - ctx.set_matrix (matrix_old) - - def draw_rectangle(self, gc, rgbFace, x, y, width, height): - if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) - ctx = gc.ctx - ctx.new_path() - ctx.rectangle (x, self.height - y - height, width, height) - self._fill_and_stroke (ctx, rgbFace) - - def draw_text(self, gc, x, y, s, prop, angle, ismath=False): # Note: x,y are device/display coords, not user-coords, unlike other # draw_* methods @@ -287,7 +205,7 @@ self.fontweights[prop.get_weight()]) # size = prop.get_size_in_points() * self.dpi.get() / 96.0 - size = prop.get_size_in_points() * self.dpi.get() / 72.0 + size = prop.get_size_in_points() * self.dpi / 72.0 ctx.save() if angle: @@ -301,7 +219,7 @@ ctx = gc.ctx width, height, descent, glyphs, rects = self.mathtext_parser.parse( - s, self.dpi.get(), prop) + s, self.dpi, prop) ctx.save() ctx.translate(x, y) @@ -319,7 +237,7 @@ self.fontweights[fontProp.weight]) # size = prop.get_size_in_points() * self.dpi.get() / 96.0 - size = fontsize * self.dpi.get() / 72.0 + size = fontsize * self.dpi / 72.0 ctx.set_font_size(size) ctx.show_text(s.encode("utf-8")) ctx.restore() @@ -349,7 +267,7 @@ if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) if ismath: width, height, descent, fonts, used_characters = self.mathtext_parser.parse( - s, self.dpi.get(), prop) + s, self.dpi, prop) return width, height, descent ctx = self.text_ctx @@ -362,7 +280,7 @@ # but if /96.0 is used the font is too small #size = prop.get_size_in_points() * self.dpi.get() / 96.0 - size = prop.get_size_in_points() * self.dpi.get() / 72.0 + size = prop.get_size_in_points() * self.dpi / 72.0 # problem - scale remembers last setting and font can become # enormous causing program to crash @@ -384,7 +302,7 @@ def points_to_pixels(self, points): if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) - return points/72.0 * self.dpi.get() + return points/72.0 * self.dpi class GraphicsContextCairo(GraphicsContextBase): @@ -428,7 +346,7 @@ def set_clip_rectangle(self, rectangle): self._cliprect = rectangle - x,y,w,h = rectangle + x,y,w,h = rectangle.bounds # pixel-aligned clip-regions are faster x,y,w,h = round(x), round(y), round(w), round(h) ctx = self.ctx @@ -439,6 +357,17 @@ # in fill_and_stroke() inside ctx.save() ... ctx.restore() + def set_clip_path(self, path): + if path is not None: + tpath, affine = path.get_transformed_path_and_affine() + ctx = self.ctx + ctx.new_path() + affine = affine + Affine2D().scale(1.0, -1.0).translate(0.0, self.renderer.height) + tpath = affine.transform_path(tpath) + RendererCairo.convert_path(ctx, tpath) + ctx.clip() + + def set_dashes(self, offset, dashes): self._dashes = offset, dashes if dashes == None: @@ -450,12 +379,17 @@ def set_foreground(self, fg, isRGB=None): GraphicsContextBase.set_foreground(self, fg, isRGB) - self.ctx.set_source_rgb(*self._rgb) + if len(self._rgb) == 3: + self.ctx.set_source_rgb(*self._rgb) + else: + self.ctx.set_source_rgba(*self._rgb) - def set_graylevel(self, frac): GraphicsContextBase.set_graylevel(self, frac) - self.ctx.set_source_rgb(*self._rgb) + if len(self._rgb) == 3: + self.ctx.set_source_rgb(*self._rgb) + else: + self.ctx.set_source_rgba(*self._rgb) def set_joinstyle(self, js): Modified: branches/transforms/lib/matplotlib/path.py =================================================================== --- branches/transforms/lib/matplotlib/path.py 2007-11-07 20:38:46 UTC (rev 4153) +++ branches/transforms/lib/matplotlib/path.py 2007-11-07 21:20:45 UTC (rev 4154) @@ -209,8 +209,11 @@ """ vertices = simple_linear_interpolation(self.vertices, steps) codes = self.codes - new_codes = Path.LINETO * npy.ones(((len(codes) - 1) * steps + 1, )) - new_codes[0::steps] = codes + if codes is not None: + new_codes = Path.LINETO * npy.ones(((len(codes) - 1) * steps + 1, )) + new_codes[0::steps] = codes + else: + new_codes = None return Path(vertices, new_codes) _unit_rectangle = None This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-11-08 16:27:19
|
Revision: 4162 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4162&view=rev Author: mdboom Date: 2007-11-08 08:27:18 -0800 (Thu, 08 Nov 2007) Log Message: ----------- Put a generic non-optimized draw_markers implementation in backend_bases. Modified Paths: -------------- branches/transforms/lib/matplotlib/backend_bases.py branches/transforms/lib/matplotlib/backends/backend_cairo.py branches/transforms/lib/matplotlib/backends/backend_template.py Modified: branches/transforms/lib/matplotlib/backend_bases.py =================================================================== --- branches/transforms/lib/matplotlib/backend_bases.py 2007-11-08 16:26:31 UTC (rev 4161) +++ branches/transforms/lib/matplotlib/backend_bases.py 2007-11-08 16:27:18 UTC (rev 4162) @@ -15,7 +15,21 @@ from matplotlib import rcParams class RendererBase: - """An abstract base class to handle drawing/rendering operations + """An abstract base class to handle drawing/rendering operations. + + The following methods *must* be implemented in the backend: + + draw_path + draw_image + draw_text + get_text_width_height_descent + + The following methods *should* be implemented in the backend for + optimization reasons: + + draw_markers + draw_path_collection + draw_quad_mesh """ def __init__(self): self._texmanager = None @@ -47,22 +61,41 @@ marker_trans is an affine transform applied to the marker. trans is an affine transform applied to the path. + + This provides a fallback implementation of draw_markers that + makes multiple calls to draw_path. Some backends may want to + override this method in order to draw the marker only once and + reuse it multiple times. """ - raise NotImplementedError - + ctx = gc.ctx + ctx.new_path() + tpath = trans.transform_path(path) + for x, y in tpath.vertices: + self.draw_path(gc, marker_path, + marker_trans + transforms.Affine2D().translate(x, y), + rgbFace) + def draw_path_collection(self, master_transform, cliprect, clippath, clippath_trans, paths, all_transforms, offsets, offsetTrans, facecolors, edgecolors, linewidths, linestyles, antialiaseds): """ + Draws a collection of paths, selecting drawing properties from + the lists facecolors, edgecolors, linewidths, linestyles and + antialiaseds. offsets is a list of offsets to apply to each + of the paths. The offsets in offsets are first transformed by + offsetTrans before being applied. + This provides a fallback implementation of draw_path_collection that makes multiple calls to draw_path. - Often, the backend will want to override this in order to - render each set of path data only once, and then reference - that path multiple times with the different offsets, colors, - styles etc. The methods _iter_collection_raw_paths and + Some backends may want to override this in order to render + each set of path data only once, and then reference that path + multiple times with the different offsets, colors, styles etc. + The generator methods _iter_collection_raw_paths and _iter_collection are provided to help with (and standardize) - the implementation across backends. + the implementation across backends. It is highly recommended + to use those generators, so that changes to the behavior of + draw_path_collection can be made globally. """ path_ids = [] for path, transform in self._iter_collection_raw_paths( Modified: branches/transforms/lib/matplotlib/backends/backend_cairo.py =================================================================== --- branches/transforms/lib/matplotlib/backends/backend_cairo.py 2007-11-08 16:26:31 UTC (rev 4161) +++ branches/transforms/lib/matplotlib/backends/backend_cairo.py 2007-11-08 16:27:18 UTC (rev 4162) @@ -156,21 +156,6 @@ self._fill_and_stroke(ctx, rgbFace) - def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None): - ctx = gc.ctx - ctx.new_path() - marker_trans = marker_trans + Affine2D().scale(1.0, -1.0) - tmarker_path = marker_trans.transform_path(marker_path) - - trans = trans + Affine2D().scale(1.0, -1.0).translate(0, self.height) - tpath = trans.transform_path(path) - for x, y in tpath.vertices: - ctx.save() - ctx.translate(x, y) - self.convert_path(ctx, tmarker_path) - self._fill_and_stroke(ctx, rgbFace) - ctx.restore() - def draw_image(self, x, y, im, bbox): # bbox - not currently used if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) Modified: branches/transforms/lib/matplotlib/backends/backend_template.py =================================================================== --- branches/transforms/lib/matplotlib/backends/backend_template.py 2007-11-08 16:26:31 UTC (rev 4161) +++ branches/transforms/lib/matplotlib/backends/backend_template.py 2007-11-08 16:27:18 UTC (rev 4162) @@ -69,8 +69,10 @@ def draw_path(self, gc, path, transform, rgbFace=None): pass - def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None): - pass + # draw_markers is optional, and we get more correct + # relative timings by leaving it out. +# def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None): +# pass # draw_path_collection is optional, and we get more correct # relative timings by leaving it out. @@ -79,7 +81,15 @@ # offsetTrans, facecolors, edgecolors, linewidths, # linestyles, antialiaseds): # pass - + + # draw_quad_mesh is optional, and we get more correct + # relative timings by leaving it out. +# def draw_quad_mesh(self, master_transform, cliprect, clippath, +# clippath_trans, meshWidth, meshHeight, coordinates, +# offsets, offsetTrans, facecolors, antialiased, +# showedges): +# pass + def draw_image(self, x, y, im, bbox, clippath=None, clippath_trans=None): pass This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-11-09 16:35:21
|
Revision: 4185 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4185&view=rev Author: mdboom Date: 2007-11-09 08:35:15 -0800 (Fri, 09 Nov 2007) Log Message: ----------- Get wx backend working with wxGraphicsContext drawing. Modified Paths: -------------- branches/transforms/lib/matplotlib/backend_bases.py branches/transforms/lib/matplotlib/backends/backend_wx.py Modified: branches/transforms/lib/matplotlib/backend_bases.py =================================================================== --- branches/transforms/lib/matplotlib/backend_bases.py 2007-11-09 16:33:58 UTC (rev 4184) +++ branches/transforms/lib/matplotlib/backend_bases.py 2007-11-09 16:35:15 UTC (rev 4185) @@ -67,8 +67,6 @@ override this method in order to draw the marker only once and reuse it multiple times. """ - ctx = gc.ctx - ctx.new_path() tpath = trans.transform_path(path) for x, y in tpath.vertices: self.draw_path(gc, marker_path, Modified: branches/transforms/lib/matplotlib/backends/backend_wx.py =================================================================== --- branches/transforms/lib/matplotlib/backends/backend_wx.py 2007-11-09 16:33:58 UTC (rev 4184) +++ branches/transforms/lib/matplotlib/backends/backend_wx.py 2007-11-09 16:35:15 UTC (rev 4185) @@ -94,7 +94,7 @@ cvs_id = '$Id$' -import sys, os, os.path, math, StringIO +import sys, os, os.path, math, StringIO, weakref # Debugging settings here... # Debug level set here. If the debug level is less than 5, information @@ -154,7 +154,9 @@ from matplotlib.artist import Artist from matplotlib.cbook import exception_to_str from matplotlib.figure import Figure +from matplotlib.path import Path from matplotlib.text import _process_text_args, Text +from matplotlib.transforms import Affine2D from matplotlib.widgets import SubplotTool from matplotlib import rcParams @@ -261,10 +263,14 @@ #return 1, 1 if ismath: s = self.strip_math(s) - if self.gc is None: gc = self.new_gc() + if self.gc is None: + gc = self.new_gc() + else: + gc = self.gc + gfx_ctx = gc.gfx_ctx font = self.get_wx_font(s, prop) - self.gc.SetFont(font) - w, h, descent, leading = self.gc.GetFullTextExtent(s) + gfx_ctx.SetFont(font, wx.BLACK) + w, h, descent, leading = gfx_ctx.GetFullTextExtent(s) return w, h, descent @@ -272,97 +278,49 @@ 'return the canvas width and height in display coords' return self.width, self.height - - def draw_arc(self, gc, rgbFace, x, y, width, height, angle1, angle2, rotation): - """ - Draw an arc centered at x,y with width and height and angles - from 0.0 to 360.0. - If rgbFace is present, fill the figure in this colour, otherwise - it is not filled. - """ + def handle_clip_rectangle(self, gc): + new_bounds = gc.get_clip_rectangle() + if new_bounds is not None: + new_bounds = new_bounds.bounds + gfx_ctx = gc.gfx_ctx + if gfx_ctx._lastcliprect != new_bounds: + gfx_ctx._lastcliprect = new_bounds + if new_bounds is None: + gfx_ctx.ResetClip() + else: + gfx_ctx.Clip(*new_bounds) + + #@staticmethod + def convert_path(gfx_ctx, tpath): + wxpath = gfx_ctx.CreatePath() + for points, code in tpath.iter_segments(): + if code == Path.MOVETO: + wxpath.MoveToPoint(*points) + elif code == Path.LINETO: + wxpath.AddLineToPoint(*points) + elif code == Path.CURVE3: + wxpath.AddQuadCurveToPoint(*points) + elif code == Path.CURVE4: + wxpath.AddCurveToPoint(*points) + elif code == Path.CLOSEPOLY: + wxpath.CloseSubpath() + return wxpath + convert_path = staticmethod(convert_path) + + def draw_path(self, gc, path, transform, rgbFace=None): gc.select() - assert gc.Ok(), "wxMemoryDC not OK to use" - # wxPython requires upper left corner of bounding rectange for ellipse - # Theoretically you don't need the int() below, but it seems to make - # rounding of arc centre point more accurate in screen co-ordinates - ulX = x - int(width/2) - ulY = self.height - int(y + (height/2)) + self.handle_clip_rectangle(gc) + gfx_ctx = gc.gfx_ctx + transform = transform + Affine2D().scale(1.0, -1.0).translate(0.0, self.height) + tpath = transform.transform_path(path) + wxpath = self.convert_path(gfx_ctx, tpath) if rgbFace is not None: - r,g,b = self._to_wx_rgb(rgbFace) - new_brush =wx.Brush(wx.Colour(r,g,b), wx.SOLID) - gc.SetBrush(new_brush) + gfx_ctx.SetBrush(wx.Brush(gc.get_wxcolour(rgbFace))) + gfx_ctx.DrawPath(wxpath) else: - gc.SetBrush(wx.TRANSPARENT_BRUSH) - gc.DrawEllipticArc(int(ulX), int(ulY), int(width)+1, int(height)+1, - int(angle1), int(angle2)) + gfx_ctx.StrokePath(wxpath) gc.unselect() - def draw_line(self, gc, x1, y1, x2, y2): - """ - Draw a single line from x1,y1 to x2,y2 - """ - DEBUG_MSG("draw_line()", 1, self) - gc.select() - gc.DrawLine(int(x1), self.height - int(y1), - int(x2), self.height - int(y2)) - gc.unselect() - - def draw_lines(self, gc, x, y): - """ - x and y are equal length arrays, draw lines connecting each - point in x, y - """ - gc.select() - assert gc.Ok(), "wxMemoryDC not OK to use" - assert len(x) == len(y), "draw_lines() x and y must be of equal length" - gc.DrawLines([wx.Point(int(x[i]), self.height - int(y[i])) for i in range(len(x))]) - gc.unselect() - - def draw_polygon(self, gc, rgbFace, points): - """ - Draw a polygon. points is a len vertices tuple, each element - giving the x,y coords a vertex - """ - gc.select() - assert gc.Ok(), "wxMemoryDC not OK to use" - points = [(int(x), self.height - int(y)) for x,y in points] - if rgbFace is not None: - r,g,b = self._to_wx_rgb(rgbFace) - new_brush =wx.Brush(wx.Colour(r,g,b), wx.SOLID) - gc.SetBrush(new_brush) - else: - gc.SetBrush(wx.TRANSPARENT_BRUSH) - gc.DrawPolygon(points) - gc.unselect() - - def draw_rectangle(self, gc, rgbFace, x, y, width, height): - """ - Draw a rectangle at lower left x,y with width and height - If filled=True, fill the rectangle with the gc foreground - gc is a GraphicsContext instance - """ - # wxPython uses rectangle from TOP left! - gc.select() - assert gc.Ok(), "wxMemoryDC not OK to use" - if rgbFace is not None: - r,g,b = self._to_wx_rgb(rgbFace) - new_brush =wx.Brush(wx.Colour(r,g,b), wx.SOLID) - gc.SetBrush(new_brush) - else: - gc.SetBrush(wx.TRANSPARENT_BRUSH) - gc.DrawRectangle(int(x), self.height - int(height + y), - int(math.ceil(width)), int(math.ceil(height))) - gc.unselect() - - def draw_point(self, gc, x, y): - """ - Draw a single point at x,y - """ - gc.select() - assert gc.Ok(), "wxMemoryDC not OK to use" - gc.DrawPoint(int(x), self.height - int(y)) - gc.unselect() - def draw_text(self, gc, x, y, s, prop, angle, ismath): """ Render the matplotlib.text.Text instance @@ -371,21 +329,23 @@ if ismath: s = self.strip_math(s) DEBUG_MSG("draw_text()", 1, self) gc.select() - + self.handle_clip_rectangle(gc) + gfx_ctx = gc.gfx_ctx + font = self.get_wx_font(s, prop) - gc.SetFont(font) - assert gc.Ok(), "wxMemoryDC not OK to use" + color = gc.get_wxcolour(gc.get_rgb()) + gfx_ctx.SetFont(font, color) w, h, d = self.get_text_width_height_descent(s, prop, ismath) x = int(x) y = int(y-h) - if angle!=0: - try: gc.DrawRotatedText(s, x, y, angle) - except: - verbose.print_error(exception_to_str('WX rotated text failed')) + if angle == 0.0: + gfx_ctx.DrawText(s, x, y) else: - gc.DrawText(s, x, y) + angle = angle * (math.pi / 180.0) + gfx_ctx.DrawRotatedText(s, x, y, angle) + gc.unselect() def new_gc(self): @@ -395,7 +355,6 @@ DEBUG_MSG('new_gc()', 2, self) self.gc = GraphicsContextWx(self.bitmap, self) self.gc.select() - assert self.gc.Ok(), "wxMemoryDC not OK to use" self.gc.unselect() return self.gc @@ -446,14 +405,7 @@ return font - def _to_wx_rgb(self, rgb): - """Takes a colour value and returns a tuple (r,g,b) suitable - for instantiating a wx.Colour.""" - r, g, b = rgb - return (int(r * 255), int(g * 255), int(b * 255)) - - def points_to_pixels(self, points): """ convert point measures to pixes using dpi and the pixels per @@ -461,15 +413,15 @@ """ return points*(PIXELS_PER_INCH/72.0*self.dpi/72.0) -class GraphicsContextWx(GraphicsContextBase, wx.MemoryDC): +class GraphicsContextWx(GraphicsContextBase): """ The graphics context provides the color, line styles, etc... - In wxPython this is done by wrapping a wxDC object and forwarding the - appropriate calls to it. Notice also that colour and line styles are - mapped on the wx.Pen() member of the wxDC. This means that we have some - rudimentary pen management here. - + This class stores a reference to a wxMemoryDC, and a + wxGraphicsContext that draws to it. Creating a wxGraphicsContext + seems to be fairly heavy, so these objects are cached based on the + bitmap object that is passed in. + The base GraphicsContext stores colors as a RGB tuple on the unit interval, eg, (0.5, 0.0, 1.0). wxPython uses an int interval, but since wxPython colour management is rather simple, I have not chosen @@ -487,26 +439,30 @@ 'dashed': wx.SHORT_DASH, 'dashdot': wx.DOT_DASH, 'dotted': wx.DOT } - _lastWxDC = None - + _cache = weakref.WeakKeyDictionary() + def __init__(self, bitmap, renderer): GraphicsContextBase.__init__(self) - wx.MemoryDC.__init__(self) #assert self.Ok(), "wxMemoryDC not OK to use" DEBUG_MSG("__init__()", 1, self) - # Make sure (belt and braces!) that existing wxDC is not selected to - # to a bitmap. - if GraphicsContextWx._lastWxDC != None: - GraphicsContextWx._lastWxDC.SelectObject(wx.NullBitmap) - - self.SelectObject(bitmap) + dc, gfx_ctx = self._cache.get(bitmap, (None, None)) + if dc is None: + print "new dc" + dc = wx.MemoryDC() + dc.SelectObject(bitmap) + gfx_ctx = wx.GraphicsContext.Create(dc) + gfx_ctx._lastcliprect = None + self._cache[bitmap] = dc, gfx_ctx + self.bitmap = bitmap - self.SetPen(wx.Pen('BLACK', 1, wx.SOLID)) - self._style=wx.SOLID + self.dc = dc + self.gfx_ctx = gfx_ctx + self._pen = wx.Pen('BLACK', 1, wx.SOLID) + gfx_ctx.SetPen(self._pen) + self._style = wx.SOLID self.renderer = renderer - GraphicsContextWx._lastWxDC = self - + def select(self): """ Select the current bitmap into this wxDC instance @@ -524,23 +480,6 @@ self.SelectObject(wx.NullBitmap) self.IsSelected = False - def set_clip_rectangle(self, rect): - """ - Destroys previous clipping region and defines a new one. - """ - DEBUG_MSG("set_clip_rectangle()", 1, self) - self.select() - l,b,w,h = rect - # this appears to be version dependent' - if hasattr(self, 'SetClippingRegionXY'): - clipfunc = getattr(self, 'SetClippingRegionXY') - else: - clipfunc = getattr(self, 'SetClippingRegion') - - clipfunc(int(l), self.renderer.height - int(b+h), - int(w), int(h)) - self.unselect() - def set_foreground(self, fg, isRGB=None): """ Set the foreground color. fg can be a matlab format string, a @@ -556,12 +495,8 @@ self.select() GraphicsContextBase.set_foreground(self, fg, isRGB) - pen = self.GetPen() - pen.SetColour(self.get_wxcolour()) - self.SetPen(pen) - brush =wx.Brush(self.get_wxcolour(), wx.SOLID) - self.SetBrush(brush) - self.SetTextForeground(self.get_wxcolour()) + self._pen.SetColour(self.get_wxcolour(self.get_rgb())) + self.gfx_ctx.SetPen(self._pen) self.unselect() def set_graylevel(self, frac): @@ -573,11 +508,8 @@ DEBUG_MSG("set_graylevel()", 1, self) self.select() GraphicsContextBase.set_graylevel(self, frac) - pen = self.GetPen() - pen.SetColour(self.get_wxcolour()) - self.SetPen(pen) - brush =wx.Brush(self.get_wxcolour(), wx.SOLID) - self.SetBrush(brush) + self._pen.SetColour(self.get_wxcolour(self.get_rgb())) + self.gfx_ctx.SetPen(self._pen) self.unselect() def set_linewidth(self, w): @@ -588,11 +520,10 @@ self.select() if w>0 and w<1: w = 1 GraphicsContextBase.set_linewidth(self, w) - pen = self.GetPen() lw = int(self.renderer.points_to_pixels(self._linewidth)) if lw==0: lw = 1 - pen.SetWidth(lw) - self.SetPen(pen) + self._pen.SetWidth(lw) + self.gfx_ctx.SetPen(self._pen) self.unselect() def set_capstyle(self, cs): @@ -602,9 +533,8 @@ DEBUG_MSG("set_capstyle()", 1, self) self.select() GraphicsContextBase.set_capstyle(self, cs) - pen = self.GetPen() - pen.SetCap(GraphicsContextWx._capd[self._capstyle]) - self.SetPen(pen) + self._pen.SetCap(GraphicsContextWx._capd[self._capstyle]) + self.gfx_ctx.SetPen(self._pen) self.unselect() def set_joinstyle(self, js): @@ -614,9 +544,8 @@ DEBUG_MSG("set_joinstyle()", 1, self) self.select() GraphicsContextBase.set_joinstyle(self, js) - pen = self.GetPen() - pen.SetJoin(GraphicsContextWx._joind[self._joinstyle]) - self.SetPen(pen) + self._pen.SetJoin(GraphicsContextWx._joind[self._joinstyle]) + self.gfx_ctx.SetPen(self._pen) self.unselect() def set_linestyle(self, ls): @@ -629,25 +558,32 @@ try: self._style = GraphicsContextWx._dashd_wx[ls] except KeyError: - self._style=wx.LONG_DASH# Style not used elsewhere... + self._style = wx.LONG_DASH# Style not used elsewhere... # On MS Windows platform, only line width of 1 allowed for dash lines if wx.Platform == '__WXMSW__': self.set_linewidth(1) - pen = self.GetPen() - pen.SetStyle(self._style) - self.SetPen(pen) + self._pen.SetStyle(self._style) + self.gfx_ctx.SetPen(self._pen) self.unselect() - def get_wxcolour(self): + def get_wxcolour(self, color): """return a wx.Colour from RGB format""" DEBUG_MSG("get_wx_color()", 1, self) - r, g, b = self.get_rgb() - r *= 255 - g *= 255 - b *= 255 - return wx.Colour(red=int(r), green=int(g), blue=int(b)) + if len(color) == 3: + r, g, b = color + r *= 255 + g *= 255 + b *= 255 + return wx.Colour(red=int(r), green=int(g), blue=int(b)) + else: + r, g, b, a = color + r *= 255 + g *= 255 + b *= 255 + a *= 255 + return wx.Colour(red=int(r), green=int(g), blue=int(b), alpha=int(a)) class FigureCanvasWx(FigureCanvasBase, wx.Panel): """ @@ -783,7 +719,7 @@ self.macros = {} # dict from wx id to seq of macros self.Printer_Init() - + def Destroy(self, *args, **kwargs): wx.Panel.Destroy(self, *args, **kwargs) @@ -938,6 +874,9 @@ self.gui_repaint() + def draw_idle(self, *args, **kwargs): + pass + def draw(self, repaint=True): """ Render the figure using RendererWx instance renderer, or using a @@ -1016,7 +955,7 @@ def _print_image(self, filename, filetype, *args, **kwargs): origBitmap = self.bitmap - l,b,width,height = self.figure.bbox.get_bounds() + l,b,width,height = self.figure.bbox.bounds width = int(math.ceil(width)) height = int(math.ceil(height)) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-11-09 19:09:44
|
Revision: 4189 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4189&view=rev Author: mdboom Date: 2007-11-09 11:09:42 -0800 (Fri, 09 Nov 2007) Log Message: ----------- Add support for nonuniform grids to imshow. Modified Paths: -------------- branches/transforms/lib/matplotlib/axes.py branches/transforms/lib/matplotlib/image.py Modified: branches/transforms/lib/matplotlib/axes.py =================================================================== --- branches/transforms/lib/matplotlib/axes.py 2007-11-09 16:43:38 UTC (rev 4188) +++ branches/transforms/lib/matplotlib/axes.py 2007-11-09 19:09:42 UTC (rev 4189) @@ -4385,7 +4385,9 @@ #### plotting z(x,y): imshow, pcolor and relatives, contour - def imshow(self, X, + def imshow(self, I, + X = None, + Y = None, cmap = None, norm = None, aspect=None, @@ -4402,18 +4404,24 @@ **kwargs): """ - IMSHOW(X, cmap=None, norm=None, aspect=None, interpolation=None, - alpha=1.0, vmin=None, vmax=None, origin=None, extent=None) + IMSHOW(I, X=None, Y=None, cmap=None, norm=None, aspect=None, + interpolation=None, alpha=1.0, vmin=None, vmax=None, + origin=None, extent=None) - IMSHOW(X) - plot image X to current axes, resampling to scale to axes - size (X may be numarray/Numeric array or PIL image) + IMSHOW(I) - plot image I to current axes, resampling to scale to axes + size (I may be numarray/Numeric array or PIL image) - IMSHOW(X, **kwargs) - Use keyword args to control image scaling, - colormapping etc. See below for details + IMSHOW(I, X, Y) - plot image I to current axes, with + nonuniform X and Y axes. (I, X and Y may be + numarray/Numeric array or PIL image) + + IMSHOW(I, X, Y, **kwargs) - Use keyword args to control image + scaling, colormapping etc. See + below for details - Display the image in X to current axes. X may be a float array, a - uint8 array or a PIL image. If X is an array, X can have the following + Display the image in I to current axes. I may be a float array, a + uint8 array or a PIL image. If I is an array, I can have the following shapes: MxN : luminance (grayscale, float array only) @@ -4425,6 +4433,10 @@ The value for each component of MxNx3 and MxNx4 float arrays should be in the range 0.0 to 1.0; MxN float arrays may be normalised. + X and/or Y may be provided to specify a non-uniform image + grid. Each element of the X or Y arrays is the width or height + of the corresponding pixel in the given image. + A image.AxesImage instance is returned The following kwargs are allowed: @@ -4488,12 +4500,25 @@ if norm is not None: assert(isinstance(norm, mcolors.Normalize)) if cmap is not None: assert(isinstance(cmap, mcolors.Colormap)) if aspect is None: aspect = rcParams['image.aspect'] - self.set_aspect(aspect) - im = mimage.AxesImage(self, cmap, norm, interpolation, origin, extent, - filternorm=filternorm, - filterrad=filterrad, **kwargs) - - im.set_data(X) + # self.set_aspect(aspect) + + if X is None and Y is None: + im = mimage.AxesImage(self, cmap, norm, interpolation, origin, extent, + filternorm=filternorm, + filterrad=filterrad, **kwargs) + + im.set_data(I) + else: + if X is None: + X = npy.arange(I.shape[1]) + if Y is None: + Y = npy.arange(I.shape[0]) + im = mimage.NonUniformImage(self, cmap=cmap, norm=norm, + interpolation=interpolation, + origin=origin, extent=extent, + filternorm=filternorm, + filterrad=filterrad, **kwargs) + im.set_data(X, Y, I) im.set_alpha(alpha) self._set_artist_props(im) im.set_clip_path(self.axesPatch) @@ -4515,7 +4540,7 @@ return im - + def _pcolorargs(self, funcname, *args): if len(args)==1: C = args[0] Modified: branches/transforms/lib/matplotlib/image.py =================================================================== --- branches/transforms/lib/matplotlib/image.py 2007-11-09 16:43:38 UTC (rev 4188) +++ branches/transforms/lib/matplotlib/image.py 2007-11-09 19:09:42 UTC (rev 4189) @@ -77,8 +77,6 @@ # reverse interp dict self._interpdr = dict([ (v,k) for k,v in self._interpd.items()]) - if interpolation is None: interpolation = rcParams['image.interpolation'] - self.set_interpolation(interpolation) self.axes = ax @@ -267,7 +265,7 @@ ACCEPTS: ['bicubic' | 'bilinear' | 'blackman100' | 'blackman256' | 'blackman64', 'nearest' | 'sinc144' | 'sinc256' | 'sinc64' | 'spline16' | 'spline36'] """ - + if s is None: s = rcParams['image.interpolation'] s = s.lower() if not self._interpd.has_key(s): raise ValueError('Illegal interpolation string') @@ -317,17 +315,10 @@ class NonUniformImage(AxesImage): def __init__(self, ax, - cmap = None, - norm = None, - extent=None, + **kwargs ): AxesImage.__init__(self, ax, - cmap = cmap, - norm = norm, - extent=extent, - interpolation = 'nearest', - origin = 'lower', - ) + **kwargs) def make_image(self, magnification=1.0): if self._A is None: @@ -382,9 +373,11 @@ raise NotImplementedError('Method not supported') def set_interpolation(self, s): - if s != 'nearest': + print s + if s != None and s != 'nearest': raise NotImplementedError('Only nearest neighbor supported') - + AxesImage.set_interpolation(self, s) + def get_extent(self): if self._A is None: raise RuntimeError('Must set data first') This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-11-15 16:28:56
|
Revision: 4306 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4306&view=rev Author: mdboom Date: 2007-11-15 08:28:54 -0800 (Thu, 15 Nov 2007) Log Message: ----------- Speed improvements. Modified Paths: -------------- branches/transforms/lib/matplotlib/backends/backend_tkagg.py branches/transforms/lib/matplotlib/transforms.py Modified: branches/transforms/lib/matplotlib/backends/backend_tkagg.py =================================================================== --- branches/transforms/lib/matplotlib/backends/backend_tkagg.py 2007-11-15 15:18:42 UTC (rev 4305) +++ branches/transforms/lib/matplotlib/backends/backend_tkagg.py 2007-11-15 16:28:54 UTC (rev 4306) @@ -146,7 +146,7 @@ def __init__(self, figure, master=None, resize_callback=None): FigureCanvasAgg.__init__(self, figure) - self._idle = True + self._idle = False t1,t2,w,h = self.figure.bbox.bounds w, h = int(w), int(h) self._tkcanvas = Tk.Canvas( Modified: branches/transforms/lib/matplotlib/transforms.py =================================================================== --- branches/transforms/lib/matplotlib/transforms.py 2007-11-15 15:18:42 UTC (rev 4305) +++ branches/transforms/lib/matplotlib/transforms.py 2007-11-15 16:28:54 UTC (rev 4306) @@ -37,6 +37,8 @@ if DEBUG: import warnings +MaskedArray = ma.MaskedArray + class TransformNode(object): """ TransformNode is the base class for anything that participates in @@ -1205,7 +1207,7 @@ def transform(self, points): mtx = self.get_matrix() - if ma.isMaskedArray(points): + if isinstance(points, MaskedArray): points = ma.dot(mtx[0:2, 0:2], points.transpose()) + mtx[0:2, 2:] return points.transpose() return affine_transform(points, mtx) @@ -1526,7 +1528,7 @@ y_points = y.transform(points[:, 1]) y_points = y_points.reshape((len(y_points), 1)) - if ma.isMaskedArray(x_points) or ma.isMaskedArray(y_points): + if isinstance(x_points, MaskedArray) or isinstance(y_points, MaskedArray): return ma.concatenate((x_points, y_points), 1) else: return npy.concatenate((x_points, y_points), 1) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-11-15 18:10:57
|
Revision: 4311 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4311&view=rev Author: mdboom Date: 2007-11-15 10:10:54 -0800 (Thu, 15 Nov 2007) Log Message: ----------- Major speed improvement (duplicate draws were being emitted). Modified Paths: -------------- branches/transforms/lib/matplotlib/axes.py branches/transforms/lib/matplotlib/backends/backend_tkagg.py Modified: branches/transforms/lib/matplotlib/axes.py =================================================================== --- branches/transforms/lib/matplotlib/axes.py 2007-11-15 17:23:03 UTC (rev 4310) +++ branches/transforms/lib/matplotlib/axes.py 2007-11-15 18:10:54 UTC (rev 4311) @@ -1608,9 +1608,8 @@ for other in self._shared_x_axes.get_siblings(self): if other is not self: other.set_xlim(self.viewLim.intervalx, emit=False) - - if self.figure.canvas is not None: - self.figure.canvas.draw_idle() + if other.figure != self.figure and other.figure.canvas is not None: + other.figure.canvas.draw_idle() return xmin, xmax @@ -1770,9 +1769,8 @@ for other in self._shared_y_axes.get_siblings(self): if other is not self: other.set_ylim(self.viewLim.intervaly, emit=False) - - if self.figure.canvas is not None: - self.figure.canvas.draw_idle() + if other.figure != self.figure and other.figure.canvas is not None: + other.figure.canvas.draw_idle() return ymin, ymax def get_yscale(self): Modified: branches/transforms/lib/matplotlib/backends/backend_tkagg.py =================================================================== --- branches/transforms/lib/matplotlib/backends/backend_tkagg.py 2007-11-15 17:23:03 UTC (rev 4310) +++ branches/transforms/lib/matplotlib/backends/backend_tkagg.py 2007-11-15 18:10:54 UTC (rev 4311) @@ -146,7 +146,7 @@ def __init__(self, figure, master=None, resize_callback=None): FigureCanvasAgg.__init__(self, figure) - self._idle = False + self._idle = True t1,t2,w,h = self.figure.bbox.bounds w, h = int(w), int(h) self._tkcanvas = Tk.Canvas( This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-11-20 21:00:22
|
Revision: 4398 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4398&view=rev Author: mdboom Date: 2007-11-20 13:00:20 -0800 (Tue, 20 Nov 2007) Log Message: ----------- Support mixed-mode rendering the PDF backend. This allows some things to be rendered as vectors and some as rasters. At the moment, mostly as a proof-of-concept, all quadmeshes are rendered as rasters with the PDF backend. Also make PDF backend resolution independent. Modified Paths: -------------- branches/transforms/lib/matplotlib/backend_bases.py branches/transforms/lib/matplotlib/backends/backend_pdf.py branches/transforms/lib/matplotlib/collections.py Added Paths: ----------- branches/transforms/lib/matplotlib/backends/backend_mixed.py Modified: branches/transforms/lib/matplotlib/backend_bases.py =================================================================== --- branches/transforms/lib/matplotlib/backend_bases.py 2007-11-20 20:21:53 UTC (rev 4397) +++ branches/transforms/lib/matplotlib/backend_bases.py 2007-11-20 21:00:20 UTC (rev 4398) @@ -9,6 +9,7 @@ import numpy as npy import matplotlib.cbook as cbook import matplotlib.colors as colors +import matplotlib._image as _image import matplotlib.path as path import matplotlib.transforms as transforms import matplotlib.widgets as widgets @@ -328,7 +329,13 @@ def strip_math(self, s): return cbook.strip_math(s) + def start_rasterizing(self): + pass + def stop_rasterizing(self): + pass + + class GraphicsContextBase: """An abstract base class that provides color, line styles, etc... """ Added: branches/transforms/lib/matplotlib/backends/backend_mixed.py =================================================================== --- branches/transforms/lib/matplotlib/backends/backend_mixed.py (rev 0) +++ branches/transforms/lib/matplotlib/backends/backend_mixed.py 2007-11-20 21:00:20 UTC (rev 4398) @@ -0,0 +1,142 @@ +from matplotlib._image import frombuffer +from matplotlib.backends.backend_agg import RendererAgg + +class MixedModeRenderer(object): + """ + A helper class to implement a renderer that switches between + vector and raster drawing. An example may be a PDF writer, where + most things are drawn with PDF vector commands, but some very + complex objects, such as quad meshes, are rasterised and then + output as images. + """ + def __init__(self, width, height, dpi, vector_renderer, raster_renderer_class=None): + """ + width: The width of the canvas in logical units + + height: The height of the canvas in logical units + + dpi: The dpi of the canvas + + vector_renderer: An instance of a subclass of RendererBase + that will be used for the vector drawing. + + raster_renderer_class: The renderer class to use for the + raster drawing. If not provided, this will use the Agg + backend (which is currently the only viable option anyway.) + """ + if raster_renderer_class is None: + raster_renderer_class = RendererAgg + + self._raster_renderer_class = raster_renderer_class + self._width = width + self._height = height + self._dpi = dpi + + assert not vector_renderer.option_image_nocomposite() + self._vector_renderer = vector_renderer + vector_renderer.start_rasterizing = self.start_rasterizing + vector_renderer.stop_rasterizing = self.stop_rasterizing + + self._raster_renderer = None + self._rasterizing = False + + self._renderer = self._vector_renderer + + def start_rasterizing(self): + """ + Enter "raster" mode. All subsequent drawing commands (until + stop_rasterizing is called) will be drawn with the raster + backend. + + If start_rasterizing is called multiple times before + stop_rasterizing is called, this method has no effect. + """ + if not self._rasterizing: + self._raster_renderer = self._raster_renderer_class( + self._width*self._dpi, self._height*self._dpi, self._dpi) + self._raster_renderer.start_rasterizing = self.start_rasterizing + self._raster_renderer.stop_rasterizing = self.stop_rasterizing + self._renderer = self._raster_renderer + self._rasterizing = True + + def stop_rasterizing(self): + """ + Exit "raster" mode. All of the drawing that was done since + the last start_rasterizing command will be copied to the + vector backend by calling draw_image. + + If stop_rasterizing is called multiple times before + start_rasterizing is called, this method has no effect. + """ + if self._rasterizing: + width, height = self._width * self._dpi, self._height * self._dpi + buffer = self._raster_renderer.buffer_rgba(0, 0) + image = frombuffer(buffer, width, height, True) + image.is_grayscale = False + + self._renderer = self._vector_renderer + self._renderer.draw_image(0, 0, image, None) + self._raster_renderer = None + self._rasterizing = False + + def get_canvas_width_height(self): + 'return the canvas width and height in display coords' + return self._width, self._height + + # The rest of this methods simply delegate to the currently active + # rendering backend. + + def open_group(self, *args, **kwargs): + return self._renderer.open_group(*args, **kwargs) + + def close_group(self, *args, **kwargs): + return self._renderer.close_group(*args, **kwargs) + + def draw_path(self, *args, **kwargs): + return self._renderer.draw_path(*args, **kwargs) + + def draw_markers(self, *args, **kwargs): + return self._renderer.draw_markers(*args, **kwargs) + + def draw_path_collection(self, *args, **kwargs): + return self._renderer.draw_path_collection(*args, **kwargs) + + def draw_quad_mesh(self, *args, **kwargs): + return self._renderer.draw_quad_mesh(*args, **kwargs) + + def get_image_magnification(self, *args, **kwargs): + return self._renderer.get_image_magnification(*args, **kwargs) + + def draw_image(self, *args, **kwargs): + return self._renderer.draw_image(*args, **kwargs) + + def draw_tex(self, *args, **kwargs): + return self._renderer.draw_tex(*args, **kwargs) + + def draw_text(self, *args, **kwargs): + return self._renderer.draw_text(*args, **kwargs) + + def flipy(self, *args, **kwargs): + return self._renderer.flipy(*args, **kwargs) + + def option_image_nocomposite(self, *args, **kwargs): + return self._vector_renderer.option_image_nocomposite(*args, **kwargs) + + def get_texmanager(self, *args, **kwargs): + return self._renderer.get_texmanager(*args, **kwargs) + + def get_text_width_height_descent(self, *args, **kwargs): + return self._renderer.get_text_width_height_descent(*args, **kwargs) + + def new_gc(self, *args, **kwargs): + return self._renderer.new_gc(*args, **kwargs) + + def points_to_pixels(self, *args, **kwargs): + return self._renderer.points_to_pixels(*args, **kwargs) + + def strip_math(self, *args, **kwargs): + return self._renderer(*args, **kwargs) + + def finalize(self, *args, **kwargs): + return self._renderer.finalize(*args, **kwargs) + Modified: branches/transforms/lib/matplotlib/backends/backend_pdf.py =================================================================== --- branches/transforms/lib/matplotlib/backends/backend_pdf.py 2007-11-20 20:21:53 UTC (rev 4397) +++ branches/transforms/lib/matplotlib/backends/backend_pdf.py 2007-11-20 21:00:20 UTC (rev 4398) @@ -20,10 +20,11 @@ from sets import Set import matplotlib -from matplotlib import __version__, rcParams, agg, get_data_path +from matplotlib import __version__, rcParams, get_data_path from matplotlib._pylab_helpers import Gcf from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\ 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 from matplotlib.figure import Figure @@ -327,8 +328,9 @@ class PdfFile: """PDF file with one page.""" - def __init__(self, width, height, filename): + def __init__(self, width, height, dpi, filename): self.width, self.height = width, height + self.dpi = dpi self.nextObject = 1 # next free object id self.xrefTable = [ [0, 65535, 'the zero object'] ] self.passed_in_file_object = False @@ -379,7 +381,7 @@ thePage = { 'Type': Name('Page'), 'Parent': pagesObject, 'Resources': resourceObject, - 'MediaBox': [ 0, 0, 72*width, 72*height ], + 'MediaBox': [ 0, 0, dpi*width, dpi*height ], 'Contents': contentObject } self.writeObject(thePageObject, thePage) @@ -1003,8 +1005,9 @@ rgba = npy.fromstring(s, npy.uint8) rgba.shape = (h, w, 4) - rgb = rgba[:,:,:4] - return h, w, rgb.tostring() + rgb = rgba[:,:,:3] + a = rgba[:,:,3:] + return h, w, rgb.tostring(), a.tostring() def _gray(self, im, rc=0.3, gc=0.59, bc=0.11): rgbat = im.as_rgba_str() @@ -1022,20 +1025,36 @@ img.flipud_out() if img.is_grayscale: height, width, data = self._gray(img) - colorspace = Name('DeviceGray') + self.beginStream( + pair[1].id, + self.reserveObject('length of image stream'), + {'Type': Name('XObject'), 'Subtype': Name('Image'), + 'Width': width, 'Height': height, + 'ColorSpace': Name('DeviceGray'), 'BitsPerComponent': 8 }) + self.currentstream.write(data) # TODO: predictors (i.e., output png) + self.endStream() else: - height, width, data = self._rgb(img) - colorspace = Name('DeviceRGB') + height, width, data, adata = self._rgb(img) + smaskObject = self.reserveObject("smask") + stream = self.beginStream( + smaskObject.id, + self.reserveObject('length of smask stream'), + {'Type': Name('XObject'), 'Subtype': Name('Image'), + 'Width': width, 'Height': height, + 'ColorSpace': Name('DeviceGray'), 'BitsPerComponent': 8 }) + self.currentstream.write(adata) # TODO: predictors (i.e., output png) + self.endStream() - self.beginStream( - pair[1].id, - self.reserveObject('length of image stream'), - {'Type': Name('XObject'), 'Subtype': Name('Image'), - 'Width': width, 'Height': height, - 'ColorSpace': colorspace, 'BitsPerComponent': 8 }) - self.currentstream.write(data) # TODO: predictors (i.e., output png) - self.endStream() - + self.beginStream( + pair[1].id, + self.reserveObject('length of image stream'), + {'Type': Name('XObject'), 'Subtype': Name('Image'), + 'Width': width, 'Height': height, + 'ColorSpace': Name('DeviceRGB'), 'BitsPerComponent': 8, + 'SMask': smaskObject}) + self.currentstream.write(data) # TODO: predictors (i.e., output png) + self.endStream() + img.flipud_out() def markerObject(self, path, trans, fillp, lw): @@ -1152,7 +1171,7 @@ self.afm_font_cache = {} self.file.used_characters = self.used_characters = {} self.mathtext_parser = MathTextParser("Pdf") - self.image_magnification = dpi/72.0 + self.dpi = dpi self.tex_font_map = None def finalize(self): @@ -1194,19 +1213,16 @@ stat_key, (realpath, Set())) used_characters[1].update(set) - def get_image_magnification(self): - return self.image_magnification - def draw_image(self, x, y, im, bbox, clippath=None, clippath_trans=None): #print >>sys.stderr, "draw_image called" # MGDTODO: Support clippath here gc = self.new_gc() - gc.set_clip_rectangle(bbox.bounds) + if bbox is not None: + gc.set_clip_rectangle(bbox) self.check_gc(gc) h, w = im.get_size_out() - h, w = h/self.image_magnification, w/self.image_magnification imob = self.file.imageObject(im) self.file.output(Op.gsave, w, 0, 0, h, x, y, Op.concat_matrix, imob, Op.use_xobject, Op.grestore) @@ -1246,7 +1262,7 @@ def draw_mathtext(self, gc, x, y, s, prop, angle): # TODO: fix positioning and encoding width, height, descent, glyphs, rects, used_characters = \ - self.mathtext_parser.parse(s, 72, prop) + self.mathtext_parser.parse(s, self.dpi, prop) self.merge_used_characters(used_characters) # When using Type 3 fonts, we can't use character codes higher @@ -1311,7 +1327,7 @@ texmanager = self.get_texmanager() fontsize = prop.get_size_in_points() dvifile = texmanager.make_dvi(s, fontsize) - dvi = dviread.Dvi(dvifile, 72) + dvi = dviread.Dvi(dvifile, self.dpi) page = iter(dvi).next() dvi.close() @@ -1539,13 +1555,13 @@ texmanager = self.get_texmanager() fontsize = prop.get_size_in_points() dvifile = texmanager.make_dvi(s, fontsize) - dvi = dviread.Dvi(dvifile, 72) + dvi = dviread.Dvi(dvifile, self.dpi) page = iter(dvi).next() dvi.close() return page.width, page.height, page.descent if ismath: w, h, d, glyphs, rects, used_characters = \ - self.mathtext_parser.parse(s, 72, prop) + self.mathtext_parser.parse(s, self.dpi, prop) elif rcParams['pdf.use14corefonts']: font = self._get_font_afm(prop) @@ -1583,14 +1599,14 @@ font = FT2Font(str(filename)) self.truetype_font_cache[key] = font font.clear() - font.set_size(prop.get_size_in_points(), 72.0) + font.set_size(prop.get_size_in_points(), self.dpi) return font def flipy(self): return False def get_canvas_width_height(self): - return self.file.width / 72.0, self.file.height / 72.0 + return self.file.width / self.dpi, self.file.height / self.dpi def new_gc(self): return GraphicsContextPdf(self.file) @@ -1830,11 +1846,12 @@ return 'pdf' def print_pdf(self, filename, **kwargs): - dpi = kwargs.get('dpi', None) - self.figure.set_dpi(72) # Override the dpi kwarg + dpi = kwargs.get('dpi', 72) + self.figure.set_dpi(dpi) # Override the dpi kwarg width, height = self.figure.get_size_inches() - file = PdfFile(width, height, filename) - renderer = RendererPdf(file, dpi) + file = PdfFile(width, height, dpi, filename) + renderer = MixedModeRenderer( + width, height, dpi, RendererPdf(file, dpi)) self.figure.draw(renderer) renderer.finalize() file.close() Modified: branches/transforms/lib/matplotlib/collections.py =================================================================== --- branches/transforms/lib/matplotlib/collections.py 2007-11-20 20:21:53 UTC (rev 4397) +++ branches/transforms/lib/matplotlib/collections.py 2007-11-20 21:00:20 UTC (rev 4398) @@ -453,11 +453,13 @@ offsets = transOffset.transform_non_affine(offsets) transOffset = transOffset.get_affine() + renderer.start_rasterizing() renderer.draw_quad_mesh( transform.frozen(), self.clipbox, clippath, clippath_trans, self._meshWidth, self._meshHeight, self._coordinates, offsets, transOffset, self._facecolors, self._antialiased, self._showedges) + renderer.stop_rasterizing() renderer.close_group(self.__class__.__name__) class PolyCollection(Collection): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-11-26 15:30:15
|
Revision: 4440 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4440&view=rev Author: mdboom Date: 2007-11-26 07:30:12 -0800 (Mon, 26 Nov 2007) Log Message: ----------- Support mixed-mode rendering in the SVG backend. Modified Paths: -------------- branches/transforms/lib/matplotlib/backend_bases.py branches/transforms/lib/matplotlib/backends/backend_mixed.py branches/transforms/lib/matplotlib/backends/backend_svg.py Modified: branches/transforms/lib/matplotlib/backend_bases.py =================================================================== --- branches/transforms/lib/matplotlib/backend_bases.py 2007-11-26 15:18:40 UTC (rev 4439) +++ branches/transforms/lib/matplotlib/backend_bases.py 2007-11-26 15:30:12 UTC (rev 4440) @@ -380,6 +380,8 @@ Return the alpha value used for blending - not supported on all backends """ + if len(self._rgb) == 4: + return self._rgb[3] return self._alpha def get_antialiased(self): Modified: branches/transforms/lib/matplotlib/backends/backend_mixed.py =================================================================== --- branches/transforms/lib/matplotlib/backends/backend_mixed.py 2007-11-26 15:18:40 UTC (rev 4439) +++ branches/transforms/lib/matplotlib/backends/backend_mixed.py 2007-11-26 15:30:12 UTC (rev 4440) @@ -41,11 +41,11 @@ self._set_current_renderer(vector_renderer) _methods = """ - open_group close_group draw_path draw_markers - draw_path_collection draw_quad_mesh get_image_magnification - draw_image draw_tex draw_text flipy option_image_nocomposite - get_texmanager get_text_width_height_descent new_gc - points_to_pixels strip_math finalize + close_group draw_image draw_markers draw_path + draw_path_collection draw_quad_mesh draw_tex draw_text + finalize flipy get_canvas_width_height get_image_magnification + get_texmanager get_text_width_height_descent new_gc open_group + option_image_nocomposite points_to_pixels strip_math """.split() def _set_current_renderer(self, renderer): self._renderer = renderer @@ -93,7 +93,3 @@ self._renderer.draw_image(l, height - b - h, image, None) self._raster_renderer = None self._rasterizing = False - - def get_canvas_width_height(self): - 'return the canvas width and height in display coords' - return self._width, self._height Modified: branches/transforms/lib/matplotlib/backends/backend_svg.py =================================================================== --- branches/transforms/lib/matplotlib/backends/backend_svg.py 2007-11-26 15:18:40 UTC (rev 4439) +++ branches/transforms/lib/matplotlib/backends/backend_svg.py 2007-11-26 15:30:12 UTC (rev 4440) @@ -5,6 +5,7 @@ from matplotlib import verbose, __version__, rcParams 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.colors import rgb2hex from matplotlib.figure import Figure @@ -93,7 +94,7 @@ return 'fill: %s; stroke: %s; stroke-width: %s; ' \ 'stroke-linejoin: %s; stroke-linecap: %s; %s opacity: %s' % ( fill, - rgb2hex(gc.get_rgb()), + rgb2hex(gc.get_rgb()[:3]), linewidth, gc.get_joinstyle(), _capstyle_d[gc.get_capstyle()], @@ -288,14 +289,12 @@ font.set_text(s, 0.0, flags=LOAD_NO_HINTING) y -= font.get_descent() / 64.0 - thetext = escape_xml_text(s) - fontfamily = font.family_name - fontstyle = prop.get_style() fontsize = prop.get_size_in_points() - color = rgb2hex(gc.get_rgb()) + color = rgb2hex(gc.get_rgb()[:3]) if rcParams['svg.embed_char_paths']: - svg = ['<g transform="'] + + svg = ['<g style="fill: %s" transform="' % color] if angle != 0: svg.append('translate(%s,%s)rotate(%1.1f)' % (x,y,-angle)) elif x != 0 or y != 0: @@ -330,6 +329,10 @@ svg.append('</g>\n') svg = ''.join(svg) else: + thetext = escape_xml_text(s) + fontfamily = font.family_name + fontstyle = prop.get_style() + style = 'font-size: %f; font-family: %s; font-style: %s; fill: %s;'%(fontsize, fontfamily,fontstyle, color) if angle!=0: transform = 'transform="translate(%s,%s) rotate(%1.1f) translate(%s,%s)"' % (x,y,-angle,-x,-y) @@ -393,7 +396,7 @@ self.mathtext_parser.parse(s, 72, prop) svg_glyphs = svg_elements.svg_glyphs svg_rects = svg_elements.svg_rects - color = rgb2hex(gc.get_rgb()) + color = rgb2hex(gc.get_rgb()[:3]) self.open_group("mathtext") @@ -466,7 +469,7 @@ self._svgwriter.write (''.join(svg)) self.close_group("mathtext") - def finish(self): + def finalize(self): write = self._svgwriter.write if len(self._char_defs): write('<defs id="fontpaths">\n') @@ -501,34 +504,23 @@ 'svgz': 'Scalable Vector Graphics'} def print_svg(self, filename, *args, **kwargs): - 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) - + svgwriter = codecs.open(filename, 'w', 'utf-8') + return self._print_svg(filename, svgwriter) + def print_svgz(self, filename, *args, **kwargs): - if is_string_like(filename): - gzipwriter = gzip.GzipFile(filename, 'w') - fh_to_close = svgwriter = codecs.EncodedFile(gzipwriter, 'utf-8') - elif is_writable_file_like(filename): - fh_to_close = gzipwriter = gzip.GzipFile(fileobj=filename, mode='w') - svgwriter = codecs.EncodedFile(gzipwriter, 'utf-8') - else: - raise ValueError("filename must be a path or a file-like object") - return self._print_svg(filename, svgwriter, fh_to_close) + 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() w, h = width*72, height*72 - renderer = RendererSVG(w, h, svgwriter, filename) + renderer = MixedModeRenderer( + width, height, 72.0, RendererSVG(w, h, svgwriter, filename)) self.figure.draw(renderer) - renderer.finish() + renderer.finalize() if fh_to_close is not None: svgwriter.close() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-11-30 16:16:52
|
Revision: 4527 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4527&view=rev Author: mdboom Date: 2007-11-30 08:16:34 -0800 (Fri, 30 Nov 2007) Log Message: ----------- Fix Cairo alpha-blending. Modified Paths: -------------- branches/transforms/lib/matplotlib/backend_bases.py branches/transforms/lib/matplotlib/backends/backend_cairo.py Modified: branches/transforms/lib/matplotlib/backend_bases.py =================================================================== --- branches/transforms/lib/matplotlib/backend_bases.py 2007-11-30 16:08:52 UTC (rev 4526) +++ branches/transforms/lib/matplotlib/backend_bases.py 2007-11-30 16:16:34 UTC (rev 4527) @@ -27,7 +27,7 @@ The following methods *should* be implemented in the backend for optimization reasons: - + draw_markers draw_path_collection draw_quad_mesh @@ -73,7 +73,7 @@ self.draw_path(gc, marker_path, marker_trans + transforms.Affine2D().translate(x, y), rgbFace) - + def draw_path_collection(self, master_transform, cliprect, clippath, clippath_trans, paths, all_transforms, offsets, offsetTrans, facecolors, edgecolors, linewidths, @@ -126,12 +126,12 @@ else: edgecolors = facecolors linewidths = npy.array([1.0], npy.float_) - + return self.draw_path_collection( master_transform, cliprect, clippath, clippath_trans, paths, [], offsets, offsetTrans, facecolors, edgecolors, linewidths, [], [antialiased]) - + def _iter_collection_raw_paths(self, master_transform, paths, all_transforms): """ This is a helper method (along with _iter_collection) to make @@ -203,20 +203,20 @@ return if Noffsets: toffsets = offsetTrans.transform(offsets) - + gc = self.new_gc() gc.set_clip_rectangle(cliprect) if clippath is not None: clippath = transforms.TransformedPath(clippath, clippath_trans) gc.set_clip_path(clippath) - + if Nfacecolors == 0: rgbFace = None if Nedgecolors == 0: gc.set_linewidth(0.0) - + xo, yo = 0, 0 for i in xrange(N): path_id = path_ids[i % Npaths] @@ -233,7 +233,7 @@ gc.set_antialiased(antialiaseds[i % Naa]) yield xo, yo, path_id, gc, rgbFace - + def get_image_magnification(self): """ Get the factor by which to magnify images passed to draw_image. @@ -282,7 +282,7 @@ your text. """ raise NotImplementedError - + def flipy(self): """return true if y small numbers are top for renderer Is used for drawing text (text.py) and images (image.py) only @@ -334,8 +334,8 @@ def stop_rasterizing(self): pass - + class GraphicsContextBase: """An abstract base class that provides color, line styles, etc... """ @@ -380,8 +380,6 @@ Return the alpha value used for blending - not supported on all backends """ - if len(self._rgb) == 4: - return self._rgb[3] return self._alpha def get_antialiased(self): @@ -795,7 +793,7 @@ # can't delete the artist while h: print "Removing",h - if h.remove(): + if h.remove(): self.draw_idle() break parent = None @@ -804,7 +802,7 @@ parent = p break h = parent - + def onHilite(self, ev): """ Mouse event processor which highlights the artists @@ -980,7 +978,7 @@ # a) otherwise we'd have cyclical imports, since all of these # classes inherit from FigureCanvasBase # b) so we don't import a bunch of stuff the user may never use - + def print_emf(self, *args, **kwargs): from backends.backend_emf import FigureCanvasEMF # lazy import emf = self.switch_backends(FigureCanvasEMF) @@ -990,7 +988,7 @@ from backends.backend_ps import FigureCanvasPS # lazy import ps = self.switch_backends(FigureCanvasPS) return ps.print_eps(*args, **kwargs) - + def print_pdf(self, *args, **kwargs): from backends.backend_pdf import FigureCanvasPdf # lazy import pdf = self.switch_backends(FigureCanvasPdf) @@ -1000,7 +998,7 @@ from backends.backend_agg import FigureCanvasAgg # lazy import agg = self.switch_backends(FigureCanvasAgg) return agg.print_png(*args, **kwargs) - + def print_ps(self, *args, **kwargs): from backends.backend_ps import FigureCanvasPS # lazy import ps = self.switch_backends(FigureCanvasPS) @@ -1016,12 +1014,12 @@ from backends.backend_svg import FigureCanvasSVG # lazy import svg = self.switch_backends(FigureCanvasSVG) return svg.print_svg(*args, **kwargs) - + def print_svgz(self, *args, **kwargs): from backends.backend_svg import FigureCanvasSVG # lazy import svg = self.switch_backends(FigureCanvasSVG) return svg.print_svgz(*args, **kwargs) - + def get_supported_filetypes(self): return self.filetypes @@ -1031,7 +1029,7 @@ groupings.setdefault(name, []).append(ext) groupings[name].sort() return groupings - + def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w', orientation='portrait', format=None, **kwargs): """ @@ -1069,7 +1067,7 @@ if dpi is None: dpi = rcParams['savefig.dpi'] - + origDPI = self.figure.dpi origfacecolor = self.figure.get_facecolor() origedgecolor = self.figure.get_edgecolor() @@ -1092,12 +1090,12 @@ self.figure.set_edgecolor(origedgecolor) self.figure.set_canvas(self) self.figure.canvas.draw() - + return result def get_default_filetype(self): raise NotImplementedError - + def set_window_title(self, title): """ Set the title text of the window containing the figure. Note that Modified: branches/transforms/lib/matplotlib/backends/backend_cairo.py =================================================================== --- branches/transforms/lib/matplotlib/backends/backend_cairo.py 2007-11-30 16:08:52 UTC (rev 4526) +++ branches/transforms/lib/matplotlib/backends/backend_cairo.py 2007-11-30 16:16:34 UTC (rev 4527) @@ -94,8 +94,8 @@ def set_ctx_from_surface (self, surface): self.ctx = cairo.Context (surface) self.ctx.save() # restore, save - when call new_gc() - + def set_width_height(self, width, height): self.width = width self.height = height @@ -111,12 +111,12 @@ if len(fill_c) == 3: ctx.set_source_rgba (fill_c[0], fill_c[1], fill_c[2], alpha) else: - ctx.set_source_rgba (*fill_c) + ctx.set_source_rgba (fill_c[0], fill_c[1], fill_c[2], alpha*fill_c[3]) ctx.fill_preserve() ctx.restore() ctx.stroke() - + #@staticmethod def convert_path(ctx, tpath): for points, code in tpath.iter_segments(): @@ -134,7 +134,7 @@ ctx.close_path() convert_path = staticmethod(convert_path) - + def draw_path(self, gc, path, transform, rgbFace=None): if len(path.vertices) > 18980: raise ValueError("The Cairo backend can not draw paths longer than 18980 points.") @@ -143,7 +143,7 @@ transform = transform + \ Affine2D().scale(1.0, -1.0).translate(0, self.height) tpath = transform.transform_path(path) - + ctx.new_path() self.convert_path(ctx, tpath) @@ -203,11 +203,11 @@ 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, @@ -228,7 +228,7 @@ ctx.restore() - + def flipy(self): if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) return True @@ -281,8 +281,8 @@ def points_to_pixels(self, points): if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) return points/72.0 * self.dpi - - + + class GraphicsContextCairo(GraphicsContextBase): _joind = { 'bevel' : cairo.LINE_JOIN_BEVEL, @@ -323,6 +323,8 @@ def set_clip_rectangle(self, rectangle): self._cliprect = rectangle + if rectangle is None: + return x,y,w,h = rectangle.bounds # pixel-aligned clip-regions are faster @@ -345,7 +347,7 @@ RendererCairo.convert_path(ctx, tpath) ctx.clip() - + def set_dashes(self, offset, dashes): self._dashes = offset, dashes if dashes == None: @@ -382,7 +384,7 @@ self._linewidth = w self.ctx.set_line_width (self.renderer.points_to_pixels(w)) - + def new_figure_manager(num, *args, **kwargs): # called by backends/__init__.py """ Create a new figure manager instance @@ -406,7 +408,7 @@ self.figure.draw (renderer) surface.write_to_png (fobj) - + def print_pdf(self, fobj, *args, **kwargs): return self._save(fobj, 'pdf', *args, **kwargs) @@ -418,16 +420,16 @@ def print_svgz(self, fobj, *args, **kwargs): return self._save(fobj, 'svgz', *args, **kwargs) - + def get_default_filetype(self): return rcParams['cairo.format'] - + def _save (self, fo, format, **kwargs): # save PDF/PS/SVG orientation = kwargs.get('orientation', 'portrait') dpi = 72 - self.figure.dpi.set (dpi) + self.figure.dpi = dpi w_in, h_in = self.figure.get_size_inches() width_in_points, height_in_points = w_in * dpi, h_in * dpi This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-12-05 18:56:25
|
Revision: 4625 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4625&view=rev Author: mdboom Date: 2007-12-05 10:56:18 -0800 (Wed, 05 Dec 2007) Log Message: ----------- Make things more robust to changes in dpi. Modified Paths: -------------- branches/transforms/lib/matplotlib/axis.py branches/transforms/lib/matplotlib/backends/backend_agg.py branches/transforms/lib/matplotlib/backends/backend_cairo.py branches/transforms/lib/matplotlib/text.py Modified: branches/transforms/lib/matplotlib/axis.py =================================================================== --- branches/transforms/lib/matplotlib/axis.py 2007-12-05 18:14:38 UTC (rev 4624) +++ branches/transforms/lib/matplotlib/axis.py 2007-12-05 18:56:18 UTC (rev 4625) @@ -86,8 +86,6 @@ self._loc = loc self._size = size - self._padPixels = self.figure.dpi * self._pad * (1/72.0) - self.tick1line = self._get_tick1line() self.tick2line = self._get_tick2line() self.gridline = self._get_gridline() @@ -115,6 +113,9 @@ self.gridline.set_clip_path(clippath, transform) set_clip_path.__doc__ = Artist.set_clip_path.__doc__ + def get_pad_pixels(self): + return self.figure.dpi * self._pad / 72.0 + def contains(self, mouseevent): """Test whether the mouse event occured in the Tick marks. @@ -222,7 +223,7 @@ # get the affine as an a,b,c,d,tx,ty list # x in data coords, y in axes coords #t = Text( - trans, vert, horiz = self.axes.get_xaxis_text1_transform(self._padPixels) + trans, vert, horiz = self.axes.get_xaxis_text1_transform(self.get_pad_pixels()) t = TextWithDash( x=0, y=0, @@ -244,7 +245,7 @@ 'Get the default Text 2 instance' # x in data coords, y in axes coords #t = Text( - trans, vert, horiz = self.axes.get_xaxis_text2_transform(self._padPixels) + trans, vert, horiz = self.axes.get_xaxis_text2_transform(self.get_pad_pixels()) t = TextWithDash( x=0, y=1, @@ -341,7 +342,7 @@ 'Get the default Text instance' # x in axes coords, y in data coords #t = Text( - trans, vert, horiz = self.axes.get_yaxis_text1_transform(self._padPixels) + trans, vert, horiz = self.axes.get_yaxis_text1_transform(self.get_pad_pixels()) t = TextWithDash( x=0, y=0, @@ -361,7 +362,7 @@ 'Get the default Text instance' # x in axes coords, y in data coords #t = Text( - trans, vert, horiz = self.axes.get_yaxis_text2_transform(self._padPixels) + trans, vert, horiz = self.axes.get_yaxis_text2_transform(self.get_pad_pixels()) t = TextWithDash( x=1, y=0, @@ -1173,7 +1174,7 @@ """ bbox, bbox2 = self.get_ticklabel_extents(renderer) # MGDTODO: Need a better way to get the pad - padPixels = self.majorTicks[0]._padPixels + padPixels = self.majorTicks[0].get_pad_pixels() above = 0.0 if bbox2.height: @@ -1409,7 +1410,7 @@ def get_text_widths(self, renderer): bbox, bbox2 = self.get_ticklabel_extents(renderer) # MGDTODO: Need a better way to get the pad - padPixels = self.majorTicks[0]._padPixels + padPixels = self.majorTicks[0].get_pad_pixels() left = 0.0 if bbox.width: Modified: branches/transforms/lib/matplotlib/backends/backend_agg.py =================================================================== --- branches/transforms/lib/matplotlib/backends/backend_agg.py 2007-12-05 18:14:38 UTC (rev 4624) +++ branches/transforms/lib/matplotlib/backends/backend_agg.py 2007-12-05 18:56:18 UTC (rev 4625) @@ -146,10 +146,9 @@ def draw_tex(self, gc, x, y, s, prop, angle): # todo, handle props, angle, origins size = prop.get_size_in_points() - dpi = self.dpi texmanager = self.get_texmanager() - key = s, size, dpi, angle, texmanager.get_font_config() + key = s, size, self.dpi, angle, texmanager.get_font_config() im = self.texd.get(key) if im is None: Z = texmanager.get_grey(s, size, dpi) @@ -285,10 +284,16 @@ def print_raw(self, filename, *args, **kwargs): FigureCanvasAgg.draw(self) - self.get_renderer()._renderer.write_rgba(str(filename)) + original_dpi = renderer.dpi + renderer.dpi = self.figure.dpi + renderer._renderer.write_rgba(str(filename)) + renderer.dpi = original_dpi print_rgba = print_raw def print_png(self, filename, *args, **kwargs): FigureCanvasAgg.draw(self) - self.get_renderer()._renderer.write_png(filename, self.figure.dpi) - + renderer = self.get_renderer() + original_dpi = renderer.dpi + renderer.dpi = self.figure.dpi + renderer._renderer.write_png(filename, self.figure.dpi) + renderer.dpi = original_dpi Modified: branches/transforms/lib/matplotlib/backends/backend_cairo.py =================================================================== --- branches/transforms/lib/matplotlib/backends/backend_cairo.py 2007-12-05 18:14:38 UTC (rev 4624) +++ branches/transforms/lib/matplotlib/backends/backend_cairo.py 2007-12-05 18:56:18 UTC (rev 4625) @@ -182,7 +182,6 @@ self.fontangles [prop.get_style()], self.fontweights[prop.get_weight()]) - # size = prop.get_size_in_points() * self.dpi.get() / 96.0 size = prop.get_size_in_points() * self.dpi / 72.0 ctx.save() @@ -214,7 +213,6 @@ self.fontangles [fontProp.style], self.fontweights[fontProp.weight]) - # size = prop.get_size_in_points() * self.dpi.get() / 96.0 size = fontsize * self.dpi / 72.0 ctx.set_font_size(size) ctx.show_text(s.encode("utf-8")) @@ -257,7 +255,6 @@ # Cairo (says it) uses 1/96 inch user space units, ref: cairo_gstate.c # but if /96.0 is used the font is too small - #size = prop.get_size_in_points() * self.dpi.get() / 96.0 size = prop.get_size_in_points() * self.dpi / 72.0 # problem - scale remembers last setting and font can become Modified: branches/transforms/lib/matplotlib/text.py =================================================================== --- branches/transforms/lib/matplotlib/text.py 2007-12-05 18:14:38 UTC (rev 4624) +++ branches/transforms/lib/matplotlib/text.py 2007-12-05 18:56:18 UTC (rev 4625) @@ -384,7 +384,8 @@ x, y = self.get_position() return (x, y, self._text, self._color, self._verticalalignment, self._horizontalalignment, - hash(self._fontproperties), self._rotation + hash(self._fontproperties), self._rotation, + self._renderer.dpi ) def get_text(self): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-12-13 18:42:58
|
Revision: 4729 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4729&view=rev Author: mdboom Date: 2007-12-13 10:42:54 -0800 (Thu, 13 Dec 2007) Log Message: ----------- Fix some regular expressions. Modified Paths: -------------- branches/transforms/lib/matplotlib/fontconfig_pattern.py branches/transforms/lib/matplotlib/mathtext.py Modified: branches/transforms/lib/matplotlib/fontconfig_pattern.py =================================================================== --- branches/transforms/lib/matplotlib/fontconfig_pattern.py 2007-12-13 18:30:45 UTC (rev 4728) +++ branches/transforms/lib/matplotlib/fontconfig_pattern.py 2007-12-13 18:42:54 UTC (rev 4729) @@ -35,8 +35,8 @@ See here for a rough specification of these patterns: http://www.fontconfig.org/fontconfig-user.html """ - + _constants = { 'thin' : ('weight', 'light'), 'extralight' : ('weight', 'light'), @@ -63,12 +63,12 @@ 'extraexpanded' : ('width', 'extra-expanded'), 'ultraexpanded' : ('width', 'ultra-expanded') } - + def __init__(self): family = Regex(r'([^%s]|(\\[%s]))*' % (family_punc, family_punc)) \ .setParseAction(self._family) - size = Regex(r'[0-9.]+') \ + size = Regex(r"([0-9]+\.?[0-9]*|\.[0-9]+)") \ .setParseAction(self._size) name = Regex(r'[a-z]+') \ .setParseAction(self._name) @@ -79,7 +79,7 @@ families =(family + ZeroOrMore( Literal(',') - + family) + + family) ).setParseAction(self._families) point_sizes =(size @@ -118,10 +118,10 @@ self._parser.parseString(pattern) except self.ParseException, e: raise ValueError("Could not parse font string: '%s'\n%s" % (pattern, e)) - + self._properties = None return props - + def _family(self, s, loc, tokens): return [family_unescape(r'\1', tokens[0])] @@ -141,7 +141,7 @@ def _point_sizes(self, s, loc, tokens): self._properties['size'] = tokens return [] - + def _property(self, s, loc, tokens): if len(tokens) == 1: if tokens[0] in self._constants: Modified: branches/transforms/lib/matplotlib/mathtext.py =================================================================== --- branches/transforms/lib/matplotlib/mathtext.py 2007-12-13 18:30:45 UTC (rev 4728) +++ branches/transforms/lib/matplotlib/mathtext.py 2007-12-13 18:42:54 UTC (rev 4729) @@ -1984,7 +1984,7 @@ autoDelim = Forward().setParseAction(self.auto_sized_delimiter) self._expression = Forward().setParseAction(self.finish).setName("finish") - float = Regex(r"-?[0-9]*(\.[0-9]+)?") + float = Regex(r"[-+]?([0-9]+\.?[0-9]*|\.[0-9]+)") lbrace = Literal('{').suppress() rbrace = Literal('}').suppress() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-12-18 15:35:10
|
Revision: 4765 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4765&view=rev Author: mdboom Date: 2007-12-18 07:35:06 -0800 (Tue, 18 Dec 2007) Log Message: ----------- Fix log scaling of polar plots. Modified Paths: -------------- branches/transforms/lib/matplotlib/axes.py branches/transforms/lib/matplotlib/projections/polar.py Modified: branches/transforms/lib/matplotlib/axes.py =================================================================== --- branches/transforms/lib/matplotlib/axes.py 2007-12-18 15:29:53 UTC (rev 4764) +++ branches/transforms/lib/matplotlib/axes.py 2007-12-18 15:35:06 UTC (rev 4765) @@ -1287,13 +1287,10 @@ return if scalex: - xl = self.get_xbound() XL = self.xaxis.get_major_locator().autoscale() self.set_xbound(XL) if scaley: - ylocator = self.yaxis.get_major_locator() - yl = self.get_ybound() - YL = ylocator.autoscale() + YL = self.yaxis.get_major_locator().autoscale() self.set_ybound(YL) def update_layout(self, renderer): Modified: branches/transforms/lib/matplotlib/projections/polar.py =================================================================== --- branches/transforms/lib/matplotlib/projections/polar.py 2007-12-18 15:29:53 UTC (rev 4764) +++ branches/transforms/lib/matplotlib/projections/polar.py 2007-12-18 15:35:06 UTC (rev 4765) @@ -74,19 +74,21 @@ The affine part of the polar projection. Scales the output so that maximum radius rests on the edge of the axes circle. """ - def __init__(self, limits): + def __init__(self, scale_transform, limits): """ limits is the view limit of the data. The only part of its bounds that is used is ymax (for the radius maximum). """ Affine2DBase.__init__(self) + self._scale_transform = scale_transform self._limits = limits - self.set_children(limits) + self.set_children(scale_transform, limits) self._mtx = None def get_matrix(self): if self._invalid: - ymax = self._limits.ymax + limits_scaled = self._limits.transformed(self._scale_transform) + ymax = limits_scaled.ymax affine = Affine2D() \ .scale(0.5 / ymax) \ .translate(0.5, 0.5) @@ -193,7 +195,7 @@ # An affine transformation on the data, generally to limit the # range of the axes - self.transProjectionAffine = self.PolarAffine(self.viewLim) + self.transProjectionAffine = self.PolarAffine(self.transScale, self.viewLim) # The complete data transformation stack -- from data all the # way to display coordinates @@ -205,7 +207,7 @@ # the edge of the axis circle. self._xaxis_transform = ( self.transProjection + - self.PolarAffine(Bbox.unit()) + + self.PolarAffine(IdentityTransform(), Bbox.unit()) + self.transAxes) # The theta labels are moved from radius == 0.0 to radius == 1.1 self._theta_label1_position = Affine2D().translate(0.0, 1.1) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-12-18 21:09:30
|
Revision: 4772 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4772&view=rev Author: mdboom Date: 2007-12-18 13:09:25 -0800 (Tue, 18 Dec 2007) Log Message: ----------- Better docstrings for set_x/yscale and friends. Modified Paths: -------------- branches/transforms/lib/matplotlib/axes.py branches/transforms/lib/matplotlib/pyplot.py branches/transforms/lib/matplotlib/scale.py Modified: branches/transforms/lib/matplotlib/axes.py =================================================================== --- branches/transforms/lib/matplotlib/axes.py 2007-12-18 21:08:19 UTC (rev 4771) +++ branches/transforms/lib/matplotlib/axes.py 2007-12-18 21:09:25 UTC (rev 4772) @@ -1651,25 +1651,18 @@ ", ".join(mscale.get_scale_names())) return self.xaxis.get_scale() - # MGDTODO: Update docstring def set_xscale(self, value, **kwargs): """ SET_XSCALE(value) - Set the xscaling: %(scale)s + Set the scaling of the x-axis: %(scale)s - If value is 'log', the additional kwargs have the following meaning - - * basex: base of the logarithm - - * subsx: a sequence of the location of the minor ticks; - None defaults to autosubs, which depend on the number of - decades in the plot. Eg for base 10, subsx=(1,2,5) will - put minor ticks on 1,2,5,11,12,15,21, ....To turn off - minor ticking, set subsx=[] - ACCEPTS: [%(scale)s] - """ % {'scale': ' | '.join([repr(x) for x in mscale.get_scale_names()])} + + Different kwargs are accepted, depending on the scale: + %(scale_docs)s + """ % {'scale': ' | '.join([repr(x) for x in mscale.get_scale_names()]), + 'scale_docs': mscale.get_scale_docs().strip()} self.xaxis.set_scale(value, **kwargs) self.autoscale_view() self._update_transScale() @@ -1815,22 +1808,16 @@ def set_yscale(self, value, **kwargs): """ - SET_YSCALE(value, basey=10, subsy=None) + SET_YSCALE(value) - Set the yscaling: %(scale)s + Set the scaling of the y-axis: %(scale)s - If value is 'log', the additional kwargs have the following meaning + ACCEPTS: [%(scale)s] - * basey: base of the logarithm - - * subsy: a sequence of the location of the minor ticks; - None defaults to autosubs, which depend on the number of - decades in the plot. Eg for base 10, subsy=(1,2,5) will - put minor ticks on 1,2,5,11,12,15, 21, ....To turn off - minor ticking, set subsy=[] - - ACCEPTS: %(scale)s - """ % {'scale': ' | '.join([repr(x) for x in mscale.get_scale_names()])} + Different kwargs are accepted, depending on the scale: + %(scale_docs)s + """ % {'scale': ' | '.join([repr(x) for x in mscale.get_scale_names()]), + 'scale_docs': mscale.get_scale_docs().strip()} self.yaxis.set_scale(value, **kwargs) self.autoscale_view() self._update_transScale() Modified: branches/transforms/lib/matplotlib/pyplot.py =================================================================== --- branches/transforms/lib/matplotlib/pyplot.py 2007-12-18 21:08:19 UTC (rev 4771) +++ branches/transforms/lib/matplotlib/pyplot.py 2007-12-18 21:09:25 UTC (rev 4772) @@ -12,7 +12,7 @@ from matplotlib.axes import Axes from matplotlib.projections import PolarAxes from matplotlib import mlab # for csv2rec in plotfile -from matplotlib.scale import get_scale_names +from matplotlib.scale import get_scale_docs, get_scale_names from matplotlib import cm from matplotlib.cm import get_cmap @@ -727,26 +727,34 @@ return ret -# MGDTODO: Update docstring def xscale(*args, **kwargs): """ SET_XSCALE(value) - Set the xscaling: %(scale)s - """ % {'scale': ' | '.join([repr(x) for x in get_scale_names()])} + Set the scaling for the x-axis: %(scale)s + + Different keywords may be accepted, depending on the scale: + + %(scale_docs)s + """ % {'scale': ' | '.join([repr(x) for x in get_scale_names()]), + 'scale_docs': get_scale_docs()} ax = gca() ret = ax.set_xscale(*args, **kwargs) draw_if_interactive() return ret -# MGDTODO: Update docstring def yscale(*args, **kwargs): """ SET_YSCALE(value) - Set the yscaling: %(scale)s - """ % {'scale': ' | '.join([repr(x) for x in get_scale_names()])} + Set the scaling for the y-axis: %(scale)s + + Different keywords may be accepted, depending on the scale: + + %(scale_docs)s + """ % {'scale': ' | '.join([repr(x) for x in get_scale_names()]), + 'scale_docs': get_scale_docs()} ax = gca() ret = ax.set_yscale(*args, **kwargs) draw_if_interactive() Modified: branches/transforms/lib/matplotlib/scale.py =================================================================== --- branches/transforms/lib/matplotlib/scale.py 2007-12-18 21:08:19 UTC (rev 4771) +++ branches/transforms/lib/matplotlib/scale.py 2007-12-18 21:09:25 UTC (rev 4772) @@ -1,3 +1,4 @@ +import textwrap import numpy as npy from matplotlib.numerix import npyma as ma MaskedArray = ma.MaskedArray @@ -2,2 +3,3 @@ +from cbook import dedent from ticker import NullFormatter, ScalarFormatter, LogFormatterMathtext, Formatter @@ -30,6 +32,8 @@ name = 'linear' def __init__(self, axis, **kwargs): + """ + """ pass def set_default_locators_and_formatters(self, axis): @@ -167,6 +171,12 @@ def __init__(self, axis, **kwargs): + """ + basex/basey: The base of the logarithm + + subsx/subsy: The number of subticks to draw between each major + tick + """ if axis.axis_name == 'x': base = kwargs.pop('basex', 10.0) subs = kwargs.pop('subsx', None) @@ -262,6 +272,16 @@ return SymmetricalLogScale.SymmetricalLogTransform(self.base) def __init__(self, axis, **kwargs): + """ + basex/basey: The base of the logarithm + + linthreshx/linthreshy: The range (-x, x) within which the plot + is linear (to avoid having the plot go to infinity around + zero). + + subsx/subsy: The number of subticks to render between each + major tick. + """ if axis.axis_name == 'x': base = kwargs.pop('basex', 10.0) linthresh = kwargs.pop('linthreshx', 2.0) @@ -342,6 +362,9 @@ return MercatorLatitudeScale.MercatorLatitudeTransform(self.thresh) def __init__(self, axis, **kwargs): + """ + thresh: The degree above which to crop the data. + """ thresh = kwargs.pop("thresh", (85 / 180.0) * npy.pi) if thresh >= npy.pi / 2.0: raise ValueError("thresh must be less than pi/2") @@ -393,3 +416,16 @@ names = _scale_mapping.keys() names.sort() return names + +def get_scale_docs(): + docs = [] + for name in get_scale_names(): + scale_class = _scale_mapping[name] + docs.append(" '%s'" % name) + docs.append("") + class_docs = textwrap.wrap( + dedent(scale_class.__init__.__doc__), initial_indent=" " * 8, + subsequent_indent = " " * 8) + docs.extend(class_docs) + docs.append("") + return "\n".join(docs) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-12-20 17:18:18
|
Revision: 4782 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4782&view=rev Author: mdboom Date: 2007-12-20 09:18:12 -0800 (Thu, 20 Dec 2007) Log Message: ----------- Major speed improvement for non-rectilinear projections. Modified Paths: -------------- branches/transforms/lib/matplotlib/axis.py branches/transforms/lib/matplotlib/lines.py branches/transforms/lib/matplotlib/transforms.py Modified: branches/transforms/lib/matplotlib/axis.py =================================================================== --- branches/transforms/lib/matplotlib/axis.py 2007-12-20 17:14:36 UTC (rev 4781) +++ branches/transforms/lib/matplotlib/axis.py 2007-12-20 17:18:12 UTC (rev 4782) @@ -304,6 +304,11 @@ 'Set the location of tick in data coords with scalar loc' x = loc + nonlinear = (hasattr(self.axes, 'yaxis') and + self.axes.yaxis.get_scale() != 'linear' or + hasattr(self.axes, 'xaxis') and + self.axes.xaxis.get_scale() != 'linear') + if self.tick1On: self.tick1line.set_xdata((x,)) if self.tick2On: @@ -314,6 +319,12 @@ self.label1.set_x(x) if self.label2On: self.label2.set_x(x) + + if nonlinear: + self.tick1line._invalid = True + self.tick2line._invalid = True + self.gridline._invalid = True + self._loc = loc def get_view_interval(self): @@ -425,6 +436,12 @@ def update_position(self, loc): 'Set the location of tick in data coords with scalar loc' y = loc + + nonlinear = (hasattr(self.axes, 'yaxis') and + self.axes.yaxis.get_scale() != 'linear' or + hasattr(self.axes, 'xaxis') and + self.axes.xaxis.get_scale() != 'linear') + if self.tick1On: self.tick1line.set_ydata((y,)) if self.tick2On: @@ -435,6 +452,11 @@ self.label1.set_y( y ) if self.label2On: self.label2.set_y( y ) + if nonlinear: + self.tick1line._invalid = True + self.tick2line._invalid = True + self.gridline._invalid = True + self._loc = loc Modified: branches/transforms/lib/matplotlib/lines.py =================================================================== --- branches/transforms/lib/matplotlib/lines.py 2007-12-20 17:14:36 UTC (rev 4781) +++ branches/transforms/lib/matplotlib/lines.py 2007-12-20 17:18:12 UTC (rev 4782) @@ -396,9 +396,6 @@ self._xorig = x self._yorig = y self._invalid = True - else: - if hasattr(self, "_transformed_path"): - self._transformed_path._invalid = self._transformed_path.INVALID_NON_AFFINE def recache(self): #if self.axes is None: print 'recache no axes' Modified: branches/transforms/lib/matplotlib/transforms.py =================================================================== --- branches/transforms/lib/matplotlib/transforms.py 2007-12-20 17:14:36 UTC (rev 4781) +++ branches/transforms/lib/matplotlib/transforms.py 2007-12-20 17:18:12 UTC (rev 4782) @@ -93,22 +93,24 @@ """ # If we are an affine transform being changed, we can set the # flag to INVALID_AFFINE_ONLY - value = ((self.is_affine or self.is_bbox) - and self.INVALID_AFFINE - or self.INVALID) + value = (self.is_affine) and self.INVALID_AFFINE or self.INVALID # Shortcut: If self is already invalid, that means its parents # are as well, so we don't need to do anything. - if self._invalid == value or not len(self._parents): + if self._invalid == value: return + if not len(self._parents): + self._invalid = value + return + # Invalidate all ancestors of self using pseudo-recursion. parent = None stack = [self] while len(stack): root = stack.pop() # Stop at subtrees that have already been invalidated - if root._invalid == 0 or root.pass_through: + if root._invalid != value or root.pass_through: root._invalid = value stack.extend(root._parents.keys()) @@ -198,6 +200,7 @@ read-only access to its data. """ is_bbox = True + is_affine = True #* Redundant: Removed for performance # @@ -208,6 +211,7 @@ def _check(points): if ma.isMaskedArray(points): warnings.warn("Bbox bounds are a masked array.") + points = npy.asarray(points) if (points[1,0] - points[0,0] == 0 or points[1,1] - points[0,1] == 0): warnings.warn("Singular Bbox.") @@ -1011,6 +1015,8 @@ transform may only be replaced with another child transform of the same dimensions. """ + pass_through = True + def __init__(self, child): """ child: A Transform instance. This child may later be replaced @@ -1546,7 +1552,6 @@ This version is an optimization for the case where both child transforms are of type Affine2DBase. """ - is_separable = True def __init__(self, x_transform, y_transform): @@ -1917,8 +1922,8 @@ the transform already applied, along with the affine part of the path necessary to complete the transformation. """ - if (self._invalid & self.INVALID_NON_AFFINE or - self._transformed_path is None): + if ((self._invalid & self.INVALID_NON_AFFINE == self.INVALID_NON_AFFINE) + or self._transformed_path is None): self._transformed_path = \ self._transform.transform_path_non_affine(self._path) self._invalid = 0 @@ -1928,7 +1933,7 @@ """ Return a fully-transformed copy of the child path. """ - if (self._invalid & self.INVALID_NON_AFFINE + if ((self._invalid & self.INVALID_NON_AFFINE == self.INVALID_NON_AFFINE) or self._transformed_path is None): self._transformed_path = \ self._transform.transform_path_non_affine(self._path) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |