From: <md...@us...> - 2008-10-16 19:50:15
|
Revision: 6229 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6229&view=rev Author: mdboom Date: 2008-10-16 19:50:05 +0000 (Thu, 16 Oct 2008) Log Message: ----------- More docs progress. Modified Paths: -------------- trunk/matplotlib/doc/devel/add_new_projection.rst trunk/matplotlib/doc/devel/outline.rst trunk/matplotlib/lib/matplotlib/colors.py trunk/matplotlib/lib/matplotlib/patches.py trunk/matplotlib/lib/matplotlib/path.py trunk/matplotlib/lib/matplotlib/projections/__init__.py trunk/matplotlib/lib/matplotlib/projections/polar.py trunk/matplotlib/lib/matplotlib/scale.py trunk/matplotlib/lib/matplotlib/transforms.py Modified: trunk/matplotlib/doc/devel/add_new_projection.rst =================================================================== --- trunk/matplotlib/doc/devel/add_new_projection.rst 2008-10-16 19:35:12 UTC (rev 6228) +++ trunk/matplotlib/doc/devel/add_new_projection.rst 2008-10-16 19:50:05 UTC (rev 6229) @@ -108,3 +108,27 @@ :file:`examples/api/custom_projection_example.py`. The polar plot functionality in :mod:`matplotlib.projections.polar` may also be of interest. + +API documentation +================= + +matplotlib.scale +---------------- + +.. automodule:: matplotlib.scale + :members: + :show-inheritance: + +matplotlib.projections +---------------------- + +.. automodule:: matplotlib.projections + :members: + :show-inheritance: + +matplotlib.projections.polar +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. automodule:: matplotlib.projections.polar + :members: + :show-inheritance: Modified: trunk/matplotlib/doc/devel/outline.rst =================================================================== --- trunk/matplotlib/doc/devel/outline.rst 2008-10-16 19:35:12 UTC (rev 6228) +++ trunk/matplotlib/doc/devel/outline.rst 2008-10-16 19:50:05 UTC (rev 6229) @@ -108,9 +108,9 @@ config/tconfig Darren needs conversion config/verbose Darren needs conversion numerix/__init__ needs conversion -projections/__init__ needs conversion -projections/geo needs conversion -projections/polar needs conversion +projections/__init__ Mike converted +projections/geo Mike converted (not included--experimental) +projections/polar Mike converted afm converted artist converted axes converted @@ -134,18 +134,18 @@ mathtext needs conversion mlab needs conversion mpl needs conversion -patches needs conversion -path needs conversion -pylab needs conversion +patches Mike converted +path Mike converted +pylab no docstrings pyplot converted quiver needs conversion rcsetup needs conversion -scale needs conversion +scale Mike converted table needs conversion texmanager Darren needs conversion text Mike converted ticker Mike needs conversion -transforms needs conversion +transforms Mike converted type1font needs conversion units needs conversion widgets needs conversion Modified: trunk/matplotlib/lib/matplotlib/colors.py =================================================================== --- trunk/matplotlib/lib/matplotlib/colors.py 2008-10-16 19:35:12 UTC (rev 6228) +++ trunk/matplotlib/lib/matplotlib/colors.py 2008-10-16 19:50:05 UTC (rev 6229) @@ -8,14 +8,14 @@ Commands which take color arguments can use several formats to specify the colors. For the basic builtin colors, you can use a single letter - b : blue - g : green - r : red - c : cyan - m : magenta - y : yellow - k : black - w : white + - b : blue + - g : green + - r : red + - c : cyan + - m : magenta + - y : yellow + - k : black + - w : white Gray shades can be given as a string encoding a float in the 0-1 range, e.g.:: Modified: trunk/matplotlib/lib/matplotlib/patches.py =================================================================== --- trunk/matplotlib/lib/matplotlib/patches.py 2008-10-16 19:35:12 UTC (rev 6228) +++ trunk/matplotlib/lib/matplotlib/patches.py 2008-10-16 19:50:05 UTC (rev 6229) @@ -82,6 +82,9 @@ return inside, {} def update_from(self, other): + """ + Updates this :class:`Patch` from the properties of *other*. + """ artist.Artist.update_from(self, other) self.set_edgecolor(other.get_edgecolor()) self.set_facecolor(other.get_facecolor()) @@ -94,9 +97,17 @@ self.set_alpha(other.get_alpha()) def get_extents(self): + """ + Return a :class:`~matplotlib.transforms.Bbox` object defining + the axis-aligned extents of the :class:`Patch`. + """ return self.get_path().get_extents(self.get_transform()) def get_transform(self): + """ + Return the :class:`~matplotlib.transforms.Transform` applied + to the :class:`Patch`. + """ return self.get_patch_transform() + artist.Artist.get_transform(self) def get_data_transform(self): @@ -106,22 +117,38 @@ return transforms.IdentityTransform() def get_antialiased(self): + """ + Returns True if the :class:`Patch` is to be drawn with antialiasing. + """ return self._antialiased get_aa = get_antialiased def get_edgecolor(self): + """ + Return the edge color of the :class:`Patch`. + """ return self._edgecolor get_ec = get_edgecolor def get_facecolor(self): + """ + Return the face color of the :class:`Patch`. + """ return self._facecolor get_fc = get_facecolor def get_linewidth(self): + """ + Return the line width in points. + """ return self._linewidth get_lw = get_linewidth def get_linestyle(self): + """ + Return the linestyle. Will be one of ['solid' | 'dashed' | + 'dashdot' | 'dotted'] + """ return self._linestyle get_ls = get_linestyle @@ -133,8 +160,11 @@ """ if aa is None: aa = mpl.rcParams['patch.antialiased'] self._antialiased = aa - set_aa = set_antialiased + def set_aa(self, aa): + """alias for set_antialiased""" + return self.set_antialiased(aa) + def set_edgecolor(self, color): """ Set the patch edge color @@ -222,15 +252,18 @@ 2. Hatching is done with solid black lines of width 0. + + ACCEPTS: [ '/' | '\\' | '|' | '-' | '#' | 'x' ] """ self._hatch = h def get_hatch(self): - 'return the current hatching pattern' + 'Return the current hatching pattern' return self._hatch def draw(self, renderer): + 'Draw the :class:`Patch` to the given *renderer*.' if not self.get_visible(): return #renderer.open_group('patch') gc = renderer.new_gc() @@ -378,8 +411,8 @@ class Rectangle(Patch): """ - Draw a rectangle with lower left at *xy*=(*x*, *y*) with specified - width and height + Draw a rectangle with lower left at *xy* = (*x*, *y*) with + specified *width* and *height*. """ def __str__(self): @@ -1296,13 +1329,11 @@ class BboxTransmuterBase(object): """ - Bbox Transmuter Base class - - BBoxTransmuterBase and its derivatives are used to make a fancy box - around a given rectangle. The __call__ method returns the Path of - the fancy box. This class is not an artist and actual drawing of the - fancy box is done by the :class:`FancyBboxPatch` class. - + :class:`BBoxTransmuterBase` and its derivatives are used to make a + fancy box around a given rectangle. The :meth:`__call__` method + returns the :class:`~matplotlib.path.Path` of the fancy box. This + class is not an artist and actual drawing of the fancy box is done + by the :class:`FancyBboxPatch` class. """ # The derived classes are required to be able to be initialized @@ -1317,11 +1348,12 @@ def transmute(self, x0, y0, width, height, mutation_size): """ - The transmute method is a very core of the BboxTransmuter class - and must be overriden in the subclasses. It receives the - location and size of the rectangle, and the mutation_size, with - which the amound padding and etc. will be scaled. It returns a - Path instance. + The transmute method is a very core of the + :class:`BboxTransmuter` class and must be overriden in the + subclasses. It receives the location and size of the + rectangle, and the mutation_size, with which the amount of + padding and etc. will be scaled. It returns a + :class:`~matplotlib.path.Path` instance. """ raise NotImplementedError('Derived must override') @@ -1501,7 +1533,8 @@ mutation_aspect=None, **kwargs): """ - *xy*=lower left corner + *xy* = lower left corner + *width*, *height* *boxstyle* describes how the fancy box will be drawn. It @@ -1636,7 +1669,7 @@ """ Set the transmuter object - ACCEPTS: BboxTransmuterBase (or its derivatives) instance + ACCEPTS: :class:`BboxTransmuterBase` (or its derivatives) instance """ self._bbox_transmuter = bbox_transmuter Modified: trunk/matplotlib/lib/matplotlib/path.py =================================================================== --- trunk/matplotlib/lib/matplotlib/path.py 2008-10-16 19:35:12 UTC (rev 6228) +++ trunk/matplotlib/lib/matplotlib/path.py 2008-10-16 19:50:05 UTC (rev 6229) @@ -15,8 +15,8 @@ class Path(object): """ - Path represents a series of possibly disconnected, possibly - closed, line and curve segments. + :class:`Path` represents a series of possibly disconnected, + possibly closed, line and curve segments. The underlying storage is made up of two parallel numpy arrays: - *vertices*: an Nx2 float array of vertices @@ -159,8 +159,7 @@ be simplified *only* if :attr:`should_simplify` is True, which is determined in the constructor by this criteria: - - No *codes* array - - No nonfinite values + - No curves - More than 128 vertices """ vertices = self.vertices @@ -219,8 +218,9 @@ .. seealso:: :class:`matplotlib.transforms.TransformedPath`: - A path class that will cache the transformed result - and automatically update when the transform changes. + A specialized path class that will cache the + transformed result and automatically update when the + transform changes. """ return Path(transform.transform(self.vertices), self.codes) @@ -265,8 +265,8 @@ Returns *True* if this path intersects another given path. *filled*, when True, treats the paths as if they were filled. - That is, if one path completely encloses the other, - :meth:`intersects_path` will return True. + That is, if one path completely encloses the other, + :meth:`intersects_path` will return True. """ return path_intersects_path(self, other, filled) Modified: trunk/matplotlib/lib/matplotlib/projections/__init__.py =================================================================== --- trunk/matplotlib/lib/matplotlib/projections/__init__.py 2008-10-16 19:35:12 UTC (rev 6228) +++ trunk/matplotlib/lib/matplotlib/projections/__init__.py 2008-10-16 19:50:05 UTC (rev 6229) @@ -3,18 +3,31 @@ from matplotlib import axes class ProjectionRegistry(object): + """ + Manages the set of projections available to the system. + """ def __init__(self): self._all_projection_types = {} def register(self, *projections): + """ + Register a new set of projection(s). + """ for projection in projections: name = projection.name self._all_projection_types[name] = projection def get_projection_class(self, name): + """ + Get a projection class from its *name*. + """ return self._all_projection_types[name] def get_projection_names(self): + """ + Get a list of the names of all projections currently + registered. + """ names = self._all_projection_types.keys() names.sort() return names @@ -31,7 +44,13 @@ def register_projection(cls): projection_registry.register(cls) -def get_projection_class(projection): +def get_projection_class(projection=None): + """ + Get a projection class from its name. + + If *projection* is None, a standard rectilinear projection is + returned. + """ if projection is None: projection = 'rectilinear' @@ -41,7 +60,24 @@ raise ValueError("Unknown projection '%s'" % projection) def projection_factory(projection, figure, rect, **kwargs): + """ + Get a new projection instance. + + *projection* is a projection name. + + *figure* is a figure to add the axes to. + + *rect* is a :class:`~matplotlib.transforms.Bbox` object specifying + the location of the axes within the figure. + + Any other kwargs are passed along to the specific projection + constructor being used. + """ + return get_projection_class(projection)(figure, rect, **kwargs) def get_projection_names(): + """ + Get a list of acceptable projection names. + """ return projection_registry.get_projection_names() Modified: trunk/matplotlib/lib/matplotlib/projections/polar.py =================================================================== --- trunk/matplotlib/lib/matplotlib/projections/polar.py 2008-10-16 19:35:12 UTC (rev 6228) +++ trunk/matplotlib/lib/matplotlib/projections/polar.py 2008-10-16 19:50:05 UTC (rev 6229) @@ -15,7 +15,7 @@ class PolarAxes(Axes): """ - A polar graph projection, where the input dimensions are theta, r. + A polar graph projection, where the input dimensions are *theta*, *r*. Theta starts pointing east and goes anti-clockwise. """ @@ -23,9 +23,10 @@ class PolarTransform(Transform): """ - The base polar transform. This handles projection theta and r into - Cartesian coordinate space, but does not perform the ultimate affine - transformation into the correct position. + The base polar transform. This handles projection *theta* and + *r* into Cartesian coordinate space *x* and *y*, but does not + perform the ultimate affine transformation into the correct + position. """ input_dims = 2 output_dims = 2 @@ -77,9 +78,10 @@ that maximum radius rests on the edge of the axes circle. """ def __init__(self, scale_transform, limits): - """ - limits is the view limit of the data. The only part of + u""" + *limits* is the view limit of the data. The only part of its bounds that is used is ymax (for the radius maximum). + The theta range is always fixed to (0, 2\u03c0). """ Affine2DBase.__init__(self) self._scale_transform = scale_transform @@ -103,7 +105,7 @@ class InvertedPolarTransform(Transform): """ The inverse of the polar transform, mapping Cartesian - coordinate space back to t and r. + coordinate space *x* and *y* back to *theta* and *r*. """ input_dims = 2 output_dims = 2 @@ -127,10 +129,11 @@ inverted.__doc__ = Transform.inverted.__doc__ class ThetaFormatter(Formatter): + u""" + Used to format the *theta* tick labels. Converts the + native unit of radians into degrees and adds a degree symbol + (\u00b0). """ - Used to format the theta tick labels. Converts the native - unit of radians into degrees and adds a degree symbol. - """ def __call__(self, x, pos=None): # \u00b0 : degree symbol return u"%d\u00b0" % ((x / npy.pi) * 180.0) @@ -140,8 +143,9 @@ Used to locate radius ticks. Ensures that all ticks are strictly positive. For all other - tasks, it delegates to the base Locator (which may be - different depending on the scale of the r-axis. + tasks, it delegates to the base + :class:`~matplotlib.ticker.Locator` (which may be different + depending on the scale of the *r*-axis. """ def __init__(self, base): self.base = base @@ -290,24 +294,26 @@ **kwargs): """ Set the angles at which to place the theta grids (these - gridlines are equal along the theta dimension). angles is in - degrees + gridlines are equal along the theta dimension). *angles* is in + degrees. - labels, if not None, is a len(angles) list of strings of the - labels to use at each angle. + *labels*, if not None, is a ``len(angles)`` list of strings of + the labels to use at each angle. - if labels is None, the labels with be fmt%%angle + If *labels* is None, the labels will be ``fmt %% angle`` - frac is the fraction of the polar axes radius at which to - place the label (1 is the edge).Eg 1.05 isd outside the axes - and 0.95 is inside the axes + *frac* is the fraction of the polar axes radius at which to + place the label (1 is the edge). Eg. 1.05 is outside the axes + and 0.95 is inside the axes. - Return value is a list of lines, labels where the lines are - lines.Line2D instances and the labels are Text - instances: + Return value is a list of tuples (*line*, *label*), where + *line* is :class:`~matplotlib.lines.Line2D` instances and the + *label* is :class:`~matplotlib.text.Text` instances. - kwargs are optional text properties for the labels + kwargs are optional text properties for the labels: + %(Text)s + ACCEPTS: sequence of floats """ angles = npy.asarray(angles, npy.float_) @@ -324,23 +330,25 @@ def set_rgrids(self, radii, labels=None, angle=None, rpad=None, **kwargs): """ - set the radial locations and labels of the r grids + Set the radial locations and labels of the *r* grids. - The labels will appear at radial distances radii at angle + The labels will appear at radial distances *radii* at the + given *angle* in degrees. - labels, if not None, is a len(radii) list of strings of the - labels to use at each angle. + *labels*, if not None, is a ``len(radii)`` list of strings of the + labels to use at each radius. - if labels is None, the self.rformatter will be used + If *labels* is None, the built-in formatter will be used. - rpad is a fraction of the max of radii which will pad each of + *rpad* is a fraction of the max of *radii* which will pad each of the radial labels in the radial direction. - Return value is a list of lines, labels where the lines are - lines.Line2D instances and the labels are text.Text - instances + Return value is a list of tuples (*line*, *label*), where + *line* is :class:`~matplotlib.lines.Line2D` instances and the + *label* is :class:`~matplotlib.text.Text` instances. - kwargs control the rgrid Text label properties: + kwargs are optional text properties for the labels: + %(Text)s ACCEPTS: sequence of floats @@ -375,7 +383,10 @@ self.viewLim.intervalx = (0.0, npy.pi * 2.0) def format_coord(self, theta, r): - 'return a format string formatting the coordinate' + """ + Return a format string formatting the coordinate using Unicode + characters. + """ theta /= math.pi # \u03b8: lower-case theta # \u03c0: lower-case pi Modified: trunk/matplotlib/lib/matplotlib/scale.py =================================================================== --- trunk/matplotlib/lib/matplotlib/scale.py 2008-10-16 19:35:12 UTC (rev 6228) +++ trunk/matplotlib/lib/matplotlib/scale.py 2008-10-16 19:50:05 UTC (rev 6229) @@ -9,50 +9,99 @@ from transforms import Transform, IdentityTransform class ScaleBase(object): + """ + The base class for all scales. + + Scales are separable transformations, working on a single dimension. + + Any subclasses will want to override: + + - :attr:`name` + - :meth:`get_transform` + + And optionally: + - :meth:`set_default_locators_and_formatters` + - :meth:`limit_range_for_scale` + """ def get_transform(self): """ - Return the transform object associated with this scale. + Return the :class:`~matplotlib.transforms.Transform` object + associated with this scale. """ raise NotImplementedError def set_default_locators_and_formatters(self, axis): """ - Set the locators and formatters that go with this scale. + Set the :class:`~matplotlib.ticker.Locator` and + :class:`~matplotlib.ticker.Formatter` objects on the given + axis to match this scale. """ raise NotImplementedError def limit_range_for_scale(self, vmin, vmax, minpos): """ - Returns the range vmin, vmax, limited to the domain supported - by this scale. + Returns the range *vmin*, *vmax*, possibly limited to the + domain supported by this scale. + + *minpos* should be the minimum positive value in the data. + This is used by log scales to determine a minimum value. """ return vmin, vmax class LinearScale(ScaleBase): + """ + The default linear scale. + """ + name = 'linear' def __init__(self, axis, **kwargs): - """ - """ pass def set_default_locators_and_formatters(self, axis): + """ + Set the locators and formatters to reasonable defaults for + linear scaling. + """ axis.set_major_locator(AutoLocator()) axis.set_major_formatter(ScalarFormatter()) axis.set_minor_locator(NullLocator()) axis.set_minor_formatter(NullFormatter()) def get_transform(self): + """ + The transform for linear scaling is just the + :class:`~matplotlib.transforms.IdentityTransform`. + """ return IdentityTransform() def _mask_non_positives(a): + """ + Return a Numpy masked array where all non-positive values are + masked. If there are no non-positive values, the original array + is returned. + """ mask = a <= 0.0 if mask.any(): return ma.MaskedArray(a, mask=mask) return a class LogScale(ScaleBase): + """ + A standard logarithmic scale. Care is taken so non-positive + values are not plotted. + + For computational efficiency (to push as much as possible to Numpy + C code in the common cases), this scale provides different + transforms depending on the base of the logarithm: + + - base 10 (:class:`Log10Transform`) + - base 2 (:class:`Log2Transform`) + - base e (:class:`NaturalLogTransform`) + - arbitrary base (:class:`LogTransform`) + """ + name = 'log' class Log10Transform(Transform): @@ -203,15 +252,26 @@ self.subs = subs def set_default_locators_and_formatters(self, axis): + """ + Set the locators and formatters to specialized versions for + log scaling. + """ axis.set_major_locator(LogLocator(self.base)) axis.set_major_formatter(LogFormatterMathtext(self.base)) axis.set_minor_locator(LogLocator(self.base, self.subs)) axis.set_minor_formatter(NullFormatter()) def get_transform(self): + """ + Return a :class:`~matplotlib.transforms.Transform` instance + appropriate for the given logarithm base. + """ return self._transform def limit_range_for_scale(self, vmin, vmax, minpos): + """ + Limit the domain to positive values. + """ return (vmin <= 0.0 and minpos or vmin, vmax <= 0.0 and minpos or vmax) @@ -221,10 +281,10 @@ The symmetrical logarithmic scale is logarithmic in both the positive and negative directions from the origin. - Since the values close to zero tend toward infinity, there is - usually need to have a range around zero that is linear. The - parameter "linthresh" allows the user to specify the size of this - range (-linthresh, linthresh). + Since the values close to zero tend toward infinity, there is a + need to have a range around zero that is linear. The parameter + *linthresh* allows the user to specify the size of this range + (-*linthresh*, *linthresh*). """ name = 'symlog' @@ -310,12 +370,19 @@ self.subs = subs def set_default_locators_and_formatters(self, axis): + """ + Set the locators and formatters to specialized versions for + symmetrical log scaling. + """ axis.set_major_locator(SymmetricalLogLocator(self.get_transform())) axis.set_major_formatter(LogFormatterMathtext(self.base)) axis.set_minor_locator(SymmetricalLogLocator(self.get_transform(), self.subs)) axis.set_minor_formatter(NullFormatter()) def get_transform(self): + """ + Return a :class:`SymmetricalLogTransform` instance. + """ return self._transform @@ -325,7 +392,17 @@ 'log' : LogScale, 'symlog' : SymmetricalLogScale } +def get_scale_names(): + names = _scale_mapping.keys() + names.sort() + return names + def scale_factory(scale, axis, **kwargs): + """ + Return a scale class by name. + + ACCEPTS: [ %s ] + """ scale = scale.lower() if scale is None: scale = 'linear' @@ -334,19 +411,20 @@ raise ValueError("Unknown scale type '%s'" % scale) return _scale_mapping[scale](axis, **kwargs) +scale_factory.__doc__ = scale_factory.__doc__ % " | ".join(get_scale_names()) def register_scale(scale_class): """ Register a new kind of scale. + + *scale_class* must be a subclass of :class:`ScaleBase`. """ _scale_mapping[scale_class.name] = scale_class -def get_scale_names(): - names = _scale_mapping.keys() - names.sort() - return names - def get_scale_docs(): + """ + Helper function for generating docstrings related to scales. + """ docs = [] for name in get_scale_names(): scale_class = _scale_mapping[name] Modified: trunk/matplotlib/lib/matplotlib/transforms.py =================================================================== --- trunk/matplotlib/lib/matplotlib/transforms.py 2008-10-16 19:35:12 UTC (rev 6228) +++ trunk/matplotlib/lib/matplotlib/transforms.py 2008-10-16 19:50:05 UTC (rev 6229) @@ -79,7 +79,7 @@ def __init__(self): """ - Creates a new TransformNode. + Creates a new :class:`TransformNode`. """ # Parents are stored in a WeakKeyDictionary, so that if the # parents are deleted, references from the children won't keep @@ -98,8 +98,8 @@ def invalidate(self): """ - Invalidate this transform node and all of its ancestors. - Should be called any time the transform changes. + Invalidate this :class:`TransformNode` and all of its + ancestors. Should be called any time the transform changes. """ # If we are an affine transform being changed, we can set the # flag to INVALID_AFFINE_ONLY @@ -145,8 +145,8 @@ """ Returns a frozen copy of this transform node. The frozen copy will not update when its children change. Useful for storing - a previously known state of a transform where copy.deepcopy() - might normally be used. + a previously known state of a transform where + ``copy.deepcopy()`` might normally be used. """ return self @@ -162,7 +162,7 @@ Affine transforms are marked in blue. Bounding boxes are marked in yellow. - fobj: A Python file-like object + *fobj*: A Python file-like object """ seen = set() @@ -242,8 +242,8 @@ def is_unit(self): """ - Returns True if the Bbox is the unit bounding box from (0, 0) - to (1, 1). + Returns True if the :class:`Bbox` is the unit bounding box + from (0, 0) to (1, 1). """ return list(self.get_points().flatten()) == [0., 0., 1., 1.] @@ -370,7 +370,7 @@ def containsx(self, x): """ - Returns True if x is between or equal to :attr:`x0` and + Returns True if *x* is between or equal to :attr:`x0` and :attr:`x1`. """ x0, x1 = self.intervalx @@ -380,7 +380,7 @@ def containsy(self, y): """ - Returns True if y is between or equal to :attr:`y0` and + Returns True if *y* is between or equal to :attr:`y0` and :attr:`y1`. """ y0, y1 = self.intervaly @@ -390,8 +390,8 @@ def contains(self, x, y): """ - Returns True if (x, y) is a coordinate inside the bounding - box or on its edge. + Returns *True* if (*x*, *y*) is a coordinate inside the + bounding box or on its edge. """ return self.containsx(x) and self.containsy(y) @@ -419,7 +419,7 @@ def fully_containsx(self, x): """ - Returns True if x is between but not equal to :attr:`x0` and + Returns True if *x* is between but not equal to :attr:`x0` and :attr:`x1`. """ x0, x1 = self.intervalx @@ -429,7 +429,7 @@ def fully_containsy(self, y): """ - Returns True if y is between but not equal to :attr:`y0` and + Returns True if *y* is between but not equal to :attr:`y0` and :attr:`y1`. """ y0, y1 = self.intervaly @@ -439,7 +439,7 @@ def fully_contains(self, x, y): """ - Returns True if (x, y) is a coordinate inside the bounding + Returns True if (*x*, *y*) is a coordinate inside the bounding box, but not on its edge. """ return self.fully_containsx(x) \ @@ -448,7 +448,8 @@ def fully_overlaps(self, other): """ Returns True if this bounding box overlaps with the given - bounding box *other*, but not on its edge alone.""" + bounding box *other*, but not on its edge alone. + """ ax1, ay1, ax2, ay2 = self._get_extents() bx1, by1, bx2, by2 = other._get_extents() @@ -491,23 +492,24 @@ 'W': (0, 0.5)} def anchored(self, c, container = None): """ - Return a copy of the Bbox, shifted to position c within a - container. + Return a copy of the :class:`Bbox`, shifted to position *c* + within a container. - c: may be either: + *c*: may be either: - * a sequence (cx, cy) where cx, cy range - from 0 to 1, where 0 is left or bottom and 1 is right or top + * a sequence (*cx*, *cy*) where *cx* and *cy* range from 0 + to 1, where 0 is left or bottom and 1 is right or top * a string: - - C for centered - - S for bottom-center - - SE for bottom-left - - E for left + - 'C' for centered + - 'S' for bottom-center + - 'SE' for bottom-left + - 'E' for left - etc. - Optional argument *container* is the box within which the :class:`Bbox` - is positioned; it defaults to the initial :class:`Bbox`. + Optional argument *container* is the box within which the + :class:`Bbox` is positioned; it defaults to the initial + :class:`Bbox`. """ if container is None: container = self @@ -523,10 +525,10 @@ def shrunk(self, mx, my): """ - Return a copy of the :class:`Bbox`, shurnk by the factor mx in - the *x* direction and the factor my in the *y* direction. The - lower left corner of the box remains unchanged. Normally mx - and my will be less than 1, but this is not enforced. + Return a copy of the :class:`Bbox`, shrunk by the factor *mx* + in the *x* direction and the factor *my* in the *y* direction. + The lower left corner of the box remains unchanged. Normally + *mx* and *my* will be less than 1, but this is not enforced. """ w, h = self.size return Bbox([self._points[0], @@ -589,9 +591,9 @@ def count_contains(self, vertices): """ - Count the number of vertices contained in the Bbox. + Count the number of vertices contained in the :class:`Bbox`. - vertices is a Nx2 numpy array. + *vertices* is a Nx2 Numpy array. """ if len(vertices) == 0: return 0 @@ -636,7 +638,7 @@ def translated(self, tx, ty): """ Return a copy of the :class:`Bbox`, statically translated by - tx and ty. + *tx* and *ty*. """ return Bbox(self._points + (tx, ty)) @@ -697,11 +699,11 @@ def __init__(self, points): """ - points: a 2x2 numpy array of the form [[x0, y0], [x1, y1]] + *points*: a 2x2 numpy array of the form [[x0, y0], [x1, y1]] If you need to create a :class:`Bbox` object from another form - of data, consider the static methods unit, from_bounds and - from_extents. + of data, consider the static methods :meth:`unit`, + :meth:`from_bounds` and :meth:`from_extents`. """ BboxBase.__init__(self) self._points = np.asarray(points, np.float_) @@ -731,10 +733,10 @@ #@staticmethod def from_bounds(x0, y0, width, height): """ - (staticmethod) Create a new :class:`Bbox` from x0, y0, width - and height. + (staticmethod) Create a new :class:`Bbox` from *x0*, *y0*, + *width* and *height*. - width and height may be negative. + *width* and *height* may be negative. """ return Bbox.from_extents(x0, y0, x0 + width, y0 + height) from_bounds = staticmethod(from_bounds) @@ -742,10 +744,10 @@ #@staticmethod def from_extents(*args): """ - (staticmethod) Create a new Bbox from left, bottom, right and - top. + (staticmethod) Create a new Bbox from *left*, *bottom*, + *right* and *top*. - The y-axis increases upwards. + The *y*-axis increases upwards. """ points = np.array(args, dtype=np.float_).reshape(2, 2) return Bbox(points) @@ -761,7 +763,7 @@ by subsequent calls to :meth:`update_from_data` or :meth:`update_from_data_xy`. - value: + *value*: - When True, subsequent calls to :meth:`update_from_data` will ignore the existing bounds of the :class:`Bbox`. @@ -776,13 +778,13 @@ Update the bounds of the :class:`Bbox` based on the passed in data. - x: a numpy array of x-values + *x*: a numpy array of *x*-values - y: a numpy array of y-values + *y*: a numpy array of *y*-values - ignore: - - when True, ignore the existing bounds of the Bbox. - - when False, include the existing bounds of the Bbox. + *ignore*: + - when True, ignore the existing bounds of the :class:`Bbox`. + - when False, include the existing bounds of the :class:`Bbox`. - when None, use the last value passed to :meth:`ignore`. """ warnings.warn("update_from_data requires a memory copy -- please replace with update_from_data_xy") @@ -794,11 +796,11 @@ Update the bounds of the :class:`Bbox` based on the passed in data. - *path*: a Path instance + *path*: a :class:`~matplotlib.path.Path` instance *ignore*: - - when True, ignore the existing bounds of the Bbox. - - when False, include the existing bounds of the Bbox. + - when True, ignore the existing bounds of the :class:`Bbox`. + - when False, include the existing bounds of the :class:`Bbox`. - when None, use the last value passed to :meth:`ignore`. """ if ignore is None: @@ -821,11 +823,11 @@ Update the bounds of the :class:`Bbox` based on the passed in data. - xy: a numpy array of 2D points + *xy*: a numpy array of 2D points - ignore: - - when True, ignore the existing bounds of the Bbox. - - when False, include the existing bounds of the Bbox. + *ignore*: + - when True, ignore the existing bounds of the :class:`Bbox`. + - when False, include the existing bounds of the :class:`Bbox`. - when None, use the last value passed to :meth:`ignore`. """ if len(xy) == 0: @@ -905,8 +907,8 @@ def set_points(self, points): """ Set the points of the bounding box directly from a numpy array - of the form: [[x0, y0], [x1, y1]]. No error checking - is performed, as this method is mainly for internal use. + of the form: [[x0, y0], [x1, y1]]. No error checking is + performed, as this method is mainly for internal use. """ if np.any(self._points != points): self._points = points @@ -914,7 +916,8 @@ def set(self, other): """ - Set this bounding box from the "frozen" bounds of another Bbox. + Set this bounding box from the "frozen" bounds of another + :class:`Bbox`. """ if np.any(self._points != other.get_points()): self._points = other.get_points() @@ -929,9 +932,9 @@ """ def __init__(self, bbox, transform): """ - bbox: a child bbox + *bbox*: a child :class:`Bbox` - transform: a 2D transform + *transform*: a 2D :class:`Transform` """ assert bbox.is_bbox assert isinstance(transform, Transform) @@ -968,8 +971,8 @@ class Transform(TransformNode): """ - The base class of all TransformNodes that actually perform a - transformation. + The base class of all :class:`TransformNode`s that actually + perform a transformation. All non-affine transformations should be subclasses of this class. New affine transformations should be subclasses of @@ -1009,7 +1012,8 @@ def __add__(self, other): """ - Composes two transforms together such that self is followed by other. + Composes two transforms together such that *self* is followed + by *other*. """ if isinstance(other, Transform): return composite_transform_factory(self, other) @@ -1018,7 +1022,8 @@ def __radd__(self, other): """ - Composes two transforms together such that self is followed by other. + Composes two transforms together such that *self* is followed + by *other*. """ if isinstance(other, Transform): return composite_transform_factory(other, self) @@ -1095,7 +1100,7 @@ """ Returns a transformed copy of path. - path: a Path instance. + *path*: a :class:`~matplotlib.path.Path` instance. In some cases, this transform may insert curves into the path that began as line segments. @@ -1107,7 +1112,7 @@ Returns a copy of path, transformed only by the affine part of this transform. - path: a Path instance + *path*: a :class:`~matplotlib.path.Path` instance. ``transform_path(path)`` is equivalent to ``transform_path_affine(transform_path_non_affine(values))``. @@ -1119,7 +1124,7 @@ Returns a copy of path, transformed only by the non-affine part of this transform. - path: a Path instance + *path*: a :class:`~matplotlib.path.Path` instance. ``transform_path(path)`` is equivalent to ``transform_path_affine(transform_path_non_affine(values))``. @@ -1131,7 +1136,7 @@ Return the corresponding inverse transformation. The return value of this method should be treated as - temporary. An update to 'self' does not cause a corresponding + temporary. An update to *self* does not cause a corresponding update to its inverted copy. ``x === self.inverted().transform(self.transform(x))`` @@ -1157,8 +1162,8 @@ def __init__(self, child): """ - child: A Transform instance. This child may later be replaced - with :meth:`set`. + *child*: A class:`Transform` instance. This child may later + be replaced with :meth:`set`. """ assert isinstance(child, Transform) @@ -1278,7 +1283,7 @@ affine transformation, use :class:`Affine2D`. Subclasses of this class will generally only need to override a - constructor and 'get_matrix' that generates a custom 3x3 matrix. + constructor and :meth:`get_matrix` that generates a custom 3x3 matrix. """ input_dims = 2 @@ -1373,7 +1378,7 @@ b d f 0 0 1 - If matrix is None, initialize with the identity transform. + If *matrix* is None, initialize with the identity transform. """ Affine2DBase.__init__(self) if matrix is None: @@ -1464,8 +1469,8 @@ """ Add a rotation (in radians) to this transform in place. - Returns self, so this method can easily be chained with more - calls to :meth:`rotate`, :meth:`rotate_deg, :meth:`translate` + Returns *self*, so this method can easily be chained with more + calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` and :meth:`scale`. """ a = np.cos(theta) @@ -1481,8 +1486,8 @@ """ Add a rotation (in degrees) to this transform in place. - Returns self, so this method can easily be chained with more - calls to :meth:`rotate`, :meth:`rotate_deg, :meth:`translate` + Returns *self*, so this method can easily be chained with more + calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` and :meth:`scale`. """ return self.rotate(degrees*np.pi/180.) @@ -1491,8 +1496,8 @@ """ Add a rotation (in radians) around the point (x, y) in place. - Returns self, so this method can easily be chained with more - calls to :meth:`rotate`, :meth:`rotate_deg, :meth:`translate` + Returns *self*, so this method can easily be chained with more + calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` and :meth:`scale`. """ return self.translate(-x, -y).rotate(theta).translate(x, y) @@ -1501,8 +1506,8 @@ """ Add a rotation (in degrees) around the point (x, y) in place. - Returns self, so this method can easily be chained with more - calls to :meth:`rotate`, :meth:`rotate_deg, :meth:`translate` + Returns *self*, so this method can easily be chained with more + calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` and :meth:`scale`. """ return self.translate(-x, -y).rotate_deg(degrees).translate(x, y) @@ -1511,8 +1516,8 @@ """ Adds a translation in place. - Returns self, so this method can easily be chained with more - calls to :meth:`rotate`, :meth:`rotate_deg, :meth:`translate` + Returns *self*, so this method can easily be chained with more + calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` and :meth:`scale`. """ translate_mtx = np.array( @@ -1526,11 +1531,11 @@ """ Adds a scale in place. - If sy is None, the same scale is applied in both the x- and - y-directions. + If *sy* is None, the same scale is applied in both the *x*- and + *y*-directions. - Returns self, so this method can easily be chained with more - calls to :meth:`rotate`, :meth:`rotate_deg, :meth:`translate` + Returns *self*, so this method can easily be chained with more + calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` and :meth:`scale`. """ if sy is None: @@ -1597,11 +1602,11 @@ class BlendedGenericTransform(Transform): """ - A "blended" transform uses one transform for the x-direction, and - another transform for the y-direction. + A "blended" transform uses one transform for the *x*-direction, and + another transform for the *y*-direction. This "generic" version can handle any given child transform in the - x- and y-directions. + *x*- and *y*-directions. """ input_dims = 2 output_dims = 2 @@ -1610,8 +1615,9 @@ def __init__(self, x_transform, y_transform): """ - Create a new "blended" transform using x_transform to - transform the x-axis and y_transform to transform the y_axis. + Create a new "blended" transform using *x_transform* to + transform the *x*-axis and *y_transform* to transform the + *y*-axis. You will generally not call this constructor directly but use the :func:`blended_transform_factory` function instead, which @@ -1699,20 +1705,22 @@ class BlendedAffine2D(Affine2DBase): """ - A "blended" transform uses one transform for the x-direction, and - another transform for the y-direction. + A "blended" transform uses one transform for the *x*-direction, and + another transform for the *y*-direction. This version is an optimization for the case where both child - transforms are of type Affine2DBase. + transforms are of type :class:`Affine2DBase`. """ is_separable = True def __init__(self, x_transform, y_transform): """ - Create a new "blended" transform using x_transform to - transform the x-axis and y_transform to transform the y_axis. + Create a new "blended" transform using *x_transform* to + transform the *x*-axis and *y_transform* to transform the + *y*-axis. - Both x_transform and y_transform must be 2D affine transforms. + Both *x_transform* and *y_transform* must be 2D affine + transforms. You will generally not call this constructor directly but use the :func:`blended_transform_factory` function instead, which @@ -1755,8 +1763,8 @@ def blended_transform_factory(x_transform, y_transform): """ - Create a new "blended" transform using x_transform to - transform the x-axis and y_transform to transform the y_axis. + Create a new "blended" transform using *x_transform* to transform + the *x*-axis and *y_transform* to transform the *y*-axis. A faster version of the blended transform is returned for the case where both child transforms are affine. @@ -1769,16 +1777,18 @@ class CompositeGenericTransform(Transform): """ - A composite transform formed by applying transform a then transform b. + A composite transform formed by applying transform *a* then + transform *b*. - This "generic" version can handle any two arbitrary transformations. + This "generic" version can handle any two arbitrary + transformations. """ pass_through = True def __init__(self, a, b): """ Create a new composite transform that is the result of - applying transform a then transform b. + applying transform *a* then transform *b*. You will generally not call this constructor directly but use the :func:`composite_transform_factory` function instead, @@ -1862,17 +1872,17 @@ class CompositeAffine2D(Affine2DBase): """ - A composite transform formed by applying transform a then transform b. + A composite transform formed by applying transform *a* then transform *b*. - This version is an optimization that handles the case where both a - and b are 2D affines. + This version is an optimization that handles the case where both *a* + and *b* are 2D affines. """ def __init__(self, a, b): """ Create a new composite transform that is the result of - applying transform a then transform b. + applying transform *a* then transform *b*. - Both a and b must be instances of :class:`Affine2DBase`. + Both *a* and *b* must be instances of :class:`Affine2DBase`. You will generally not call this constructor directly but use the :func:`composite_transform_factory` function instead, @@ -1916,7 +1926,7 @@ is the identity transform. Composite transforms may also be created using the '+' operator, - e.g.: + e.g.:: c = a + b """ @@ -1931,14 +1941,15 @@ class BboxTransform(Affine2DBase): """ - BboxTransform linearly transforms points from one Bbox to another Bbox. + :class:`BboxTransform` linearly transforms points from one + :class:`Bbox` to another :class:`Bbox`. """ is_separable = True def __init__(self, boxin, boxout): """ - Create a new BboxTransform that linearly transforms points - from boxin to boxout. + Create a new :class:`BboxTransform` that linearly transforms + points from *boxin* to *boxout*. """ assert boxin.is_bbox assert boxout.is_bbox @@ -1974,15 +1985,16 @@ class BboxTransformTo(Affine2DBase): """ - BboxTransformTo is a transformation that linearly transforms - points from the unit bounding box to a given :class:`Bbox`. + :class:`BboxTransformTo` is a transformation that linearly + transforms points from the unit bounding box to a given + :class:`Bbox`. """ is_separable = True def __init__(self, boxout): """ Create a new :class:`BboxTransformTo` that linearly transforms - points from the unit bounding box to boxout. + points from the unit bounding box to *boxout*. """ assert boxout.is_bbox @@ -2013,7 +2025,7 @@ class BboxTransformFrom(Affine2DBase): """ - BboxTransform linearly transforms points from a given + :class:`BboxTransformFrom` linearly transforms points from a given :class:`Bbox` to the unit bounding box. """ is_separable = True @@ -2050,8 +2062,8 @@ class ScaledTranslation(Affine2DBase): """ - A transformation that translates by xt and yt, after xt and yt - have been transformaed by the given transform scale_trans. + A transformation that translates by *xt* and *yt*, after *xt* and *yt* + have been transformad by the given transform *scale_trans*. """ def __init__(self, xt, yt, scale_trans): Affine2DBase.__init__(self) @@ -2080,13 +2092,15 @@ class TransformedPath(TransformNode): """ - A TransformedPath caches a non-affine transformed copy of the - path. This cached copy is automatically updated when the - non-affine part of the transform changes. + A :class:`TransformedPath` caches a non-affine transformed copy of + the :class:`~matplotlib.path.Path`. This cached copy is + automatically updated when the non-affine part of the transform + changes. """ def __init__(self, path, transform): """ - Create a new TransformedPath from the given path and transform. + Create a new :class:`TransformedPath` from the given + :class:`~matplotlib.path.Path` and :class:`Transform`. """ assert isinstance(transform, Transform) TransformNode.__init__(self) @@ -2111,8 +2125,8 @@ Return a copy of the child path, with the non-affine part of the transform already applied, along with the affine part of the path necessary to complete the transformation. Unlike - get_transformed_path_and_affine, no interpolation will be - performed. + :meth:`get_transformed_path_and_affine`, no interpolation will + be performed. """ self._revalidate() return self._transformed_points, self.get_affine() @@ -2201,82 +2215,3 @@ raise ValueError('units must be dots, points, or inches') return trans + ScaledTranslation(x, y, fig.dpi_scale_trans) -if __name__ == '__main__': - import copy - from random import random - import timeit - - bbox = Bbox.from_extents(10., 15., 20., 25.) - assert bbox.x0 == 10 - assert bbox.y0 == 15 - assert bbox.x1 == 20 - assert bbox.y1 == 25 - - assert np.all(bbox.min == [10, 15]) - assert np.all(bbox.max == [20, 25]) - assert np.all(bbox.intervalx == (10, 20)) - assert np.all(bbox.intervaly == (15, 25)) - - assert bbox.width == 10 - assert bbox.height == 10 - - assert bbox.bounds == (10, 15, 10, 10) - - assert tuple(np.asarray(bbox).flatten()) == (10, 15, 20, 25) - - bbox.intervalx = (11, 21) - bbox.intervaly = (16, 26) - - assert bbox.bounds == (11, 16, 10, 10) - - bbox.x0 = 12 - bbox.y0 = 17 - bbox.x1 = 22 - bbox.y1 = 27 - - assert bbox.bounds == (12, 17, 10, 10) - - bbox = Bbox.from_bounds(10, 11, 12, 13) - assert bbox.bounds == (10, 11, 12, 13) - - bbox_copy = copy.deepcopy(bbox) - assert (bbox.extents == bbox_copy.extents).all() - bbox_copy.p1 = (14, 15) - assert bbox.bounds == (10, 11, 12, 13) - assert bbox_copy.bounds == (10, 11, 4, 4) - - bbox1 = Bbox([[10., 15.], [20., 25.]]) - bbox2 = Bbox([[30., 35.], [40., 45.]]) - trans = BboxTransform(bbox1, bbox2) - bbox3 = bbox1.transformed(trans) - assert (bbox3.extents == bbox2.extents).all() - - translation = Affine2D().translate(10, 20) - assert translation.to_values() == (1, 0, 0, 1, 10, 20) - scale = Affine2D().scale(10, 20) - assert scale.to_values() == (10, 0, 0, 20, 0, 0) - rotation = Affine2D().rotate_deg(30) - assert rotation.to_values() == (0.86602540378443871, 0.49999999999999994, - -0.49999999999999994, 0.86602540378443871, - 0.0, 0.0) - - points = np.array([[1, 2], [3, 4], [5, 6], [7, 8]], np.float_) - translated_points = translation.transform(points) - assert (translated_points == [[11., 22.], [13., 24.], [15., 26.], [17., 28.]]).all() - scaled_points = scale.transform(points) - print scaled_points - rotated_points = rotation.transform(points) - print rotated_points - - tpoints1 = rotation.transform(translation.transform(scale.transform(points))) - trans_sum = scale + translation + rotation - tpoints2 = trans_sum.transform(points) - # Need to do some sort of fuzzy comparison here? - assert (tpoints1.round() == tpoints2.round()).all() - - print points - - # Here are some timing tests - points = np.asarray([(random(), random()) for i in xrange(10000)]) - t = timeit.Timer("trans_sum.transform(points)", "from __main__ import trans_sum, points") - print "Time to transform 10000 x 10 points:", t.timeit(10) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |