|
From: <ef...@us...> - 2008-11-18 23:38:59
|
Revision: 6414
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6414&view=rev
Author: efiring
Date: 2008-11-18 23:38:53 +0000 (Tue, 18 Nov 2008)
Log Message:
-----------
New custom colormap example; and fix typo in Axes.autoscale_view
Modified Paths:
--------------
trunk/matplotlib/examples/tests/backend_driver.py
trunk/matplotlib/lib/matplotlib/axes.py
Added Paths:
-----------
trunk/matplotlib/examples/pylab_examples/custom_cmap.py
Added: trunk/matplotlib/examples/pylab_examples/custom_cmap.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/custom_cmap.py (rev 0)
+++ trunk/matplotlib/examples/pylab_examples/custom_cmap.py 2008-11-18 23:38:53 UTC (rev 6414)
@@ -0,0 +1,134 @@
+#!/usr/bin/env python
+
+import numpy as np
+import matplotlib.pyplot as plt
+from matplotlib.colors import LinearSegmentedColormap
+
+"""
+
+Example: suppose you want red to increase from 0 to 1 over the bottom
+half, green to do the same over the middle half, and blue over the top
+half. Then you would use:
+
+cdict = {'red': ((0.0, 0.0, 0.0),
+ (0.5, 1.0, 1.0),
+ (1.0, 1.0, 1.0)),
+
+ 'green': ((0.0, 0.0, 0.0),
+ (0.25, 0.0, 0.0),
+ (0.75, 1.0, 1.0),
+ (1.0, 1.0, 1.0)),
+
+ 'blue': ((0.0, 0.0, 0.0),
+ (0.5, 0.0, 0.0),
+ (1.0, 1.0, 1.0))}
+
+If, as in this example, there are no discontinuities in the r, g, and b
+components, then it is quite simple: the second and third element of
+each tuple, above, is the same--call it "y". The first element ("x")
+defines interpolation intervals over the full range of 0 to 1, and it
+must span that whole range. In other words, the values of x divide the
+0-to-1 range into a set of segments, and y gives the end-point color
+values for each segment.
+
+Now consider the green. cdict['green'] is saying that for
+0 <= x <= 0.25, y is zero; no green.
+0.25 < x <= 0.75, y varies linearly from 0 to 1.
+x > 0.75, y remains at 1, full green.
+
+If there are discontinuities, then it is a little more complicated.
+Label the 3 elements in each row in the cdict entry for a given color as
+(x, y0, y1). Then for values of x between x[i] and x[i+1] the color
+value is interpolated between y1[i] and y0[i+1].
+
+Going back to the cookbook example, look at cdict['red']; because y0 !=
+y1, it is saying that for x from 0 to 0.5, red increases from 0 to 1,
+but then it jumps down, so that for x from 0.5 to 1, red increases from
+0.7 to 1. Green ramps from 0 to 1 as x goes from 0 to 0.5, then jumps
+back to 0, and ramps back to 1 as x goes from 0.5 to 1.
+
+row i: x y0 y1
+ /
+ /
+row i+1: x y0 y1
+
+Above is an attempt to show that for x in the range x[i] to x[i+1], the
+interpolation is between y1[i] and y0[i+1]. So, y0[0] and y1[-1] are
+never used.
+
+"""
+
+
+
+cdict1 = {'red': ((0.0, 0.0, 0.0),
+ (0.5, 0.0, 0.1),
+ (1.0, 1.0, 1.0)),
+
+ 'green': ((0.0, 0.0, 0.0),
+ (1.0, 0.0, 0.0)),
+
+ 'blue': ((0.0, 0.0, 1.0),
+ (0.5, 0.1, 0.0),
+ (1.0, 0.0, 0.0))
+ }
+
+cdict2 = {'red': ((0.0, 0.0, 0.0),
+ (0.5, 0.0, 1.0),
+ (1.0, 0.1, 1.0)),
+
+ 'green': ((0.0, 0.0, 0.0),
+ (1.0, 0.0, 0.0)),
+
+ 'blue': ((0.0, 0.0, 0.1),
+ (0.5, 1.0, 0.0),
+ (1.0, 0.0, 0.0))
+ }
+
+cdict3 = {'red': ((0.0, 0.0, 0.0),
+ (0.25,0.0, 0.0),
+ (0.5, 0.8, 1.0),
+ (0.75,1.0, 1.0),
+ (1.0, 0.4, 1.0)),
+
+ 'green': ((0.0, 0.0, 0.0),
+ (0.25,0.0, 0.0),
+ (0.5, 0.9, 0.9),
+ (0.75,0.0, 0.0),
+ (1.0, 0.0, 0.0)),
+
+ 'blue': ((0.0, 0.0, 0.4),
+ (0.25,1.0, 1.0),
+ (0.5, 1.0, 0.8),
+ (0.75,0.0, 0.0),
+ (1.0, 0.0, 0.0))
+ }
+
+
+blue_red1 = LinearSegmentedColormap('BlueRed1', cdict1)
+blue_red2 = LinearSegmentedColormap('BlueRed2', cdict2)
+blue_red3 = LinearSegmentedColormap('BlueRed3', cdict3)
+
+x = np.arange(0, np.pi, 0.1)
+y = np.arange(0, 2*np.pi, 0.1)
+X, Y = np.meshgrid(x,y)
+Z = np.cos(X) * np.sin(Y)
+
+plt.figure(figsize=(10,4))
+plt.subplots_adjust(wspace=0.3)
+
+plt.subplot(1,3,1)
+plt.imshow(Z, interpolation='nearest', cmap=blue_red1)
+plt.colorbar()
+
+plt.subplot(1,3,2)
+plt.imshow(Z, interpolation='nearest', cmap=blue_red2)
+plt.colorbar()
+
+plt.subplot(1,3,3)
+plt.imshow(Z, interpolation='nearest', cmap=blue_red3)
+plt.colorbar()
+
+plt.suptitle('Custom Blue-Red colormaps')
+
+plt.show()
+
Modified: trunk/matplotlib/examples/tests/backend_driver.py
===================================================================
--- trunk/matplotlib/examples/tests/backend_driver.py 2008-11-18 21:37:25 UTC (rev 6413)
+++ trunk/matplotlib/examples/tests/backend_driver.py 2008-11-18 23:38:53 UTC (rev 6414)
@@ -43,6 +43,7 @@
'contour_demo.py',
'contour_label_demo.py',
'contourf_demo.py',
+ 'custom_cmap.py',
'geo_demo.py',
'griddata_demo.py',
'csd_demo.py',
Modified: trunk/matplotlib/lib/matplotlib/axes.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/axes.py 2008-11-18 21:37:25 UTC (rev 6413)
+++ trunk/matplotlib/lib/matplotlib/axes.py 2008-11-18 23:38:53 UTC (rev 6414)
@@ -1496,7 +1496,7 @@
if scalex:
self.set_xbound(x0, x1)
if scaley:
- self.set_ybound(y0, 11)
+ self.set_ybound(y0, y1)
return
if scalex:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2008-11-19 14:45:51
|
Revision: 6415
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6415&view=rev
Author: mdboom
Date: 2008-11-19 14:45:44 +0000 (Wed, 19 Nov 2008)
Log Message:
-----------
Converted API_CHANGES to reST and included it in the documentation tree.
Modified Paths:
--------------
trunk/matplotlib/doc/api/index.rst
Added Paths:
-----------
trunk/matplotlib/doc/api/api_changes.rst
Removed Paths:
-------------
trunk/matplotlib/API_CHANGES
Deleted: trunk/matplotlib/API_CHANGES
===================================================================
--- trunk/matplotlib/API_CHANGES 2008-11-18 23:38:53 UTC (rev 6414)
+++ trunk/matplotlib/API_CHANGES 2008-11-19 14:45:44 UTC (rev 6415)
@@ -1,1310 +0,0 @@
-Changes for 0.98.x
-==================
-
-* set_xlim, ylim now return a copy of the viewlim array to
- avoid modify inplace surprises
-
-* AFM.get_fullname() and get_familyname() no longer raise an
- exception if the AFM file does not specify these optional attributes,
- but returns a guess based on the required FontName attribute.
-
-* Changed precision kwarg in spy; default is 0, and the string value
- 'present' is used for sparse arrays only to show filled locations.
-
-* EllipseCollection added.
-
-* Added angles kwarg to quiver for more flexible specification of
- the arrow angles.
-
-* Deprecated (raise NotImplementedError) all the mlab2 functions from
- matplotlib.mlab out of concern that some of them were not clean room
- implementations.
-
-* Methods get_offsets and set_offsets added to Collections base
- class.
-
-* Figure.figurePatch renamed Figure.patch, Axes.axesPatch renamed
- Axes.patch, Axes.axesFrame renamed Axes.frame, Axes.get_frame, which
- returns Axes.patch, is deprecated. Examples and users guide updated
-
-* Changes in the ContourLabeler attributes (clabel function) so that they
- all have a form like .labelAttribute. The three attributes that are most
- likely to be used by end users, .cl, .cl_xy and .cl_cvalues have been
- maintained for the moment (in addition to their renamed versions), but they
- are depricated and will eventually be removed.
-
-* Moved several function in mlab.py and cbook.py into a separate module
- numerical_methods.py because they were unrelated to the initial purpose of
- mlab or cbook and appeared more coherent elsewhere.
-
-Changes for 0.98.1
-==================
-
-* Removed broken axes3d support and replaced it with a non implemented
- error pointing to 0.91.x
-
-Changes for 0.98.0
-==================
-
- matplotlib.image.imread now no longer always returns RGBA -- if
- the image is luminance or RGB, it will return a MxN or MxNx3 array
- if possible. Also uint8 is no longer always forced to float.
-
- Rewrote the cm.ScalarMappable callback infrastructure to use
- cbook.CallbackRegistry rather than custom callback handling. Amy
- users of add_observer/notify of the cm.ScalarMappable should uae
- the cm.ScalarMappable.callbacksSM CallbackRegistry instead.
-
- New axes function and Axes method provide control over the plot
- color cycle: axes.set_default_color_cycle(clist) and
- Axes.set_color_cycle(clist).
-
- matplotlib now requires python2.4, so matplotlib.cbook will no
- loner provide set, enumerate, reversed or izip compatability functions
-
- In numpy 1.0 bins are specified by the left edges only. The axes
- method "hist" now uses future numpy 1.3 semantic for histograms.
- Providing binedges, the last value gives the upper-right edge now,
- which was implicitly set to +infinity in numpy 1.0. This also means
- that the last bin doesn't contain upper outliers any more by default.
-
- New axes method and pyplot function, hexbin, is an alternative
- to scatter for large datasets. It makes something like a
- pcolor of a 2-D histogram, but uses hexagonal bins.
-
- New kwarg, "symmetric", in MaxNLocator
- allows one require an axis to be centered on zero.
-
- toolkits must now be imported from mpl_toolkits (not matplotlib.toolkits)
-
-TRANSFORMS REFACTORING
-
- The primary goal of this refactoring was to make it easier to
- extend matplotlib to support new kinds of projections. This is
- primarily an internal improvement, and the possible user-visible
- changes it allows are yet to come.
-
- See transforms.py for a description of the design of the new
- transformation framework.
-
- For efficiency, many of these functions return views into Numpy
- arrays. This means that if you hold on to a reference to them,
- their contents may change. If you want to store a snapshot of
- their current values, use the Numpy array method copy().
-
- The view intervals are now stored only in one place -- in the Axes
- instance, not in the formatter instances as well. This means
- formatters must get their limits from their Axis, which in turn
- looks up its limits from the Axes. If a Locator is used
- temporarily and not assigned to an Axis or Axes, (e.g. in
- contour.py), a dummy axis must be created to store its bounds.
- Call Locator.create_dummy_axis() to do so.
-
- The functionality of Pbox has been merged with Bbox. Its methods
- now all return copies rather than modifying in place.
-
- The following lists many of the simple changes necessary to update
- code from the old transformation framework to the new one. In
- particular, methods that return a copy are named with a verb in
- the past tense, whereas methods that alter an object in place are
- named with a very in the present tense.
-
- transforms.py
- Bbox.get_bounds() Bbox.bounds
-
- Bbox.width() Bbox.width
-
- Bbox.height() Bbox.height
-
- Bbox.intervalx().get_bounds() Bbox.intervalx
- Bbox.intervalx().set_bounds()
- [Bbox.intervalx is now a property.]
-
- Bbox.intervaly().get_bounds() Bbox.intervaly
- Bbox.intervaly().set_bounds()
- [Bbox.intervaly is now a property.]
-
- Bbox.xmin() Bbox.x0 or Bbox.xmin
- Bbox.ymin() Bbox.y0 or Bbox.ymin
- Bbox.xmax() Bbox.x1 or Bbox.xmax
- Bbox.ymax() Bbox.y1 or Bbox.ymax
- [The Bbox is bound by the points (x0, y0) to (x1, y1) and
- there is no defined order to these points, that is, x0 is not
- necessarily the left edge of the box. To get the left edge of
- the Bbox, use the read-only property xmin.]
-
- Bbox.overlaps(bboxes) Bbox.count_overlaps(bboxes)
-
- bbox_all(bboxes) Bbox.union(bboxes)
- [Bbox.union is a staticmethod.]
-
- lbwh_to_bbox(l, b, w, h) Bbox.from_bounds(x0, y0, w, h)
-
- inverse_transform_bbox(trans, bbox) bbox.inverse_transformed(trans)
-
- Interval.contains_open(v) interval_contains_open(tuple, v)
- Interval.contains(v) interval_contains_open(tuple, v)
-
- identity_transform() IdentityTransform()
-
- blend_xy_sep_transform(xtrans, ytrans) blended_transform_factory(xtrans, ytrans)
-
- scale_transform(xs, ys) Affine2D().scale(xs[, ys])
-
- get_bbox_transform(boxin, boxout) BboxTransform(boxin, boxout) or
- BboxTransformFrom(boxin) or
- BboxTransformTo(boxout)
-
- Transform.seq_xy_tup(points) Transform.transform(points)
-
- Transform.inverse_xy_tup(points) Transform.inverted().transform(points)
-
- axes.py
- Axes.get_position() Axes.get_position()
- [Axes.get_position() used to return a list of points, not it
- returns a transforms.Bbox instance.]
-
- Axes.set_position() Axes.set_position()
- [Axes.set_position() now accepts either four scalars or a
- transforms Bbox instance.]
-
- [also returns a Bbox]
- Axes.toggle_log_lineary() Axes.set_yscale()
- [Since the recfactoring allows for more than two scale types
- ('log' or 'linear'), it no longer makes sense to have a
- toggle. Axes.toggle_log_lineary() has been removed.]
-
- Axes.hlines(linestyle=) Axes.hlines(linestyles=)
- Axes.vlines(linestyle=) Axes.vlines(linestyles=)
- [The kwarg 'linestyle' has been replaced with 'linestyles',
- which accepts either a single linestyle or a list of
- linestyles to use.]
-
- Subplot class is gone -- now there is only SubplotBase.
-
- The Polar class has moved to projections/polar.py
-
- artist.py
- Artist.set_clip_path(path) Artist.set_clip_path(path, transform)
- [set_clip_path now accepts a path.Path instance and a
- transformation that will be applied to the path immediately
- before clipping.]
-
- collections.py
- linestyle linestyles
- [Linestyles are now treated like all other collection
- attributes -- a single value or multiple values may be
- provided.]
-
- colors.py
- ColorConvertor.to_rgba_list(c) ColorConvertor.to_rgba_array(c)
- [ColorConvertor.to_rgba_array(c) returns an Nx4 Numpy array of
- RGBA color quadruples.]
-
- contour.py
- Contour._segments Contour.get_paths()
- [Contour.get_paths() now returns a list of path.Path instances.]
-
- figure.py
- Figure.dpi.get()/set() Figure.dpi (a property)
-
- patches.py
- get_verts() get_path()
- [Patch.get_path() returns a path.Path instance.]
-
- backend_bases.py
- GraphicsContext.set_clip_rectangle(tuple) GraphicsContext.set_clip_rectangle(bbox)
-
- GraphicsContext.get_clip_path() GraphicsContext.get_clip_path()
- [GraphicsContext.get_clip_path() returns a tuple of the form
- (path, affine_transform), where path is a path.Path instance
- and affine_transform is a transforms.Affine2D instance.]
-
- GraphicsContext.set_clip_path(clippath) GraphicsContext.set_clip_path(clippath)
- [Now accepts only an instance of transforms.TransformedPath.]
-
- RendererBase class:
- **new methods** --->
- draw_path(self, gc, path, transform, rgbFace)
-
- draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace)
-
- draw_path_collection(self, master_transform, cliprect, clippath,
- clippath_trans, paths, all_transforms, offsets,
- offsetTrans, facecolors, edgecolors, linewidths,
- linestyles, antialiaseds) [optional]
-
-
- **changed methods** --->
- draw_image(self, x, y, im, bbox) draw_image(self, x, y, im, bbox,
- clippath, clippath_trans)
-
- **removed methods** --->
- draw_arc
- draw_line_collection
- draw_line
- draw_lines
- draw_point
- draw_quad_mesh
- draw_poly_collection
- draw_polygon
- draw_rectangle
- draw_regpoly_collection
-
-END OF TRANSFORMS REFACTORING
-
-
-
-
-0.91.2 Released
-
- For csv2rec, checkrows=0 is the new default indicating all rows
- will be checked for type inference
-
- A warning is issued when an image is drawn on log-scaled
- axes, since it will not log-scale the image data.
-
- Moved rec2gtk to matplotlib.toolkits.gtktools
-
- Moved rec2excel to matplotlib.toolkits.exceltools
-
- Removed, dead/experimental ExampleInfo, Namespace and Importer
- code from matplotlib/__init__.py
-
-0.91.1 Released
-
-0.91.0 Released
-
- Changed cbook.is_file_like to cbook.is_writable_file_like and
- corrected behavior.
-
- Added ax kwarg to pyplot.colorbar and Figure.colorbar so that
- one can specify the axes object from which space for the colorbar
- is to be taken, if one does not want to make the colorbar axes
- manually.
-
- Changed cbook.reversed so it yields a tuple rather than a
- (index, tuple). This agrees with the python reversed builtin,
- and cbook only defines reversed if python doesnt provide the
- builtin.
-
- Made skiprows=1 the default on csv2rec
-
- The gd and paint backends have been deleted.
-
- The errorbar method and function now accept additional kwargs
- so that upper and lower limits can be indicated by capping the
- bar with a caret instead of a straight line segment.
-
- The dviread.py file now has a parser for files like psfonts.map
- and pdftex.map, to map TeX font names to external files.
-
- The file type1font.py contains a new class for Type 1 fonts.
- Currently it simply reads pfa and pfb format files and stores the
- data in a way that is suitable for embedding in pdf files. In the
- future the class might actually parse the font to allow e.g.
- subsetting.
-
- FT2Font now supports FT_Attach_File. In practice this can be used
- to read an afm file in addition to a pfa/pfb file, to get metrics
- and kerning information for a Type 1 font.
-
- The AFM class now supports querying CapHeight and stem widths. The
- get_name_char method now has an isord kwarg like get_width_char.
-
- Changed pcolor default to shading='flat'; but as noted now in the
- docstring, it is preferable to simply use the edgecolor kwarg.
-
- The mathtext font commands (\cal, \rm, \it, \tt) now behave as TeX
- does: they are in effect until the next font change command or the
- end of the grouping. Therefore uses of $\cal{R}$ should be
- changed to ${\cal R}$. Alternatively, you may use the new
- LaTeX-style font commands (\mathcal, \mathrm, \mathit, \mathtt)
- which do affect the following group, eg. $\mathcal{R}$.
-
- Text creation commands have a new default linespacing and
- a new linespacing kwarg, which is a multiple of the maximum
- vertical extent of a line of ordinary text. The default is
- 1.2; linespacing=2 would be like ordinary double spacing, for
- example.
-
- Changed default kwarg in colors.Normalize.__init__ to clip=False;
- clipping silently defeats the purpose of the special over, under,
- and bad values in the colormap, thereby leading to unexpected
- behavior. The new default should reduce such surprises.
-
- Made the emit property of set_xlim and set_ylim true by default;
- removed the Axes custom callback handling into a 'callbacks'
- attribute which is a cbook.CallbackRegistry instance. This now
- supports the xlim_changed and ylim_changed Axes events.
-
-0.90.1 released
-
- The file dviread.py has a (very limited and fragile) dvi reader
- for usetex support. The API might change in the future so don't
- depend on it yet.
-
- Removed deprecated support for a float value as a gray-scale;
- now it must be a string, like '0.5'. Added alpha kwarg to
- ColorConverter.to_rgba_list.
-
- New method set_bounds(vmin, vmax) for formatters, locators sets
- the viewInterval and dataInterval from floats.
-
- Removed deprecated colorbar_classic.
-
- Line2D.get_xdata and get_ydata valid_only=False kwarg is replaced
- by orig=True. When True, it returns the original data, otherwise
- the processed data (masked, converted)
-
- Some modifications to the units interface.
- units.ConversionInterface.tickers renamed to
- units.ConversionInterface.axisinfo and it now returns a
- units.AxisInfo object rather than a tuple. This will make it
- easier to add axis info functionality (eg I added a default label
- on this iteration) w/o having to change the tuple length and hence
- the API of the client code everytime new functionality is added.
- Also, units.ConversionInterface.convert_to_value is now simply
- named units.ConversionInterface.convert.
-
- Axes.errorbar uses Axes.vlines and Axes.hlines to draw its error
- limits int he vertical and horizontal direction. As you'll see
- in the changes below, these funcs now return a LineCollection
- rather than a list of lines. The new return signature for
- errorbar is ylins, caplines, errorcollections where
- errorcollections is a xerrcollection, yerrcollection
-
- Axes.vlines and Axes.hlines now create and returns a LineCollection, not a list
- of lines. This is much faster. The kwarg signature has changed,
- so consult the docs
-
- MaxNLocator accepts a new Boolean kwarg ('integer') to force
- ticks to integer locations.
-
- Commands that pass an argument to the Text constructor or to
- Text.set_text() now accept any object that can be converted
- with '%s'. This affects xlabel(), title(), etc.
-
- Barh now takes a **kwargs dict instead of most of the old
- arguments. This helps ensure that bar and barh are kept in sync,
- but as a side effect you can no longer pass e.g. color as a
- positional argument.
-
- ft2font.get_charmap() now returns a dict that maps character codes
- to glyph indices (until now it was reversed)
-
- Moved data files into lib/matplotlib so that setuptools' develop
- mode works. Re-organized the mpl-data layout so that this source
- structure is maintained in the installation. (I.e. the 'fonts' and
- 'images' sub-directories are maintained in site-packages.).
- Suggest removing site-packages/matplotlib/mpl-data and
- ~/.matplotlib/ttffont.cache before installing
-
-0.90.0 released
-
- All artists now implement a "pick" method which users should not
- call. Rather, set the "picker" property of any artist you want to
- pick on (the epsilon distance in points for a hit test) and
- register with the "pick_event" callback. See
- examples/pick_event_demo.py for details
-
- Bar, barh, and hist have "log" binary kwarg: log=True
- sets the ordinate to a log scale.
-
- Boxplot can handle a list of vectors instead of just
- an array, so vectors can have different lengths.
-
- Plot can handle 2-D x and/or y; it plots the columns.
-
- Added linewidth kwarg to bar and barh.
-
- Made the default Artist._transform None (rather than invoking
- identity_transform for each artist only to have it overridden
- later). Use artist.get_transform() rather than artist._transform,
- even in derived classes, so that the default transform will be
- created lazily as needed
-
- New LogNorm subclass of Normalize added to colors.py.
- All Normalize subclasses have new inverse() method, and
- the __call__() method has a new clip kwarg.
-
- Changed class names in colors.py to match convention:
- normalize -> Normalize, no_norm -> NoNorm. Old names
- are still available for now.
-
- Removed obsolete pcolor_classic command and method.
-
- Removed lineprops and markerprops from the Annotation code and
- replaced them with an arrow configurable with kwarg arrowprops.
- See examples/annotation_demo.py - JDH
-
-0.87.7 released
-
- Completely reworked the annotations API because I found the old
- API cumbersome. The new design is much more legible and easy to
- read. See matplotlib.text.Annotation and
- examples/annotation_demo.py
-
- markeredgecolor and markerfacecolor cannot be configured in
- matplotlibrc any more. Instead, markers are generally colored
- automatically based on the color of the line, unless marker colors
- are explicitely set as kwargs - NN
-
- Changed default comment character for load to '#' - JDH
-
- math_parse_s_ft2font_svg from mathtext.py & mathtext2.py now returns
- width, height, svg_elements. svg_elements is an instance of Bunch (
- cmbook.py) and has the attributes svg_glyphs and svg_lines, which are both
- lists.
-
- Renderer.draw_arc now takes an additional parameter, rotation.
- It specifies to draw the artist rotated in degrees anti-
- clockwise. It was added for rotated ellipses.
-
- Renamed Figure.set_figsize_inches to Figure.set_size_inches to
- better match the get method, Figure.get_size_inches.
-
- Removed the copy_bbox_transform from transforms.py; added
- shallowcopy methods to all transforms. All transforms already
- had deepcopy methods.
-
- FigureManager.resize(width, height): resize the window
- specified in pixels
-
- barh: x and y args have been renamed to width and bottom
- respectively, and their order has been swapped to maintain
- a (position, value) order.
-
- bar and barh: now accept kwarg 'edgecolor'.
-
- bar and barh: The left, height, width and bottom args can
- now all be scalars or sequences; see docstring.
-
- barh: now defaults to edge aligned instead of center
- aligned bars
-
- bar, barh and hist: Added a keyword arg 'align' that
- controls between edge or center bar alignment.
-
- Collections: PolyCollection and LineCollection now accept
- vertices or segments either in the original form [(x,y),
- (x,y), ...] or as a 2D numerix array, with X as the first column
- and Y as the second. Contour and quiver output the numerix
- form. The transforms methods Bbox.update() and
- Transformation.seq_xy_tups() now accept either form.
-
- Collections: LineCollection is now a ScalarMappable like
- PolyCollection, etc.
-
- Specifying a grayscale color as a float is deprecated; use
- a string instead, e.g., 0.75 -> '0.75'.
-
- Collections: initializers now accept any mpl color arg, or
- sequence of such args; previously only a sequence of rgba
- tuples was accepted.
-
- Colorbar: completely new version and api; see docstring. The
- original version is still accessible as colorbar_classic, but
- is deprecated.
-
- Contourf: "extend" kwarg replaces "clip_ends"; see docstring.
- Masked array support added to pcolormesh.
-
- Modified aspect-ratio handling:
- Removed aspect kwarg from imshow
- Axes methods:
- set_aspect(self, aspect, adjustable=None, anchor=None)
- set_adjustable(self, adjustable)
- set_anchor(self, anchor)
- Pylab interface:
- axis('image')
-
- Backend developers: ft2font's load_char now takes a flags
- argument, which you can OR together from the LOAD_XXX
- constants.
-
-API Changes in matplotlib-0.86
-
- Matplotlib data is installed into the matplotlib module.
- This is similar to package_data. This should get rid of
- having to check for many possibilities in _get_data_path().
- The MATPLOTLIBDATA env key is still checked first to allow
- for flexibility.
-
- 1) Separated the color table data from cm.py out into
- a new file, _cm.py, to make it easier to find the actual
- code in cm.py and to add new colormaps. Everything
- from _cm.py is imported by cm.py, so the split should be
- transparent.
- 2) Enabled automatic generation of a colormap from
- a list of colors in contour; see modified
- examples/contour_demo.py.
- 3) Support for imshow of a masked array, with the
- ability to specify colors (or no color at all) for
- masked regions, and for regions that are above or
- below the normally mapped region. See
- examples/image_masked.py.
- 4) In support of the above, added two new classes,
- ListedColormap, and no_norm, to colors.py, and modified
- the Colormap class to include common functionality. Added
- a clip kwarg to the normalize class.
-
-
-API Changes in matplotlib-0.85
-
- Made xtick and ytick separate props in rc
-
- made pos=None the default for tick formatters rather than 0 to
- indicate "not supplied"
-
- Removed "feature" of minor ticks which prevents them from
- overlapping major ticks. Often you want major and minor ticks at
- the same place, and can offset the major ticks with the pad. This
- could be made configurable
-
- Changed the internal structure of contour.py to a more OO style.
- Calls to contour or contourf in axes.py or pylab.py now return
- a ContourSet object which contains references to the
- LineCollections or PolyCollections created by the call,
- as well as the configuration variables that were used.
- The ContourSet object is a "mappable" if a colormap was used.
-
- Added a clip_ends kwarg to contourf. From the docstring:
- * clip_ends = True
- If False, the limits for color scaling are set to the
- minimum and maximum contour levels.
- True (default) clips the scaling limits. Example:
- if the contour boundaries are V = [-100, 2, 1, 0, 1, 2, 100],
- then the scaling limits will be [-100, 100] if clip_ends
- is False, and [-3, 3] if clip_ends is True.
- Added kwargs linewidths, antialiased, and nchunk to contourf. These
- are experimental; see the docstring.
-
- Changed Figure.colorbar():
- kw argument order changed;
- if mappable arg is a non-filled ContourSet, colorbar() shows
- lines instead hof polygons.
- if mappable arg is a filled ContourSet with clip_ends=True,
- the endpoints are not labelled, so as to give the
- correct impression of open-endedness.
-
- Changed LineCollection.get_linewidths to get_linewidth, for
- consistency.
-
-
-API Changes in matplotlib-0.84
-
- Unified argument handling between hlines and vlines. Both now
- take optionally a fmt argument (as in plot) and a keyword args
- that can be passed onto Line2D.
-
- Removed all references to "data clipping" in rc and lines.py since
- these were not used and not optimized. I'm sure they'll be
- resurrected later with a better implementation when needed.
-
- 'set' removed - no more deprecation warnings. Use 'setp' instead.
-
- Backend developers: Added flipud method to image and removed it
- from to_str. Removed origin kwarg from backend.draw_image.
- origin is handled entirely by the frontend now.
-
-API Changes in matplotlib-0.83
-
- - Made HOME/.matplotlib the new config dir where the matplotlibrc
- file, the ttf.cache, and the tex.cache live. The new default
- filenames in .matplotlib have no leading dot and are not hidden.
- Eg, the new names are matplotlibrc, tex.cache, and ttffont.cache.
- This is how ipython does it so it must be right.
-
- If old files are found, a warning is issued and they are moved to
- the new location.
-
- - backends/__init__.py no longer imports new_figure_manager,
- draw_if_interactive and show from the default backend, but puts
- these imports into a call to pylab_setup. Also, the Toolbar is no
- longer imported from WX/WXAgg. New usage:
-
- from backends import pylab_setup
- new_figure_manager, draw_if_interactive, show = pylab_setup()
-
- - Moved Figure.get_width_height() to FigureCanvasBase. It now
- returns int instead of float.
-
-API Changes in matplotlib-0.82
-
- - toolbar import change in GTKAgg, GTKCairo and WXAgg
-
- - Added subplot config tool to GTK* backends -- note you must now
- import the NavigationToolbar2 from your backend of choice rather
- than from backend_gtk because it needs to know about the backend
- specific canvas -- see examples/embedding_in_gtk2.py. Ditto for
- wx backend -- see examples/embedding_in_wxagg.py
-
-
- - hist bin change
-
- Sean Richards notes there was a problem in the way we created
- the binning for histogram, which made the last bin
- underrepresented. From his post:
-
- I see that hist uses the linspace function to create the bins
- and then uses searchsorted to put the values in their correct
- bin. Thats all good but I am confused over the use of linspace
- for the bin creation. I wouldn't have thought that it does
- what is needed, to quote the docstring it creates a "Linear
- spaced array from min to max". For it to work correctly
- shouldn't the values in the bins array be the same bound for
- each bin? (i.e. each value should be the lower bound of a
- bin). To provide the correct bins for hist would it not be
- something like
-
- def bins(xmin, xmax, N):
- if N==1: return xmax
- dx = (xmax-xmin)/N # instead of N-1
- return xmin + dx*arange(N)
-
-
- This suggestion is implemented in 0.81. My test script with these
- changes does not reveal any bias in the binning
-
- from matplotlib.numerix.mlab import randn, rand, zeros, Float
- from matplotlib.mlab import hist, mean
-
- Nbins = 50
- Ntests = 200
- results = zeros((Ntests,Nbins), typecode=Float)
- for i in range(Ntests):
- print 'computing', i
- x = rand(10000)
- n, bins = hist(x, Nbins)
- results[i] = n
- print mean(results)
-
-
-API CHANGES in matplotlib-0.81
-
- - pylab and artist "set" functions renamed to setp to avoid clash
- with python2.4 built-in set. Current version will issue a
- deprecation warning which will be removed in future versions
-
- - imshow interpolation arguments changes for advanced interpolation
- schemes. See help imshow, particularly the interpolation,
- filternorm and filterrad kwargs
-
- - Support for masked arrays has been added to the plot command and
- to the Line2D object. Only the valid points are plotted. A
- "valid_only" kwarg was added to the get_xdata() and get_ydata()
- methods of Line2D; by default it is False, so that the original
- data arrays are returned. Setting it to True returns the plottable
- points.
-
- - contour changes:
-
- Masked arrays: contour and contourf now accept masked arrays as
- the variable to be contoured. Masking works correctly for
- contour, but a bug remains to be fixed before it will work for
- contourf. The "badmask" kwarg has been removed from both
- functions.
-
- Level argument changes:
-
- Old version: a list of levels as one of the positional
- arguments specified the lower bound of each filled region; the
- upper bound of the last region was taken as a very large
- number. Hence, it was not possible to specify that z values
- between 0 and 1, for example, be filled, and that values
- outside that range remain unfilled.
-
- New version: a list of N levels is taken as specifying the
- boundaries of N-1 z ranges. Now the user has more control over
- what is colored and what is not. Repeated calls to...
[truncated message content] |
|
From: <jd...@us...> - 2008-11-20 18:58:57
|
Revision: 6423
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6423&view=rev
Author: jdh2358
Date: 2008-11-20 18:58:54 +0000 (Thu, 20 Nov 2008)
Log Message:
-----------
added some helper functions for poly collections and masked regions
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/collections.py
trunk/matplotlib/lib/matplotlib/mlab.py
trunk/matplotlib/src/_backend_agg.cpp
Added Paths:
-----------
trunk/matplotlib/examples/api/filled_masked_regions.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-11-20 15:46:46 UTC (rev 6422)
+++ trunk/matplotlib/CHANGELOG 2008-11-20 18:58:54 UTC (rev 6423)
@@ -1,3 +1,11 @@
+2008-11-20 Added some static helper methods
+ BrokenHBarCollection.span_masked and
+ PolyCollection.fill_between_masked for visualizing
+ non-masked regions. In the longer term, the better
+ solution will be to fix the relevant classes and functions
+ to handle masked data, so this may be a temporary solution
+ - JDH
+
2008-11-12 Add x_isdata and y_isdata attributes to Artist instances,
and use them to determine whether either or both
coordinates are used when updating dataLim. This is
Added: trunk/matplotlib/examples/api/filled_masked_regions.py
===================================================================
--- trunk/matplotlib/examples/api/filled_masked_regions.py (rev 0)
+++ trunk/matplotlib/examples/api/filled_masked_regions.py 2008-11-20 18:58:54 UTC (rev 6423)
@@ -0,0 +1,45 @@
+"""
+Illustrate some helper functions for shading regions where a logical
+mask is True
+"""
+import numpy as np
+import matplotlib.pyplot as plt
+import matplotlib.collections as collections
+
+
+t = np.arange(0.0, 2, 0.01)
+s = np.sin(2*np.pi*t)
+
+fig = plt.figure()
+ax = fig.add_subplot(111)
+ax.set_title('using fill_between_masked')
+ax.plot(t, s, '-')
+ax.axhline(0, color='black', lw=2)
+
+collection = collections.PolyCollection.fill_between_masked(t, s, s>=0, yboundary=0, color='green', alpha=0.5)
+ax.add_collection(collection)
+
+collection = collections.PolyCollection.fill_between_masked(t, s, s<=0, yboundary=0, color='red', alpha=0.5)
+ax.add_collection(collection)
+
+
+fig = plt.figure()
+ax = fig.add_subplot(111)
+ax.set_title('using span_masked')
+ax.plot(t, s, '-')
+ax.axhline(0, color='black', lw=2)
+
+collection = collections.BrokenBarHCollection.span_masked(t, s>0, ymin=0, ymax=1, facecolor='green', alpha=0.5)
+ax.add_collection(collection)
+
+collection = collections.BrokenBarHCollection.span_masked(t, s<0, ymin=-1, ymax=0, facecolor='red', alpha=0.5)
+ax.add_collection(collection)
+
+
+
+plt.show()
+
+
+
+
+
Modified: trunk/matplotlib/lib/matplotlib/collections.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/collections.py 2008-11-20 15:46:46 UTC (rev 6422)
+++ trunk/matplotlib/lib/matplotlib/collections.py 2008-11-20 18:58:54 UTC (rev 6423)
@@ -19,6 +19,7 @@
import matplotlib.artist as artist
import matplotlib.backend_bases as backend_bases
import matplotlib.path as mpath
+import matplotlib.mlab as mlab
class Collection(artist.Artist, cm.ScalarMappable):
"""
@@ -234,7 +235,7 @@
self._urls = [None,]
else:
self._urls = urls
-
+
def get_urls(self): return self._urls
def set_offsets(self, offsets):
@@ -671,6 +672,49 @@
for x in self._sizes]
return Collection.draw(self, renderer)
+
+ @staticmethod
+ def fill_between_masked(x, y, mask, yboundary=0, **kwargs):
+ """
+ Create a :class:`PolyCollection` filling the regions between *y*
+ and *yboundary7* where ``mask==True``
+
+
+ *x*
+ an N length np array of the x data
+
+ *y*
+ an N length np array of the y data
+
+ *mask*
+ an N length numpy boolean array
+
+ *yboundary*
+ a scalar to fill between *y* and the boundary
+
+ *kwargs*
+ keyword args passed on to the :class:`PolyCollection`
+
+ """
+ polys = []
+ for ind0, ind1 in mlab.contiguous_regions(mask):
+ theseverts = []
+ xslice = x[ind0:ind1]
+ yslice = y[ind0:ind1]
+ N = len(xslice)
+ X = np.zeros((2*N+2, 2), np.float)
+ X[0] = xslice[0], yboundary
+ X[N+1] = xslice[-1], yboundary
+ X[1:N+1,0] = xslice
+ X[1:N+1,1] = yslice
+ X[N+2:,0] = xslice[::-1]
+ X[N+2:,1] = yboundary
+
+ polys.append(X)
+
+ collection = PolyCollection(polys, **kwargs)
+ return collection
+
class BrokenBarHCollection(PolyCollection):
"""
A collection of horizontal bars spanning *yrange* with a sequence of
@@ -692,6 +736,25 @@
PolyCollection.__init__(self, verts, **kwargs)
__init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
+
+ @staticmethod
+ def span_masked(x, mask, ymin, ymax, **kwargs):
+ """
+ Create a BrokenBarHCollection to plot horizontal bars from
+ over the regions in *x* where *mask* is True. The bars range
+ on the y-axis from *ymin* to *ymax*
+
+ A :class:`BrokenBarHCollection` is returned.
+ **kwargs are passed on to the collection
+ """
+ xranges = []
+ for ind0, ind1 in mlab.contiguous_regions(mask):
+ xslice = x[ind0:ind1]
+ xranges.append((xslice[0], xslice[-1]-xslice[0]))
+
+ collection = BrokenBarHCollection(xranges, [ymin, ymax-ymin], **kwargs)
+ return collection
+
class RegularPolyCollection(Collection):
"""Draw a collection of regular polygons with *numsides*."""
_path_generator = mpath.Path.unit_regular_polygon
Modified: trunk/matplotlib/lib/matplotlib/mlab.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/mlab.py 2008-11-20 15:46:46 UTC (rev 6422)
+++ trunk/matplotlib/lib/matplotlib/mlab.py 2008-11-20 18:58:54 UTC (rev 6423)
@@ -159,7 +159,7 @@
import csv, warnings, copy, os
import numpy as np
-
+ma = np.ma
from matplotlib import verbose
import matplotlib.nxutils as nxutils
@@ -247,7 +247,7 @@
#The checks for if y is x are so that we can use the same function to
#implement the core of psd(), csd(), and spectrogram() without doing
#extra calculations. We return the unaveraged Pxy, freqs, and t.
-
+
#Make sure we're dealing with a numpy array. If y and x were the same
#object to start with, keep them that way
same_data = y is x
@@ -309,7 +309,7 @@
Pxy /= (np.abs(windowVals)**2).sum()
t = 1./Fs * (ind + NFFT / 2.)
freqs = float(Fs) / pad_to * np.arange(numFreqs)
-
+
return Pxy, freqs, t
#Split out these keyword docs so that they can be used elsewhere
@@ -2104,7 +2104,8 @@
def csv2rec(fname, comments='#', skiprows=0, checkrows=0, delimiter=',',
- converterd=None, names=None, missing='', missingd=None):
+ converterd=None, names=None, missing='', missingd=None,
+ use_mrecords=True):
"""
Load data from comma/space/tab delimited file in *fname* into a
numpy record array and return the record array.
@@ -2139,9 +2140,11 @@
be masked, e.g. '0000-00-00' or 'unused'
- *missing*: a string whose value signals a missing field regardless of
- the column it appears in, e.g. 'unused'
+ the column it appears in
- If no rows are found, *None* is returned -- see :file:`examples/loadrec.py`
+ - *use_mrecords*: if True, return an mrecords.fromrecords record array if any of the data are missing
+
+ If no rows are found, *None* is returned -- see :file:`examples/loadrec.py`
"""
if converterd is None:
@@ -2338,7 +2341,8 @@
if not len(rows):
return None
- if np.any(rowmasks):
+
+ if use_mrecords and np.any(rowmasks):
try: from numpy.ma import mrecords
except ImportError:
raise RuntimeError('numpy 1.05 or later is required for masked array support')
@@ -2938,19 +2942,25 @@
xv, yv = poly_below(0, x, y)
ax.fill(xv, yv)
"""
- xs = np.asarray(xs)
- ys = np.asarray(ys)
+ if ma.isMaskedArray(xs) or ma.isMaskedArray(ys):
+ nx = ma
+ else:
+ nx = np
+
+ xs = nx.asarray(xs)
+ ys = nx.asarray(ys)
Nx = len(xs)
Ny = len(ys)
assert(Nx==Ny)
- x = xmin*np.ones(2*Nx)
- y = np.ones(2*Nx)
+ x = xmin*nx.ones(2*Nx)
+ y = nx.ones(2*Nx)
x[:Nx] = xs
y[:Nx] = ys
y[Nx:] = ys[::-1]
return x, y
+
def poly_between(x, ylower, yupper):
"""
Given a sequence of *x*, *ylower* and *yupper*, return the polygon
@@ -2961,17 +2971,23 @@
Return value is *x*, *y* arrays for use with
:meth:`matplotlib.axes.Axes.fill`.
"""
+ if ma.isMaskedArray(ylower) or ma.isMaskedArray(yupper) or ma.isMaskedArray(x):
+ nx = ma
+ else:
+ nx = np
+
Nx = len(x)
if not cbook.iterable(ylower):
- ylower = ylower*np.ones(Nx)
+ ylower = ylower*nx.ones(Nx)
if not cbook.iterable(yupper):
- yupper = yupper*np.ones(Nx)
+ yupper = yupper*nx.ones(Nx)
- x = np.concatenate( (x, x[::-1]) )
- y = np.concatenate( (yupper, ylower[::-1]) )
+ x = nx.concatenate( (x, x[::-1]) )
+ y = nx.concatenate( (yupper, ylower[::-1]) )
return x,y
+
def is_closed_polygon(X):
"""
Tests whether first and last object in a sequence are the same. These are
@@ -2980,6 +2996,28 @@
"""
return np.all(X[0] == X[-1])
+
+def contiguous_regions(mask):
+ """
+ return a list of (ind0, ind1) such that mask[ind0:ind1].all() is
+ True and we cover all such regions
+
+ TODO: this is a pure python implementation which probably has a much faster numpy impl
+ """
+
+ in_region = None
+ boundaries = []
+ for i, val in enumerate(mask):
+ if in_region is None and val:
+ in_region = i
+ elif in_region is not None and not val:
+ boundaries.append((in_region, i))
+ in_region = None
+
+ if in_region is not None:
+ boundaries.append((in_region, i+1))
+ return boundaries
+
##################################################
# Vector and path length geometry calculations
##################################################
Modified: trunk/matplotlib/src/_backend_agg.cpp
===================================================================
--- trunk/matplotlib/src/_backend_agg.cpp 2008-11-20 15:46:46 UTC (rev 6422)
+++ trunk/matplotlib/src/_backend_agg.cpp 2008-11-20 18:58:54 UTC (rev 6423)
@@ -385,7 +385,8 @@
if (!py_convert_bbox(box_obj.ptr(), l, b, r, t))
throw Py::TypeError("Invalid bbox provided to copy_from_bbox");
- agg::rect_i rect((int)l, height - (int)t, (int)r, height - (int)b);
+ // std::cout << l << " " << b << " " << r << " " << t << " " << (height - (int)b) << " " << height - (int)t << std::endl;
+ agg::rect_i rect((int)l, height - (int)b, (int)r, height - (int)t);
BufferRegion* reg = NULL;
try {
@@ -419,9 +420,11 @@
BufferRegion* region = static_cast<BufferRegion*>(args[0].ptr());
if (region->data==NULL)
- return Py::Object();
- //throw Py::ValueError("Cannot restore_region from NULL data");
+ throw Py::ValueError("Cannot restore_region from NULL data");
+ //return Py::Object();
+ //std::cout << "restoring " << region->width << " " << region->height << " " << region->stride << " " << region->rect.x1 << " " << region->rect.y1 << std::endl;
+
agg::rendering_buffer rbuf;
rbuf.attach(region->data,
region->width,
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2008-11-20 20:22:13
|
Revision: 6424
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6424&view=rev
Author: jdh2358
Date: 2008-11-20 20:22:08 +0000 (Thu, 20 Nov 2008)
Log Message:
-----------
reverted a bug I introduced when toying around with copy region in agg
Modified Paths:
--------------
trunk/matplotlib/examples/event_handling/path_editor.py
trunk/matplotlib/lib/matplotlib/collections.py
trunk/matplotlib/src/_backend_agg.cpp
Modified: trunk/matplotlib/examples/event_handling/path_editor.py
===================================================================
--- trunk/matplotlib/examples/event_handling/path_editor.py 2008-11-20 18:58:54 UTC (rev 6423)
+++ trunk/matplotlib/examples/event_handling/path_editor.py 2008-11-20 20:22:08 UTC (rev 6424)
@@ -1,3 +1,5 @@
+import matplotlib
+matplotlib.use('TkAgg')
import numpy as np
import matplotlib.path as mpath
import matplotlib.patches as mpatches
Modified: trunk/matplotlib/lib/matplotlib/collections.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/collections.py 2008-11-20 18:58:54 UTC (rev 6423)
+++ trunk/matplotlib/lib/matplotlib/collections.py 2008-11-20 20:22:08 UTC (rev 6424)
@@ -701,6 +701,9 @@
theseverts = []
xslice = x[ind0:ind1]
yslice = y[ind0:ind1]
+ if not len(xslice):
+ continue
+
N = len(xslice)
X = np.zeros((2*N+2, 2), np.float)
X[0] = xslice[0], yboundary
@@ -750,6 +753,8 @@
xranges = []
for ind0, ind1 in mlab.contiguous_regions(mask):
xslice = x[ind0:ind1]
+ if not len(xslice):
+ continue
xranges.append((xslice[0], xslice[-1]-xslice[0]))
collection = BrokenBarHCollection(xranges, [ymin, ymax-ymin], **kwargs)
Modified: trunk/matplotlib/src/_backend_agg.cpp
===================================================================
--- trunk/matplotlib/src/_backend_agg.cpp 2008-11-20 18:58:54 UTC (rev 6423)
+++ trunk/matplotlib/src/_backend_agg.cpp 2008-11-20 20:22:08 UTC (rev 6424)
@@ -386,7 +386,7 @@
throw Py::TypeError("Invalid bbox provided to copy_from_bbox");
// std::cout << l << " " << b << " " << r << " " << t << " " << (height - (int)b) << " " << height - (int)t << std::endl;
- agg::rect_i rect((int)l, height - (int)b, (int)r, height - (int)t);
+ agg::rect_i rect((int)l, height - (int)t, (int)r, height - (int)b);
BufferRegion* reg = NULL;
try {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2008-11-21 11:28:35
|
Revision: 6429
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6429&view=rev
Author: jdh2358
Date: 2008-11-21 11:28:32 +0000 (Fri, 21 Nov 2008)
Log Message:
-----------
Merged revisions 6086,6365,6427-6428 via svnmerge from
https://matplotlib.svn.sourceforge.net/svnroot/matplotlib/branches/v0_91_maint
........
r6086 | mdboom | 2008-09-11 15:28:11 -0500 (Thu, 11 Sep 2008) | 2 lines
Fix backticks in PS output.
........
r6365 | mdboom | 2008-11-05 09:15:28 -0600 (Wed, 05 Nov 2008) | 1 line
Fix bug in zoom rectangle with twin axes
........
r6427 | jdh2358 | 2008-11-21 05:14:12 -0600 (Fri, 21 Nov 2008) | 1 line
fixed poly between
........
r6428 | jdh2358 | 2008-11-21 05:15:04 -0600 (Fri, 21 Nov 2008) | 1 line
fixed poly below
........
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/backend_bases.py
trunk/matplotlib/lib/matplotlib/mlab.py
Property Changed:
----------------
trunk/matplotlib/
Property changes on: trunk/matplotlib
___________________________________________________________________
Modified: svnmerge-integrated
- /branches/v0_91_maint:1-6073,6149
+ /branches/v0_91_maint:1-6428
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-11-21 11:15:04 UTC (rev 6428)
+++ trunk/matplotlib/CHANGELOG 2008-11-21 11:28:32 UTC (rev 6429)
@@ -54,6 +54,10 @@
2008-10-08 Add path simplification support to paths with gaps. - EF
+=======
+2008-11-05 Fix bug with zoom to rectangle and twin axes - MGD
+
+>>>>>>> .merge-right.r6428
2008-10-05 Fix problem with AFM files that don't specify the font's
full name or family name. - JKS
@@ -97,6 +101,10 @@
2008-09-10 Add "filled" kwarg to Path.intersects_path and
Path.intersects_bbox. - MGD
+=======
+2008-09-11 Fix use of backticks in PS - MGD
+
+>>>>>>> .merge-right.r6086
2008-09-07 Changed full arrows slightly to avoid an xpdf rendering
problem reported by Friedrich Hagedorn. - JKS
Modified: trunk/matplotlib/lib/matplotlib/backend_bases.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backend_bases.py 2008-11-21 11:15:04 UTC (rev 6428)
+++ trunk/matplotlib/lib/matplotlib/backend_bases.py 2008-11-21 11:28:32 UTC (rev 6429)
@@ -1883,6 +1883,8 @@
for cur_xypress in self._xypress:
x, y = event.x, event.y
lastx, lasty, a, ind, lim, trans = cur_xypress
+ if a._sharex or a._sharey:
+ continue
# ignore singular clicks - 5 pixels is a threshold
if abs(x-lastx)<5 or abs(y-lasty)<5:
self._xypress = None
Modified: trunk/matplotlib/lib/matplotlib/mlab.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/mlab.py 2008-11-21 11:15:04 UTC (rev 6428)
+++ trunk/matplotlib/lib/matplotlib/mlab.py 2008-11-21 11:28:32 UTC (rev 6429)
@@ -1438,6 +1438,181 @@
else: return X
+def slopes(x,y):
+ """
+ SLOPES calculate the slope y'(x) Given data vectors X and Y SLOPES
+ calculates Y'(X), i.e the slope of a curve Y(X). The slope is
+ estimated using the slope obtained from that of a parabola through
+ any three consecutive points.
+
+ This method should be superior to that described in the appendix
+ of A CONSISTENTLY WELL BEHAVED METHOD OF INTERPOLATION by Russel
+ W. Stineman (Creative Computing July 1980) in at least one aspect:
+
+ Circles for interpolation demand a known aspect ratio between x-
+ and y-values. For many functions, however, the abscissa are given
+ in different dimensions, so an aspect ratio is completely
+ arbitrary.
+
+ The parabola method gives very similar results to the circle
+ method for most regular cases but behaves much better in special
+ cases
+
+ Norbert Nemec, Institute of Theoretical Physics, University or
+ Regensburg, April 2006 Norbert.Nemec at physik.uni-regensburg.de
+
+ (inspired by a original implementation by Halldor Bjornsson,
+ Icelandic Meteorological Office, March 2006 halldor at vedur.is)
+ """
+ # Cast key variables as float.
+ x=np.asarray(x, np.float_)
+ y=np.asarray(y, np.float_)
+
+ yp=np.zeros(y.shape, np.float_)
+
+ dx=x[1:] - x[:-1]
+ dy=y[1:] - y[:-1]
+ dydx = dy/dx
+ yp[1:-1] = (dydx[:-1] * dx[1:] + dydx[1:] * dx[:-1])/(dx[1:] + dx[:-1])
+ yp[0] = 2.0 * dy[0]/dx[0] - yp[1]
+ yp[-1] = 2.0 * dy[-1]/dx[-1] - yp[-2]
+ return yp
+
+
+def stineman_interp(xi,x,y,yp=None):
+ """
+ STINEMAN_INTERP Well behaved data interpolation. Given data
+ vectors X and Y, the slope vector YP and a new abscissa vector XI
+ the function stineman_interp(xi,x,y,yp) uses Stineman
+ interpolation to calculate a vector YI corresponding to XI.
+
+ Here's an example that generates a coarse sine curve, then
+ interpolates over a finer abscissa:
+
+ x = linspace(0,2*pi,20); y = sin(x); yp = cos(x)
+ xi = linspace(0,2*pi,40);
+ yi = stineman_interp(xi,x,y,yp);
+ plot(x,y,'o',xi,yi)
+
+ The interpolation method is described in the article A
+ CONSISTENTLY WELL BEHAVED METHOD OF INTERPOLATION by Russell
+ W. Stineman. The article appeared in the July 1980 issue of
+ Creative Computing with a note from the editor stating that while
+ they were
+
+ not an academic journal but once in a while something serious
+ and original comes in adding that this was
+ "apparently a real solution" to a well known problem.
+
+ For yp=None, the routine automatically determines the slopes using
+ the "slopes" routine.
+
+ X is assumed to be sorted in increasing order
+
+ For values xi[j] < x[0] or xi[j] > x[-1], the routine tries a
+ extrapolation. The relevance of the data obtained from this, of
+ course, questionable...
+
+ original implementation by Halldor Bjornsson, Icelandic
+ Meteorolocial Office, March 2006 halldor at vedur.is
+
+ completely reworked and optimized for Python by Norbert Nemec,
+ Institute of Theoretical Physics, University or Regensburg, April
+ 2006 Norbert.Nemec at physik.uni-regensburg.de
+
+ """
+
+ # Cast key variables as float.
+ x=np.asarray(x, np.float_)
+ y=np.asarray(y, np.float_)
+ assert x.shape == y.shape
+ N=len(y)
+
+ if yp is None:
+ yp = slopes(x,y)
+ else:
+ yp=np.asarray(yp, np.float_)
+
+ xi=np.asarray(xi, np.float_)
+ yi=np.zeros(xi.shape, np.float_)
+
+ # calculate linear slopes
+ dx = x[1:] - x[:-1]
+ dy = y[1:] - y[:-1]
+ s = dy/dx #note length of s is N-1 so last element is #N-2
+
+ # find the segment each xi is in
+ # this line actually is the key to the efficiency of this implementation
+ idx = np.searchsorted(x[1:-1], xi)
+
+ # now we have generally: x[idx[j]] <= xi[j] <= x[idx[j]+1]
+ # except at the boundaries, where it may be that xi[j] < x[0] or xi[j] > x[-1]
+
+ # the y-values that would come out from a linear interpolation:
+ sidx = s.take(idx)
+ xidx = x.take(idx)
+ yidx = y.take(idx)
+ xidxp1 = x.take(idx+1)
+ yo = yidx + sidx * (xi - xidx)
+
+ # the difference that comes when using the slopes given in yp
+ dy1 = (yp.take(idx)- sidx) * (xi - xidx) # using the yp slope of the left point
+ dy2 = (yp.take(idx+1)-sidx) * (xi - xidxp1) # using the yp slope of the right point
+
+ dy1dy2 = dy1*dy2
+ # The following is optimized for Python. The solution actually
+ # does more calculations than necessary but exploiting the power
+ # of numpy, this is far more efficient than coding a loop by hand
+ # in Python
+ yi = yo + dy1dy2 * np.choose(np.array(np.sign(dy1dy2), np.int32)+1,
+ ((2*xi-xidx-xidxp1)/((dy1-dy2)*(xidxp1-xidx)),
+ 0.0,
+ 1/(dy1+dy2),))
+ return yi
+
+def inside_poly(points, verts):
+ """
+ points is a sequence of x,y points
+ verts is a sequence of x,y vertices of a poygon
+
+ return value is a sequence of indices into points for the points
+ that are inside the polygon
+ """
+ res, = np.nonzero(nxutils.points_inside_poly(points, verts))
+ return res
+
+def poly_below(ymin, xs, ys):
+ """
+ given a arrays *xs* and *ys*, return the vertices of a polygon
+ that has a scalar lower bound *ymin* and an upper bound at the *ys*.
+
+ intended for use with Axes.fill, eg::
+
+ xv, yv = poly_below(0, x, y)
+ ax.fill(xv, yv)
+ """
+ return poly_between(xs, ys, xmin)
+
+
+def poly_between(x, ylower, yupper):
+ """
+ given a sequence of x, ylower and yupper, return the polygon that
+ fills the regions between them. ylower or yupper can be scalar or
+ iterable. If they are iterable, they must be equal in length to x
+
+ return value is x, y arrays for use with Axes.fill
+ """
+ Nx = len(x)
+ if not cbook.iterable(ylower):
+ ylower = ylower*np.ones(Nx)
+
+ if not cbook.iterable(yupper):
+ yupper = yupper*np.ones(Nx)
+
+ x = np.concatenate( (x, x[::-1]) )
+ y = np.concatenate( (yupper, ylower[::-1]) )
+ return x,y
+
### the following code was written and submitted by Fernando Perez
### from the ipython numutils package under a BSD license
# begin fperez functions
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2008-11-23 19:04:40
|
Revision: 6432
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6432&view=rev
Author: jdh2358
Date: 2008-11-23 19:04:35 +0000 (Sun, 23 Nov 2008)
Log Message:
-----------
generalized fill between poly collection
Modified Paths:
--------------
trunk/matplotlib/examples/api/filled_masked_regions.py
trunk/matplotlib/lib/matplotlib/collections.py
Modified: trunk/matplotlib/examples/api/filled_masked_regions.py
===================================================================
--- trunk/matplotlib/examples/api/filled_masked_regions.py 2008-11-21 18:20:00 UTC (rev 6431)
+++ trunk/matplotlib/examples/api/filled_masked_regions.py 2008-11-23 19:04:35 UTC (rev 6432)
@@ -8,31 +8,36 @@
t = np.arange(0.0, 2, 0.01)
-s = np.sin(2*np.pi*t)
+s1 = np.sin(2*np.pi*t)
+s2 = 1.2*np.sin(4*np.pi*t)
fig = plt.figure()
ax = fig.add_subplot(111)
-ax.set_title('using fill_between_masked')
-ax.plot(t, s, '-')
+ax.set_title('using fill_between_where')
+ax.plot(t, s1, t, s2)
ax.axhline(0, color='black', lw=2)
-collection = collections.PolyCollection.fill_between_masked(t, s, s>=0, yboundary=0, color='green', alpha=0.5)
+collection = collections.PolyCollection.fill_between_where(
+ t, s1, s2, s1>=s2, color='green', alpha=0.5)
ax.add_collection(collection)
-collection = collections.PolyCollection.fill_between_masked(t, s, s<=0, yboundary=0, color='red', alpha=0.5)
+collection = collections.PolyCollection.fill_between_where(
+ t, s1, s2, s1<=s2, color='red', alpha=0.5)
ax.add_collection(collection)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_title('using span_masked')
-ax.plot(t, s, '-')
+ax.plot(t, s1, '-')
ax.axhline(0, color='black', lw=2)
-collection = collections.BrokenBarHCollection.span_masked(t, s>0, ymin=0, ymax=1, facecolor='green', alpha=0.5)
+collection = collections.BrokenBarHCollection.span_masked(
+ t, s1>0, ymin=0, ymax=1, facecolor='green', alpha=0.5)
ax.add_collection(collection)
-collection = collections.BrokenBarHCollection.span_masked(t, s<0, ymin=-1, ymax=0, facecolor='red', alpha=0.5)
+collection = collections.BrokenBarHCollection.span_masked(
+ t, s1<0, ymin=-1, ymax=0, facecolor='red', alpha=0.5)
ax.add_collection(collection)
Modified: trunk/matplotlib/lib/matplotlib/collections.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/collections.py 2008-11-21 18:20:00 UTC (rev 6431)
+++ trunk/matplotlib/lib/matplotlib/collections.py 2008-11-23 19:04:35 UTC (rev 6432)
@@ -674,7 +674,7 @@
@staticmethod
- def fill_between_masked(x, y, mask, yboundary=0, **kwargs):
+ def fill_between_where(x, y1, y2, mask, **kwargs):
"""
Create a :class:`PolyCollection` filling the regions between *y*
and *yboundary7* where ``mask==True``
@@ -683,35 +683,50 @@
*x*
an N length np array of the x data
- *y*
- an N length np array of the y data
+ *y1*
+ an N length scalar or np array of the x data
+ *y2*
+ an N length scalar or np array of the x data
+
*mask*
an N length numpy boolean array
- *yboundary*
- a scalar to fill between *y* and the boundary
-
*kwargs*
keyword args passed on to the :class:`PolyCollection`
"""
+ if not cbook.iterable(y1):
+ y1 = np.ones_like(x)*y1
+
+ if not cbook.iterable(y2):
+ y2 = np.ones_like(x)*y2
+
+ assert( (len(x)==len(y1)) and (len(x)==len(y2)) )
+
polys = []
for ind0, ind1 in mlab.contiguous_regions(mask):
theseverts = []
xslice = x[ind0:ind1]
- yslice = y[ind0:ind1]
+ y1slice = y1[ind0:ind1]
+ y2slice = y2[ind0:ind1]
+
if not len(xslice):
continue
N = len(xslice)
X = np.zeros((2*N+2, 2), np.float)
- X[0] = xslice[0], yboundary
- X[N+1] = xslice[-1], yboundary
+
+ # the purpose of the next two lines is for when y2 is a
+ # scalar like 0 and we want the fill to go all the way
+ # down to 0 even if none of the y1 sample points do
+ X[0] = xslice[0], y2slice[0]
+ X[N+1] = xslice[-1], y2slice[-1]
+
X[1:N+1,0] = xslice
- X[1:N+1,1] = yslice
+ X[1:N+1,1] = y1slice
X[N+2:,0] = xslice[::-1]
- X[N+2:,1] = yboundary
+ X[N+2:,1] = y2slice[::-1]
polys.append(X)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2008-11-23 19:06:02
|
Revision: 6433
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6433&view=rev
Author: jdh2358
Date: 2008-11-23 19:05:58 +0000 (Sun, 23 Nov 2008)
Log Message:
-----------
renamed fill where examples
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
Added Paths:
-----------
trunk/matplotlib/examples/api/fill_where_demo.py
Removed Paths:
-------------
trunk/matplotlib/examples/api/filled_masked_regions.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-11-23 19:04:35 UTC (rev 6432)
+++ trunk/matplotlib/CHANGELOG 2008-11-23 19:05:58 UTC (rev 6433)
@@ -1,10 +1,7 @@
2008-11-20 Added some static helper methods
BrokenHBarCollection.span_masked and
- PolyCollection.fill_between_masked for visualizing
- non-masked regions. In the longer term, the better
- solution will be to fix the relevant classes and functions
- to handle masked data, so this may be a temporary solution
- - JDH
+ PolyCollection.fill_between_where for visualizing logical
+ regions. See examples/api/fill_where_demo.py - JDH
2008-11-12 Add x_isdata and y_isdata attributes to Artist instances,
and use them to determine whether either or both
Copied: trunk/matplotlib/examples/api/fill_where_demo.py (from rev 6432, trunk/matplotlib/examples/api/filled_masked_regions.py)
===================================================================
--- trunk/matplotlib/examples/api/fill_where_demo.py (rev 0)
+++ trunk/matplotlib/examples/api/fill_where_demo.py 2008-11-23 19:05:58 UTC (rev 6433)
@@ -0,0 +1,50 @@
+"""
+Illustrate some helper functions for shading regions where a logical
+mask is True
+"""
+import numpy as np
+import matplotlib.pyplot as plt
+import matplotlib.collections as collections
+
+
+t = np.arange(0.0, 2, 0.01)
+s1 = np.sin(2*np.pi*t)
+s2 = 1.2*np.sin(4*np.pi*t)
+
+fig = plt.figure()
+ax = fig.add_subplot(111)
+ax.set_title('using fill_between_where')
+ax.plot(t, s1, t, s2)
+ax.axhline(0, color='black', lw=2)
+
+collection = collections.PolyCollection.fill_between_where(
+ t, s1, s2, s1>=s2, color='green', alpha=0.5)
+ax.add_collection(collection)
+
+collection = collections.PolyCollection.fill_between_where(
+ t, s1, s2, s1<=s2, color='red', alpha=0.5)
+ax.add_collection(collection)
+
+
+fig = plt.figure()
+ax = fig.add_subplot(111)
+ax.set_title('using span_masked')
+ax.plot(t, s1, '-')
+ax.axhline(0, color='black', lw=2)
+
+collection = collections.BrokenBarHCollection.span_masked(
+ t, s1>0, ymin=0, ymax=1, facecolor='green', alpha=0.5)
+ax.add_collection(collection)
+
+collection = collections.BrokenBarHCollection.span_masked(
+ t, s1<0, ymin=-1, ymax=0, facecolor='red', alpha=0.5)
+ax.add_collection(collection)
+
+
+
+plt.show()
+
+
+
+
+
Deleted: trunk/matplotlib/examples/api/filled_masked_regions.py
===================================================================
--- trunk/matplotlib/examples/api/filled_masked_regions.py 2008-11-23 19:04:35 UTC (rev 6432)
+++ trunk/matplotlib/examples/api/filled_masked_regions.py 2008-11-23 19:05:58 UTC (rev 6433)
@@ -1,50 +0,0 @@
-"""
-Illustrate some helper functions for shading regions where a logical
-mask is True
-"""
-import numpy as np
-import matplotlib.pyplot as plt
-import matplotlib.collections as collections
-
-
-t = np.arange(0.0, 2, 0.01)
-s1 = np.sin(2*np.pi*t)
-s2 = 1.2*np.sin(4*np.pi*t)
-
-fig = plt.figure()
-ax = fig.add_subplot(111)
-ax.set_title('using fill_between_where')
-ax.plot(t, s1, t, s2)
-ax.axhline(0, color='black', lw=2)
-
-collection = collections.PolyCollection.fill_between_where(
- t, s1, s2, s1>=s2, color='green', alpha=0.5)
-ax.add_collection(collection)
-
-collection = collections.PolyCollection.fill_between_where(
- t, s1, s2, s1<=s2, color='red', alpha=0.5)
-ax.add_collection(collection)
-
-
-fig = plt.figure()
-ax = fig.add_subplot(111)
-ax.set_title('using span_masked')
-ax.plot(t, s1, '-')
-ax.axhline(0, color='black', lw=2)
-
-collection = collections.BrokenBarHCollection.span_masked(
- t, s1>0, ymin=0, ymax=1, facecolor='green', alpha=0.5)
-ax.add_collection(collection)
-
-collection = collections.BrokenBarHCollection.span_masked(
- t, s1<0, ymin=-1, ymax=0, facecolor='red', alpha=0.5)
-ax.add_collection(collection)
-
-
-
-plt.show()
-
-
-
-
-
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2008-11-23 19:15:04
|
Revision: 6434
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6434&view=rev
Author: jdh2358
Date: 2008-11-23 19:15:01 +0000 (Sun, 23 Nov 2008)
Log Message:
-----------
updated api for fill_between_where and span_where
Modified Paths:
--------------
trunk/matplotlib/examples/api/fill_where_demo.py
trunk/matplotlib/lib/matplotlib/collections.py
Modified: trunk/matplotlib/examples/api/fill_where_demo.py
===================================================================
--- trunk/matplotlib/examples/api/fill_where_demo.py 2008-11-23 19:05:58 UTC (rev 6433)
+++ trunk/matplotlib/examples/api/fill_where_demo.py 2008-11-23 19:15:01 UTC (rev 6434)
@@ -1,6 +1,9 @@
"""
Illustrate some helper functions for shading regions where a logical
mask is True
+
+See :meth:`matplotlib.collections.PolyCollection.fill_between_where`
+and :meth:`matplotlib.collections.BrokenBarHCollection.span_where`
"""
import numpy as np
import matplotlib.pyplot as plt
@@ -18,26 +21,26 @@
ax.axhline(0, color='black', lw=2)
collection = collections.PolyCollection.fill_between_where(
- t, s1, s2, s1>=s2, color='green', alpha=0.5)
+ t, s1, s2, where=s1>=s2, color='green', alpha=0.5)
ax.add_collection(collection)
collection = collections.PolyCollection.fill_between_where(
- t, s1, s2, s1<=s2, color='red', alpha=0.5)
+ t, s1, s2, where=s1<=s2, color='red', alpha=0.5)
ax.add_collection(collection)
fig = plt.figure()
ax = fig.add_subplot(111)
-ax.set_title('using span_masked')
+ax.set_title('using span_where')
ax.plot(t, s1, '-')
ax.axhline(0, color='black', lw=2)
-collection = collections.BrokenBarHCollection.span_masked(
- t, s1>0, ymin=0, ymax=1, facecolor='green', alpha=0.5)
+collection = collections.BrokenBarHCollection.span_where(
+ t, ymin=0, ymax=1, where=s1>0, facecolor='green', alpha=0.5)
ax.add_collection(collection)
-collection = collections.BrokenBarHCollection.span_masked(
- t, s1<0, ymin=-1, ymax=0, facecolor='red', alpha=0.5)
+collection = collections.BrokenBarHCollection.span_where(
+ t, ymin=-1, ymax=0, where=s1<0, facecolor='red', alpha=0.5)
ax.add_collection(collection)
Modified: trunk/matplotlib/lib/matplotlib/collections.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/collections.py 2008-11-23 19:05:58 UTC (rev 6433)
+++ trunk/matplotlib/lib/matplotlib/collections.py 2008-11-23 19:15:01 UTC (rev 6434)
@@ -674,10 +674,10 @@
@staticmethod
- def fill_between_where(x, y1, y2, mask, **kwargs):
+ def fill_between_where(x, y1, y2, where, **kwargs):
"""
Create a :class:`PolyCollection` filling the regions between *y*
- and *yboundary7* where ``mask==True``
+ and *yboundary7* where ``where==True``
*x*
@@ -689,7 +689,7 @@
*y2*
an N length scalar or np array of the x data
- *mask*
+ *where*
an N length numpy boolean array
*kwargs*
@@ -705,7 +705,7 @@
assert( (len(x)==len(y1)) and (len(x)==len(y2)) )
polys = []
- for ind0, ind1 in mlab.contiguous_regions(mask):
+ for ind0, ind1 in mlab.contiguous_regions(where):
theseverts = []
xslice = x[ind0:ind1]
y1slice = y1[ind0:ind1]
@@ -756,17 +756,17 @@
@staticmethod
- def span_masked(x, mask, ymin, ymax, **kwargs):
+ def span_where(x, ymin, ymax, where, **kwargs):
"""
Create a BrokenBarHCollection to plot horizontal bars from
- over the regions in *x* where *mask* is True. The bars range
+ over the regions in *x* where *where* is True. The bars range
on the y-axis from *ymin* to *ymax*
A :class:`BrokenBarHCollection` is returned.
**kwargs are passed on to the collection
"""
xranges = []
- for ind0, ind1 in mlab.contiguous_regions(mask):
+ for ind0, ind1 in mlab.contiguous_regions(where):
xslice = x[ind0:ind1]
if not len(xslice):
continue
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2008-11-23 19:56:41
|
Revision: 6437
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6437&view=rev
Author: jdh2358
Date: 2008-11-23 19:56:37 +0000 (Sun, 23 Nov 2008)
Log Message:
-----------
moved fill_between to axes/pyplot method
Modified Paths:
--------------
trunk/matplotlib/boilerplate.py
trunk/matplotlib/doc/_templates/index.html
trunk/matplotlib/examples/api/fill_where_demo.py
trunk/matplotlib/examples/pylab_examples/fill_between.py
trunk/matplotlib/lib/matplotlib/axes.py
trunk/matplotlib/lib/matplotlib/collections.py
trunk/matplotlib/lib/matplotlib/pyplot.py
Added Paths:
-----------
trunk/matplotlib/examples/api/span_regions.py
Modified: trunk/matplotlib/boilerplate.py
===================================================================
--- trunk/matplotlib/boilerplate.py 2008-11-23 19:18:24 UTC (rev 6436)
+++ trunk/matplotlib/boilerplate.py 2008-11-23 19:56:37 UTC (rev 6437)
@@ -64,6 +64,7 @@
'csd',
'errorbar',
'fill',
+ 'fill_between',
'hexbin',
'hist',
'hlines',
Modified: trunk/matplotlib/doc/_templates/index.html
===================================================================
--- trunk/matplotlib/doc/_templates/index.html 2008-11-23 19:18:24 UTC (rev 6436)
+++ trunk/matplotlib/doc/_templates/index.html 2008-11-23 19:56:37 UTC (rev 6437)
@@ -409,8 +409,21 @@
</td>
</tr>
+
<tr>
<th align="left">
+ <a href="api/pyplot_api.html#matplotlib.pyplot.fill_between">fill_between</a>
+
+ </th>
+
+ <td align="left">
+ make filled polygons between two curves
+ </td>
+
+ </tr>
+
+ <tr>
+ <th align="left">
<a href="api/pyplot_api.html#matplotlib.pyplot.findobj">findobj</a>
</th>
Modified: trunk/matplotlib/examples/api/fill_where_demo.py
===================================================================
--- trunk/matplotlib/examples/api/fill_where_demo.py 2008-11-23 19:18:24 UTC (rev 6436)
+++ trunk/matplotlib/examples/api/fill_where_demo.py 2008-11-23 19:56:37 UTC (rev 6437)
@@ -17,7 +17,7 @@
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_title('using fill_between_where')
-ax.plot(t, s1, t, s2)
+ax.plot(t, s1, t, s2, color='black')
ax.axhline(0, color='black', lw=2)
collection = collections.PolyCollection.fill_between_where(
@@ -32,7 +32,7 @@
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_title('using span_where')
-ax.plot(t, s1, '-')
+ax.plot(t, s1, , color='black')
ax.axhline(0, color='black', lw=2)
collection = collections.BrokenBarHCollection.span_where(
Added: trunk/matplotlib/examples/api/span_regions.py
===================================================================
--- trunk/matplotlib/examples/api/span_regions.py (rev 0)
+++ trunk/matplotlib/examples/api/span_regions.py 2008-11-23 19:56:37 UTC (rev 6437)
@@ -0,0 +1,38 @@
+"""
+Illustrate some helper functions for shading regions where a logical
+mask is True
+
+See :meth:`matplotlib.collections.BrokenBarHCollection.span_where`
+"""
+import numpy as np
+import matplotlib.pyplot as plt
+import matplotlib.collections as collections
+
+
+t = np.arange(0.0, 2, 0.01)
+s1 = np.sin(2*np.pi*t)
+s2 = 1.2*np.sin(4*np.pi*t)
+
+
+fig = plt.figure()
+ax = fig.add_subplot(111)
+ax.set_title('using span_where')
+ax.plot(t, s1, color='black')
+ax.axhline(0, color='black', lw=2)
+
+collection = collections.BrokenBarHCollection.span_where(
+ t, ymin=0, ymax=1, where=s1>0, facecolor='green', alpha=0.5)
+ax.add_collection(collection)
+
+collection = collections.BrokenBarHCollection.span_where(
+ t, ymin=-1, ymax=0, where=s1<0, facecolor='red', alpha=0.5)
+ax.add_collection(collection)
+
+
+
+plt.show()
+
+
+
+
+
Modified: trunk/matplotlib/examples/pylab_examples/fill_between.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/fill_between.py 2008-11-23 19:18:24 UTC (rev 6436)
+++ trunk/matplotlib/examples/pylab_examples/fill_between.py 2008-11-23 19:56:37 UTC (rev 6437)
@@ -3,27 +3,31 @@
from pylab import figure, show
import numpy as np
-x = np.arange(0, 2, 0.01)
+x = np.arange(0.0, 2, 0.01)
y1 = np.sin(2*np.pi*x)
-y2 = np.sin(4*np.pi*x) + 2
+y2 = 1.2*np.sin(4*np.pi*x)
fig = figure()
-ax = fig.add_subplot(311)
-ax2 = fig.add_subplot(312)
-ax3 = fig.add_subplot(313)
+ax1 = fig.add_subplot(311)
+ax2 = fig.add_subplot(312, sharex=ax1)
+ax3 = fig.add_subplot(313, sharex=ax1)
+ax1.fill_between(x, 0, y1)
+ax1.set_ylabel('between y1 and 0')
-xs, ys = mlab.poly_between(x, 0, y1)
-ax.fill(xs, ys)
-ax.set_ylabel('between y1 and 0')
-
-xs, ys = mlab.poly_between(x, y1, 1)
-ax2.fill(xs, ys)
+ax2.fill_between(x, y1, 1)
ax2.set_ylabel('between y1 and 1')
-xs, ys = mlab.poly_between(x, y1, y2)
-ax3.fill(xs, ys)
+ax3.fill_between(x, y1, y2)
ax3.set_ylabel('between y1 and y2')
ax3.set_xlabel('x')
+
+fig = figure()
+ax = fig.add_subplot(111)
+ax1.plot(x, y1, x, y2, color='black')
+ax.fill_between(x, y1, y2, where=y2>y1, facecolor='green')
+ax.fill_between(x, y1, y2, where=y2<=y1, facecolor='red')
+ax.set_title('fill between where')
+
show()
Modified: trunk/matplotlib/lib/matplotlib/axes.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/axes.py 2008-11-23 19:18:24 UTC (rev 6436)
+++ trunk/matplotlib/lib/matplotlib/axes.py 2008-11-23 19:56:37 UTC (rev 6437)
@@ -1302,6 +1302,7 @@
if autolim:
if collection._paths and len(collection._paths):
self.update_datalim(collection.get_datalim(self.transData))
+
collection._remove_method = lambda h: self.collections.remove(h)
def add_line(self, line):
@@ -5456,12 +5457,8 @@
supports are supported by the fill format string.
If you would like to fill below a curve, eg. shade a region
- between 0 and *y* along *x*, use
- :func:`~matplotlib.pylab.poly_between`, eg.::
+ between 0 and *y* along *x*, use :meth:`fill_between`
- xs, ys = poly_between(x, 0, y)
- axes.fill(xs, ys, facecolor='red', alpha=0.5)
-
The *closed* kwarg will close the polygon when *True* (default).
kwargs control the Polygon properties:
@@ -5472,9 +5469,6 @@
.. plot:: mpl_examples/pylab_examples/fill_demo.py
- .. seealso::
- :file:`examples/pylab_examples/fill_between.py`:
- For more examples.
"""
if not self._hold: self.cla()
@@ -5486,6 +5480,92 @@
return patches
fill.__doc__ = cbook.dedent(fill.__doc__) % martist.kwdocd
+ def fill_between(self, x, y1, y2=0, where=None, **kwargs):
+ """
+ call signature::
+
+ fill_between(x, y1, y2=0, where=None, **kwargs)
+
+ Create a :class:`~matplotlib.collectionsPolyCollection`
+ filling the regions between *y1* and *y2* where
+ ``where==True``
+
+ *x*
+ an N length np array of the x data
+
+ *y1*
+ an N length scalar or np array of the x data
+
+ *y2*
+ an N length scalar or np array of the x data
+
+ *where*
+ if None, default to fill between everywhere. If not None,
+ it is a a N length numpy boolean array and the fill will
+ only happen over the regions where ``where==True``
+
+ *kwargs*
+ keyword args passed on to the :class:`PolyCollection`
+
+ .. seealso::
+ :file:`examples/pylab_examples/fill_between.py`:
+ For more examples.
+
+ kwargs control the Polygon properties:
+
+ %(PolyCollection)s
+
+ """
+ x = np.asarray(x)
+ if not cbook.iterable(y1):
+ y1 = np.ones_like(x)*y1
+
+ if not cbook.iterable(y2):
+ y2 = np.ones_like(x)*y2
+
+ if where is None:
+ where = np.ones(len(x), np.bool)
+
+ y1 = np.asarray(y1)
+ y2 = np.asarray(y2)
+ where = np.asarray(where)
+ assert( (len(x)==len(y1)) and (len(x)==len(y2)) and len(x)==len(where))
+
+ polys = []
+ for ind0, ind1 in mlab.contiguous_regions(where):
+ theseverts = []
+ xslice = x[ind0:ind1]
+ y1slice = y1[ind0:ind1]
+ y2slice = y2[ind0:ind1]
+
+ if not len(xslice):
+ continue
+
+ N = len(xslice)
+ X = np.zeros((2*N+2, 2), np.float)
+
+ # the purpose of the next two lines is for when y2 is a
+ # scalar like 0 and we want the fill to go all the way
+ # down to 0 even if none of the y1 sample points do
+ X[0] = xslice[0], y2slice[0]
+ X[N+1] = xslice[-1], y2slice[-1]
+
+ X[1:N+1,0] = xslice
+ X[1:N+1,1] = y1slice
+ X[N+2:,0] = xslice[::-1]
+ X[N+2:,1] = y2slice[::-1]
+
+ polys.append(X)
+
+ collection = mcoll.PolyCollection(polys, **kwargs)
+
+ self.update_datalim_numerix(x[where], y1[where])
+ self.update_datalim_numerix(x[where], y2[where])
+ self.add_collection(collection)
+ self.autoscale_view()
+ return collection
+ fill_between.__doc__ = cbook.dedent(fill_between.__doc__) % martist.kwdocd
+
#### plotting z(x,y): imshow, pcolor and relatives, contour
def imshow(self, X, cmap=None, norm=None, aspect=None,
Modified: trunk/matplotlib/lib/matplotlib/collections.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/collections.py 2008-11-23 19:18:24 UTC (rev 6436)
+++ trunk/matplotlib/lib/matplotlib/collections.py 2008-11-23 19:56:37 UTC (rev 6437)
@@ -673,66 +673,6 @@
return Collection.draw(self, renderer)
- @staticmethod
- def fill_between_where(x, y1, y2, where, **kwargs):
- """
- Create a :class:`PolyCollection` filling the regions between *y*
- and *yboundary7* where ``where==True``
-
-
- *x*
- an N length np array of the x data
-
- *y1*
- an N length scalar or np array of the x data
-
- *y2*
- an N length scalar or np array of the x data
-
- *where*
- an N length numpy boolean array
-
- *kwargs*
- keyword args passed on to the :class:`PolyCollection`
-
- """
- if not cbook.iterable(y1):
- y1 = np.ones_like(x)*y1
-
- if not cbook.iterable(y2):
- y2 = np.ones_like(x)*y2
-
- assert( (len(x)==len(y1)) and (len(x)==len(y2)) )
-
- polys = []
- for ind0, ind1 in mlab.contiguous_regions(where):
- theseverts = []
- xslice = x[ind0:ind1]
- y1slice = y1[ind0:ind1]
- y2slice = y2[ind0:ind1]
-
- if not len(xslice):
- continue
-
- N = len(xslice)
- X = np.zeros((2*N+2, 2), np.float)
-
- # the purpose of the next two lines is for when y2 is a
- # scalar like 0 and we want the fill to go all the way
- # down to 0 even if none of the y1 sample points do
- X[0] = xslice[0], y2slice[0]
- X[N+1] = xslice[-1], y2slice[-1]
-
- X[1:N+1,0] = xslice
- X[1:N+1,1] = y1slice
- X[N+2:,0] = xslice[::-1]
- X[N+2:,1] = y2slice[::-1]
-
- polys.append(X)
-
- collection = PolyCollection(polys, **kwargs)
- return collection
-
class BrokenBarHCollection(PolyCollection):
"""
A collection of horizontal bars spanning *yrange* with a sequence of
Modified: trunk/matplotlib/lib/matplotlib/pyplot.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/pyplot.py 2008-11-23 19:18:24 UTC (rev 6436)
+++ trunk/matplotlib/lib/matplotlib/pyplot.py 2008-11-23 19:56:37 UTC (rev 6437)
@@ -1120,61 +1120,62 @@
"""
Plotting commands
- ========= =================================================
- Command Description
- ========= =================================================
- axes Create a new axes
- axis Set or return the current axis limits
- bar make a bar chart
- boxplot make a box and whiskers chart
- cla clear current axes
- clabel label a contour plot
- clf clear a figure window
- close close a figure window
- colorbar add a colorbar to the current figure
- cohere make a plot of coherence
- contour make a contour plot
- contourf make a filled contour plot
- csd make a plot of cross spectral density
- draw force a redraw of the current figure
- errorbar make an errorbar graph
- figlegend add a legend to the figure
- figimage add an image to the figure, w/o resampling
- figtext add text in figure coords
- figure create or change active figure
- fill make filled polygons
- gca return the current axes
- gcf return the current figure
- gci get the current image, or None
- getp get a handle graphics property
- hist make a histogram
- hold set the hold state on current axes
- legend add a legend to the axes
- loglog a log log plot
- imread load image file into array
- imshow plot image data
- matshow display a matrix in a new figure preserving aspect
- pcolor make a pseudocolor plot
- plot make a line plot
- plotfile plot data from a flat file
- psd make a plot of power spectral density
- quiver make a direction field (arrows) plot
- rc control the default params
- savefig save the current figure
- scatter make a scatter plot
- setp set a handle graphics property
- semilogx log x axis
- semilogy log y axis
- show show the figures
- specgram a spectrogram plot
- stem make a stem plot
- subplot make a subplot (numrows, numcols, axesnum)
- table add a table to the axes
- text add some text at location x,y to the current axes
- title add a title to the current axes
- xlabel add an xlabel to the current axes
- ylabel add a ylabel to the current axes
- ========= =================================================
+ ========= =================================================
+ Command Description
+ ========= =================================================
+ axes Create a new axes
+ axis Set or return the current axis limits
+ bar make a bar chart
+ boxplot make a box and whiskers chart
+ cla clear current axes
+ clabel label a contour plot
+ clf clear a figure window
+ close close a figure window
+ colorbar add a colorbar to the current figure
+ cohere make a plot of coherence
+ contour make a contour plot
+ contourf make a filled contour plot
+ csd make a plot of cross spectral density
+ draw force a redraw of the current figure
+ errorbar make an errorbar graph
+ figlegend add a legend to the figure
+ figimage add an image to the figure, w/o resampling
+ figtext add text in figure coords
+ figure create or change active figure
+ fill make filled polygons
+ fill_between make filled polygons
+ gca return the current axes
+ gcf return the current figure
+ gci get the current image, or None
+ getp get a handle graphics property
+ hist make a histogram
+ hold set the hold state on current axes
+ legend add a legend to the axes
+ loglog a log log plot
+ imread load image file into array
+ imshow plot image data
+ matshow display a matrix in a new figure preserving aspect
+ pcolor make a pseudocolor plot
+ plot make a line plot
+ plotfile plot data from a flat file
+ psd make a plot of power spectral density
+ quiver make a direction field (arrows) plot
+ rc control the default params
+ savefig save the current figure
+ scatter make a scatter plot
+ setp set a handle graphics property
+ semilogx log x axis
+ semilogy log y axis
+ show show the figures
+ specgram a spectrogram plot
+ stem make a stem plot
+ subplot make a subplot (numrows, numcols, axesnum)
+ table add a table to the axes
+ text add some text at location x,y to the current axes
+ title add a title to the current axes
+ xlabel add an xlabel to the current axes
+ ylabel add a ylabel to the current axes
+ ========= =================================================
The following commands will set the default colormap accordingly:
@@ -1493,7 +1494,6 @@
## Plotting part 2: autogenerated wrappers for axes methods ##
-### Do not edit below this point
# This function was autogenerated by boilerplate.py. Do not edit as
# changes will be lost
def acorr(*args, **kwargs):
@@ -1870,6 +1870,50 @@
# This function was autogenerated by boilerplate.py. Do not edit as
# changes will be lost
+def fill_between(*args, **kwargs):
+ # allow callers to override the hold state by passing hold=True|False
+ b = ishold()
+ h = kwargs.pop('hold', None)
+ if h is not None:
+ hold(h)
+ try:
+ ret = gca().fill_between(*args, **kwargs)
+ draw_if_interactive()
+ except:
+ hold(b)
+ raise
+
+ hold(b)
+ return ret
+if Axes.fill_between.__doc__ is not None:
+ fill_between.__doc__ = dedent(Axes.fill_between.__doc__) + """
+
+Additional kwargs: hold = [True|False] overrides default hold state"""
+
+# This function was autogenerated by boilerplate.py. Do not edit as
+# changes will be lost
+def hexbin(*args, **kwargs):
+ # allow callers to override the hold state by passing hold=True|False
+ b = ishold()
+ h = kwargs.pop('hold', None)
+ if h is not None:
+ hold(h)
+ try:
+ ret = gca().hexbin(*args, **kwargs)
+ draw_if_interactive()
+ except:
+ hold(b)
+ raise
+ gci._current = ret
+ hold(b)
+ return ret
+if Axes.hexbin.__doc__ is not None:
+ hexbin.__doc__ = dedent(Axes.hexbin.__doc__) + """
+
+Additional kwargs: hold = [True|False] overrides default hold state"""
+
+# This function was autogenerated by boilerplate.py. Do not edit as
+# changes will be lost
def hist(*args, **kwargs):
# allow callers to override the hold state by passing hold=True|False
b = ishold()
@@ -2156,28 +2200,6 @@
# This function was autogenerated by boilerplate.py. Do not edit as
# changes will be lost
-def hexbin(*args, **kwargs):
- # allow callers to override the hold state by passing hold=True|False
- b = ishold()
- h = kwargs.pop('hold', None)
- if h is not None:
- hold(h)
- try:
- ret = gca().hexbin(*args, **kwargs)
- draw_if_interactive()
- except:
- hold(b)
- raise
- gci._current = ret
- hold(b)
- return ret
-if Axes.hexbin.__doc__ is not None:
- hexbin.__doc__ = dedent(Axes.hexbin.__doc__) + """
-
-Additional kwargs: hold = [True|False] overrides default hold state"""
-
-# This function was autogenerated by boilerplate.py. Do not edit as
-# changes will be lost
def semilogx(*args, **kwargs):
# allow callers to override the hold state by passing hold=True|False
b = ishold()
@@ -2438,10 +2460,8 @@
# changes will be lost
def autumn():
'''
- Set the default colormap to *autumn* and apply to current image if any.
-
- .. seealso::
- :func:`colormaps`
+ set the default colormap to autumn and apply to current image if any.
+ See help(colormaps) for more information
'''
rc('image', cmap='autumn')
im = gci()
@@ -2455,10 +2475,8 @@
# changes will be lost
def bone():
'''
- Set the default colormap to bone and apply to current image if any.
-
- .. seealso::
- :func:`colormaps`
+ set the default colormap to bone and apply to current image if any.
+ See help(colormaps) for more information
'''
rc('image', cmap='bone')
im = gci()
@@ -2472,10 +2490,8 @@
# changes will be lost
def cool():
'''
- Set the default colormap to cool and apply to current image if any.
-
- .. seealso::
- :func:`colormaps`
+ set the default colormap to cool and apply to current image if any.
+ See help(colormaps) for more information
'''
rc('image', cmap='cool')
im = gci()
@@ -2489,10 +2505,8 @@
# changes will be lost
def copper():
'''
- Set the default colormap to copper and apply to current image if any.
-
- .. seealso::
- :func:`colormaps`
+ set the default colormap to copper and apply to current image if any.
+ See help(colormaps) for more information
'''
rc('image', cmap='copper')
im = gci()
@@ -2506,10 +2520,8 @@
# changes will be lost
def flag():
'''
- Set the default colormap to flag and apply to current image if any.
-
- .. seealso::
- :func:`colormaps`
+ set the default colormap to flag and apply to current image if any.
+ See help(colormaps) for more information
'''
rc('image', cmap='flag')
im = gci()
@@ -2523,10 +2535,8 @@
# changes will be lost
def gray():
'''
- Set the default colormap to gray and apply to current image if any.
-
- .. seealso::
- :func:`colormaps`
+ set the default colormap to gray and apply to current image if any.
+ See help(colormaps) for more information
'''
rc('image', cmap='gray')
im = gci()
@@ -2540,10 +2550,8 @@
# changes will be lost
def hot():
'''
- Set the default colormap to hot and apply to current image if any.
-
- .. seealso::
- :func:`colormaps`
+ set the default colormap to hot and apply to current image if any.
+ See help(colormaps) for more information
'''
rc('image', cmap='hot')
im = gci()
@@ -2557,10 +2565,8 @@
# changes will be lost
def hsv():
'''
- Set the default colormap to hsv and apply to current image if any.
-
- .. seealso::
- :func:`colormaps`
+ set the default colormap to hsv and apply to current image if any.
+ See help(colormaps) for more information
'''
rc('image', cmap='hsv')
im = gci()
@@ -2574,10 +2580,8 @@
# changes will be lost
def jet():
'''
- Set the default colormap to jet and apply to current image if any.
-
- .. seealso::
- :func:`colormaps`
+ set the default colormap to jet and apply to current image if any.
+ See help(colormaps) for more information
'''
rc('image', cmap='jet')
im = gci()
@@ -2591,10 +2595,8 @@
# changes will be lost
def pink():
'''
- Set the default colormap to pink and apply to current image if any.
-
- .. seealso::
- :func:`colormaps`
+ set the default colormap to pink and apply to current image if any.
+ See help(colormaps) for more information
'''
rc('image', cmap='pink')
im = gci()
@@ -2608,10 +2610,8 @@
# changes will be lost
def prism():
'''
- Set the default colormap to prism and apply to current image if any.
-
- .. seealso::
- :func:`colormaps`
+ set the default colormap to prism and apply to current image if any.
+ See help(colormaps) for more information
'''
rc('image', cmap='prism')
im = gci()
@@ -2625,10 +2625,8 @@
# changes will be lost
def spring():
'''
- Set the default colormap to spring and apply to current image if any.
-
- .. seealso::
- :func:`colormaps`
+ set the default colormap to spring and apply to current image if any.
+ See help(colormaps) for more information
'''
rc('image', cmap='spring')
im = gci()
@@ -2642,10 +2640,8 @@
# changes will be lost
def summer():
'''
- Set the default colormap to summer and apply to current image if any.
-
- .. seealso::
- :func:`colormaps`
+ set the default colormap to summer and apply to current image if any.
+ See help(colormaps) for more information
'''
rc('image', cmap='summer')
im = gci()
@@ -2659,10 +2655,8 @@
# changes will be lost
def winter():
'''
- Set the default colormap to winter and apply to current image if any.
-
- .. seealso::
- :func:`colormaps`
+ set the default colormap to winter and apply to current image if any.
+ See help(colormaps) for more information
'''
rc('image', cmap='winter')
im = gci()
@@ -2676,10 +2670,8 @@
# changes will be lost
def spectral():
'''
- Set the default colormap to spectral and apply to current image if any.
-
- .. seealso::
- :func:`colormaps`
+ set the default colormap to spectral and apply to current image if any.
+ See help(colormaps) for more information
'''
rc('image', cmap='spectral')
im = gci()
@@ -2687,3 +2679,5 @@
if im is not None:
im.set_cmap(cm.spectral)
draw_if_interactive()
+
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2008-11-24 20:12:59
|
Revision: 6442
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6442&view=rev
Author: mdboom
Date: 2008-11-24 20:12:55 +0000 (Mon, 24 Nov 2008)
Log Message:
-----------
[ 2314869 ] Log base-2 axes fail with certain axis limits
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/ticker.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-11-24 03:53:14 UTC (rev 6441)
+++ trunk/matplotlib/CHANGELOG 2008-11-24 20:12:55 UTC (rev 6442)
@@ -1,3 +1,5 @@
+2008-11-24 Fix crash in log ticking. - MGD
+
2008-11-20 Added some static helper methods
BrokenHBarCollection.span_masked and
PolyCollection.fill_between_where for visualizing logical
Modified: trunk/matplotlib/lib/matplotlib/ticker.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/ticker.py 2008-11-24 03:53:14 UTC (rev 6441)
+++ trunk/matplotlib/lib/matplotlib/ticker.py 2008-11-24 20:12:55 UTC (rev 6442)
@@ -1037,7 +1037,7 @@
decades = np.arange(math.floor(vmin),
math.ceil(vmax)+stride, stride)
- if len(subs) > 1 or subs[0] != 1.0:
+ if len(subs) > 1 or (len(subs == 1) and subs[0] != 1.0):
ticklocs = []
for decadeStart in b**decades:
ticklocs.extend( subs*decadeStart )
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2008-11-25 04:04:05
|
Revision: 6445
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6445&view=rev
Author: jdh2358
Date: 2008-11-25 04:03:59 +0000 (Tue, 25 Nov 2008)
Log Message:
-----------
point to the right url for the rc file
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/doc/_templates/gallery.html
trunk/matplotlib/doc/_templates/indexsidebar.html
trunk/matplotlib/doc/make.py
trunk/matplotlib/doc/users/customizing.rst
trunk/matplotlib/lib/matplotlib/__init__.py
trunk/matplotlib/matplotlibrc.template
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-11-24 20:18:38 UTC (rev 6444)
+++ trunk/matplotlib/CHANGELOG 2008-11-25 04:03:59 UTC (rev 6445)
@@ -1,9 +1,8 @@
2008-11-24 Fix crash in log ticking. - MGD
-2008-11-20 Added some static helper methods
- BrokenHBarCollection.span_masked and
- PolyCollection.fill_between_where for visualizing logical
- regions. See examples/api/fill_where_demo.py - JDH
+2008-11-20 Added static helper method BrokenHBarCollection.span_where
+ and Axes/pyplot method fill_between. See
+ examples/pylab/fill_between.py - JDH
2008-11-12 Add x_isdata and y_isdata attributes to Artist instances,
and use them to determine whether either or both
Modified: trunk/matplotlib/doc/_templates/gallery.html
===================================================================
--- trunk/matplotlib/doc/_templates/gallery.html 2008-11-24 20:18:38 UTC (rev 6444)
+++ trunk/matplotlib/doc/_templates/gallery.html 2008-11-25 04:03:59 UTC (rev 6445)
@@ -49,6 +49,8 @@
<a href="examples/api/scatter_piecharts.html"><img src="_static/plot_directive/mpl_examples/api/thumbnails/scatter_piecharts.png" border="0" alt="scatter_piecharts"/></a>
+<a href="examples/api/span_regions.html"><img src="_static/plot_directive/mpl_examples/api/thumbnails/span_regions.png" border="0" alt="span_regions"/></a>
+
<a href="examples/api/two_scales.html"><img src="_static/plot_directive/mpl_examples/api/thumbnails/two_scales.png" border="0" alt="two_scales"/></a>
<a href="examples/api/watermark_image.html"><img src="_static/plot_directive/mpl_examples/api/thumbnails/watermark_image.png" border="0" alt="watermark_image"/></a>
@@ -157,6 +159,8 @@
<a href="examples/pylab_examples/csd_demo.html"><img src="_static/plot_directive/mpl_examples/pylab_examples/thumbnails/csd_demo.png" border="0" alt="csd_demo"/></a>
+<a href="examples/pylab_examples/custom_cmap.html"><img src="_static/plot_directive/mpl_examples/pylab_examples/thumbnails/custom_cmap.png" border="0" alt="custom_cmap"/></a>
+
<a href="examples/pylab_examples/custom_figure_class.html"><img src="_static/plot_directive/mpl_examples/pylab_examples/thumbnails/custom_figure_class.png" border="0" alt="custom_figure_class"/></a>
<a href="examples/pylab_examples/custom_ticker1.html"><img src="_static/plot_directive/mpl_examples/pylab_examples/thumbnails/custom_ticker1.png" border="0" alt="custom_ticker1"/></a>
@@ -223,9 +227,9 @@
<a href="examples/pylab_examples/figure_title.html"><img src="_static/plot_directive/mpl_examples/pylab_examples/thumbnails/figure_title.png" border="0" alt="figure_title"/></a>
-<a href="examples/pylab_examples/fill_between.html"><img src="_static/plot_directive/mpl_examples/pylab_examples/thumbnails/fill_between.png" border="0" alt="fill_between"/></a>
+<a href="examples/pylab_examples/fill_between.html"><img src="_static/plot_directive/mpl_examples/pylab_examples/thumbnails/fill_between_00.png" border="0" alt="fill_between"/></a>
-<a href="examples/pylab_examples/fill_between_posneg.html"><img src="_static/plot_directive/mpl_examples/pylab_examples/thumbnails/fill_between_posneg.png" border="0" alt="fill_between_posneg"/></a>
+<a href="examples/pylab_examples/fill_between.html"><img src="_static/plot_directive/mpl_examples/pylab_examples/thumbnails/fill_between_01.png" border="0" alt="fill_between"/></a>
<a href="examples/pylab_examples/fill_demo.html"><img src="_static/plot_directive/mpl_examples/pylab_examples/thumbnails/fill_demo.png" border="0" alt="fill_demo"/></a>
@@ -419,6 +423,8 @@
<a href="examples/pylab_examples/psd_demo.html"><img src="_static/plot_directive/mpl_examples/pylab_examples/thumbnails/psd_demo.png" border="0" alt="psd_demo"/></a>
+<a href="examples/pylab_examples/psd_demo2.html"><img src="_static/plot_directive/mpl_examples/pylab_examples/thumbnails/psd_demo2.png" border="0" alt="psd_demo2"/></a>
+
<a href="examples/pylab_examples/pythonic_matplotlib.html"><img src="_static/plot_directive/mpl_examples/pylab_examples/thumbnails/pythonic_matplotlib.png" border="0" alt="pythonic_matplotlib"/></a>
<a href="examples/pylab_examples/quadmesh_demo.html"><img src="_static/plot_directive/mpl_examples/pylab_examples/thumbnails/quadmesh_demo.png" border="0" alt="quadmesh_demo"/></a>
Modified: trunk/matplotlib/doc/_templates/indexsidebar.html
===================================================================
--- trunk/matplotlib/doc/_templates/indexsidebar.html 2008-11-24 20:18:38 UTC (rev 6444)
+++ trunk/matplotlib/doc/_templates/indexsidebar.html 2008-11-25 04:03:59 UTC (rev 6445)
@@ -33,7 +33,7 @@
<p>For details on what's new, see the detailed <a href="{{
pathto('_static/CHANGELOG', 1) }}">changelog</a>. Anything that could
-required changes to your existing codes is logged in the <a href="{{
+require changes to your existing codes is logged in the <a href="{{
pathto('api/api_changes.html', 1) }}">api changes</a> file.</p>
<h3>Other stuff</h3>
Modified: trunk/matplotlib/doc/make.py
===================================================================
--- trunk/matplotlib/doc/make.py 2008-11-24 20:18:38 UTC (rev 6444)
+++ trunk/matplotlib/doc/make.py 2008-11-25 04:03:59 UTC (rev 6445)
@@ -17,9 +17,6 @@
def sf():
'push a copy to the sf site'
shutil.copy('../CHANGELOG', 'build/html/_static/CHANGELOG')
- shutil.copy('../API_CHANGES', 'build/html/_static/API_CHANGES')
- shutil.copy('../MIGRATION.txt', 'build/html/_static/MIGRATION.txt')
-
os.system('cd build/html; rsync -avz . jdh2358,mat...@we...:/home/groups/m/ma/matplotlib/htdocs/ -essh --cvs-exclude')
def sfpdf():
@@ -44,6 +41,7 @@
check_build()
if not os.path.exists('examples/index.rst'):
examples()
+ shutil.copy('mpl_data/matplotlibrc', '_static/matplotlibrc')
#figs()
if os.system('sphinx-build -b html -d build/doctrees . build/html'):
raise SystemExit("Building HTML failed.")
Modified: trunk/matplotlib/doc/users/customizing.rst
===================================================================
--- trunk/matplotlib/doc/users/customizing.rst 2008-11-24 20:18:38 UTC (rev 6444)
+++ trunk/matplotlib/doc/users/customizing.rst 2008-11-25 04:03:59 UTC (rev 6445)
@@ -61,6 +61,10 @@
.. _matplotlibrc-sample:
A sample matplotlibrc file
---------------------------
+--------------------------------------------------------------------
+.. htmlonly::
+
+ `(download) <../_static/matplotlibrc>`__
+
.. literalinclude:: ../mpl_data/matplotlibrc
Modified: trunk/matplotlib/lib/matplotlib/__init__.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/__init__.py 2008-11-24 20:18:38 UTC (rev 6444)
+++ trunk/matplotlib/lib/matplotlib/__init__.py 2008-11-25 04:03:59 UTC (rev 6445)
@@ -666,7 +666,7 @@
Bad key "%s" on line %d in
%s.
You probably need to get an updated matplotlibrc file from
-http://matplotlib.sf.net/matplotlibrc or from the matplotlib source
+http://matplotlib.sf.net/_static/matplotlibrc or from the matplotlib source
distribution""" % (key, cnt, fname)
if ret['datapath'] is None:
Modified: trunk/matplotlib/matplotlibrc.template
===================================================================
--- trunk/matplotlib/matplotlibrc.template 2008-11-24 20:18:38 UTC (rev 6444)
+++ trunk/matplotlib/matplotlibrc.template 2008-11-25 04:03:59 UTC (rev 6445)
@@ -10,13 +10,16 @@
# (win32 systems).
#
# This file is best viewed in a editor which supports python mode
-# syntax highlighting # Blank lines, or lines starting with a comment
+# syntax highlighting. Blank lines, or lines starting with a comment
# symbol, are ignored, as are trailing comments. Other lines must
-# have the format # key : val # optional comment # Colors: for the
-# color values below, you can either use - a matplotlib color string,
-# such as r, k, or b - an rgb tuple, such as (1.0, 0.5, 0.0) - a hex
-# string, such as ff00ff or #ff00ff - a scalar grayscale intensity
-# such as 0.75 - a legal html color name, eg red, blue, darkslategray
+# have the format
+# key : val # optional comment
+#
+# Colors: for the color values below, you can either use - a
+# matplotlib color string, such as r, k, or b - an rgb tuple, such as
+# (1.0, 0.5, 0.0) - a hex string, such as ff00ff or #ff00ff - a scalar
+# grayscale intensity such as 0.75 - a legal html color name, eg red,
+# blue, darkslategray
#### CONFIGURATION BEGINS HERE
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <lee...@us...> - 2008-11-25 18:57:02
|
Revision: 6448
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6448&view=rev
Author: leejjoon
Date: 2008-11-25 18:56:57 +0000 (Tue, 25 Nov 2008)
Log Message:
-----------
scatterpoints support in Legend. patch by Erik Tollerud
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/legend.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-11-25 18:28:13 UTC (rev 6447)
+++ trunk/matplotlib/CHANGELOG 2008-11-25 18:56:57 UTC (rev 6448)
@@ -1,3 +1,6 @@
+2008-11-25 Added scatterpoints support in Legend. patch by Erik
+ Tollerud - JJL
+
2008-11-24 Fix crash in log ticking. - MGD
2008-11-20 Added static helper method BrokenHBarCollection.span_where
Modified: trunk/matplotlib/lib/matplotlib/legend.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/legend.py 2008-11-25 18:28:13 UTC (rev 6447)
+++ trunk/matplotlib/lib/matplotlib/legend.py 2008-11-25 18:56:57 UTC (rev 6448)
@@ -83,6 +83,7 @@
def __init__(self, parent, handles, labels,
loc = None,
numpoints = None, # the number of points in the legend line
+ scatterpoints = 3, # TODO: may be an rcParam
prop = None,
pad = None, # the fractional whitespace inside the legend border
borderpad = None,
@@ -101,6 +102,7 @@
labels # a list of strings to label the legend
loc # a location code
numpoints = 4 # the number of points in the legend line
+ scatterpoints = 3 # the number of points for the scatterplot legend
prop = FontProperties(size='smaller') # the font property
pad = 0.2 # the fractional whitespace inside the legend border
markerscale = 0.6 # the relative size of legend markers vs. original
@@ -118,10 +120,10 @@
Artist.__init__(self)
- proplist=[numpoints, pad, borderpad, markerscale, labelsep,
+ proplist=[numpoints, scatterpoints, pad, borderpad, markerscale, labelsep,
handlelen, handletextsep, axespad, shadow]
- propnames=['numpoints', 'pad', 'borderpad', 'markerscale', 'labelsep',
- 'handlelen', 'handletextsep', 'axespad', 'shadow']
+ propnames=['numpoints','scatterpoints', 'pad', 'borderpad', 'markerscale',
+ 'labelsep', 'handlelen', 'handletextsep', 'axespad', 'shadow']
for name, value in safezip(propnames,proplist):
if value is None:
value=rcParams["legend."+name]
@@ -130,7 +132,9 @@
warnings.warn("Use 'borderpad' instead of 'pad'.", DeprecationWarning)
# 2008/10/04
if self.numpoints <= 0:
- raise ValueError("numpoints must be >= 0; it was %d"% numpoints)
+ raise ValueError("numpoints must be > 0; it was %d"% numpoints)
+ if self.scatterpoints <= 0:
+ raise ValueError("scatterpoints must be > 0; it was %d"% numpoints)
if prop is None:
self.prop=FontProperties(size=rcParams["legend.fontsize"])
else:
@@ -142,8 +146,8 @@
self._scatteryoffsets = np.array([4./8., 5./8., 3./8.])
else:
self._scatteryoffsets = np.asarray(scatteryoffsets)
- reps = int(self.numpoints / len(self._scatteryoffsets)) + 1
- self._scatteryoffsets = np.tile(self._scatteryoffsets, reps)[:self.numpoints]
+ reps = int(self.scatterpoints / len(self._scatteryoffsets)) + 1
+ self._scatteryoffsets = np.tile(self._scatteryoffsets, reps)[:self.scatterpoints]
if isinstance(parent,Axes):
self.isaxes = True
@@ -261,10 +265,14 @@
# centered marker proxy
for handle, label in safezip(handles, texts):
- if self.numpoints > 1:
- xdata = np.linspace(left, left + self.handlelen, self.numpoints)
+ if isinstance(handle, RegularPolyCollection):
+ npoints = self.scatterpoints
+ else:
+ npoints = self.numpoints
+ if npoints > 1:
+ xdata = np.linspace(left, left + self.handlelen, npoints)
xdata_marker = xdata
- elif self.numpoints == 1:
+ elif npoints == 1:
xdata = np.linspace(left, left + self.handlelen, 2)
xdata_marker = [left + 0.5*self.handlelen]
@@ -326,8 +334,11 @@
# we may need to scale these sizes by "markerscale"
# attribute. But other handle types does not seem
# to care about this attribute and it is currently ignored.
- sizes = [.5*(size_max+size_min), size_max,
- size_min]
+ if self.scatterpoints < 4:
+ sizes = [.5*(size_max+size_min), size_max,
+ size_min]
+ else:
+ sizes = size_max*np.linspace(0,1,self.scatterpoints)+size_min
p = type(handle)(handle.get_numsides(),
rotation=handle.get_rotation(),
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2008-11-25 22:22:52
|
Revision: 6453
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6453&view=rev
Author: jdh2358
Date: 2008-11-25 21:43:36 +0000 (Tue, 25 Nov 2008)
Log Message:
-----------
added rc param axes.unicode_minus
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/projections/polar.py
trunk/matplotlib/lib/matplotlib/rcsetup.py
trunk/matplotlib/lib/matplotlib/ticker.py
trunk/matplotlib/matplotlibrc.template
Added Paths:
-----------
trunk/matplotlib/examples/api/unicode_minus.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-11-25 21:14:13 UTC (rev 6452)
+++ trunk/matplotlib/CHANGELOG 2008-11-25 21:43:36 UTC (rev 6453)
@@ -1,3 +1,6 @@
+2008-11-25 Added rcParam axes.unicode_minus which allows plain hypen
+ for minus when False - JDH
+
2008-11-25 Added scatterpoints support in Legend. patch by Erik
Tollerud - JJL
Added: trunk/matplotlib/examples/api/unicode_minus.py
===================================================================
--- trunk/matplotlib/examples/api/unicode_minus.py (rev 0)
+++ trunk/matplotlib/examples/api/unicode_minus.py 2008-11-25 21:43:36 UTC (rev 6453)
@@ -0,0 +1,18 @@
+"""
+You can use the proper typesetting unicode minus (see
+http://en.wikipedia.org/wiki/Plus_sign#Plus_sign) or the ASCII hypen
+for minus, which some people prefer. The matplotlibrc param
+axes.unicode_minus controls the default behavior.
+
+The default is to use the unicode minus
+"""
+import numpy as np
+import matplotlib
+import matplotlib.pyplot as plt
+
+matplotlib.rcParams['axes.unicode_minus'] = False
+fig = plt.figure()
+ax = fig.add_subplot(111)
+ax.plot(10*np.random.randn(100), 10*np.random.randn(100), 'o')
+ax.set_title('Using hypen instead of unicode minus')
+plt.show()
Modified: trunk/matplotlib/lib/matplotlib/projections/polar.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/projections/polar.py 2008-11-25 21:14:13 UTC (rev 6452)
+++ trunk/matplotlib/lib/matplotlib/projections/polar.py 2008-11-25 21:43:36 UTC (rev 6453)
@@ -139,6 +139,11 @@
if rcParams['text.usetex'] and not rcParams['text.latex.unicode']:
return r"$%d^\circ$" % ((x / npy.pi) * 180.0)
else:
+ # we use unicode, rather than mathtext with \circ, so
+ # that it will work correctly with any arbitrary font
+ # (assuming it has a degree sign), whereas $5\circ$
+ # will only work correctly with one of the supported
+ # math fonts (Computer Modern and STIX)
return u"%d\u00b0" % ((x / npy.pi) * 180.0)
class RadialLocator(Locator):
Modified: trunk/matplotlib/lib/matplotlib/rcsetup.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/rcsetup.py 2008-11-25 21:14:13 UTC (rev 6452)
+++ trunk/matplotlib/lib/matplotlib/rcsetup.py 2008-11-25 21:43:36 UTC (rev 6453)
@@ -412,6 +412,7 @@
# use scientific notation if log10
# of the axis range is smaller than the
# first or larger than the second
+ 'axes.unicode_minus' : [True, validate_bool],
'polaraxes.grid' : [True, validate_bool], # display polar grid or not
Modified: trunk/matplotlib/lib/matplotlib/ticker.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/ticker.py 2008-11-25 21:14:13 UTC (rev 6452)
+++ trunk/matplotlib/lib/matplotlib/ticker.py 2008-11-25 21:43:36 UTC (rev 6453)
@@ -313,7 +313,7 @@
def fix_minus(self, s):
'use a unicode minus rather than hyphen'
- if rcParams['text.usetex']: return s
+ if rcParams['text.usetex'] or not rcParams['axes.unicode_minus']: return s
else: return s.replace('-', u'\u2212')
def __call__(self, x, pos=None):
Modified: trunk/matplotlib/matplotlibrc.template
===================================================================
--- trunk/matplotlib/matplotlibrc.template 2008-11-25 21:14:13 UTC (rev 6452)
+++ trunk/matplotlib/matplotlibrc.template 2008-11-25 21:43:36 UTC (rev 6453)
@@ -205,6 +205,8 @@
#axes.formatter.limits : -7, 7 # use scientific notation if log10
# of the axis range is smaller than the
# first or larger than the second
+#axes.unicode_minus : True # use unicode for the minus symbol
+ # rather than hypen. See http://en.wikipedia.org/wiki/Plus_sign#Plus_sign
#polaraxes.grid : True # display grid on polar axes
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2008-11-26 17:43:12
|
Revision: 6454
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6454&view=rev
Author: jdh2358
Date: 2008-11-26 17:43:09 +0000 (Wed, 26 Nov 2008)
Log Message:
-----------
added figure/axes enter/leave events
Modified Paths:
--------------
trunk/matplotlib/doc/users/event_handling.rst
trunk/matplotlib/lib/matplotlib/backend_bases.py
Added Paths:
-----------
trunk/matplotlib/examples/event_handling/figure_axes_enter_leave.py
Modified: trunk/matplotlib/doc/users/event_handling.rst
===================================================================
--- trunk/matplotlib/doc/users/event_handling.rst 2008-11-25 21:43:36 UTC (rev 6453)
+++ trunk/matplotlib/doc/users/event_handling.rst 2008-11-26 17:43:09 UTC (rev 6454)
@@ -53,15 +53,19 @@
======================= ======================================================================================
Event name Class and description
======================= ======================================================================================
-'button_press_event' :class:`~matplotlib.backend_bases.MouseEvent` - mouse button is pressed
-'button_release_event' :class:`~matplotlib.backend_bases.MouseEvent` - mouse button is released
-'draw_event' :class:`~matplotlib.backend_bases.DrawEvent` - canvas draw
-'key_press_event' :class:`~matplotlib.backend_bases.KeyEvent` - key is pressed
-'key_release_event' :class:`~matplotlib.backend_bases.KeyEvent` - key is released
-'motion_notify_event' :class:`~matplotlib.backend_bases.MouseEvent` - mouse motion
-'pick_event' :class:`~matplotlib.backend_bases.PickEvent` - an object in the canvas is selected
-'resize_event' :class:`~matplotlib.backend_bases.ResizeEvent` - figure canvas is resized
-'scroll_event' :class:`~matplotlib.backend_bases.MouseEvent` - mouse scroll wheel is rolled
+'button_press_event' :class:`~matplotlib.backend_bases.MouseEvent` - mouse button is pressed
+'button_release_event' :class:`~matplotlib.backend_bases.MouseEvent` - mouse button is released
+'draw_event' :class:`~matplotlib.backend_bases.DrawEvent` - canvas draw
+'key_press_event' :class:`~matplotlib.backend_bases.KeyEvent` - key is pressed
+'key_release_event' :class:`~matplotlib.backend_bases.KeyEvent` - key is released
+'motion_notify_event' :class:`~matplotlib.backend_bases.MouseEvent` - mouse motion
+'pick_event' :class:`~matplotlib.backend_bases.PickEvent` - an object in the canvas is selected
+'resize_event' :class:`~matplotlib.backend_bases.ResizeEvent` - figure canvas is resized
+'scroll_event' :class:`~matplotlib.backend_bases.MouseEvent` - mouse scroll wheel is rolled
+'figure_enter_event' :class:`~matplotlib.backend_bases.LocationEvent` - mouse enters a new figure
+'figure_leave_event' :class:`~matplotlib.backend_bases.LocationEvent` - mouse leaves a figure
+'axes_enter_event' :class:`~matplotlib.backend_bases.LocationEvent` - mouse enters a new axes
+'axes_leave_event' :class:`~matplotlib.backend_bases.LocationEvent` - mouse leaves an axes
======================= ======================================================================================
.. _event-attributes:
@@ -330,6 +334,66 @@
plt.show()
+.. _enter-leave-events:
+
+Mouse enter and leave
+======================
+
+If you want to be notified when the mouse enters or leaves a figure or
+axes, you can connect to the figure/axes enter/leave events. Here is
+a simple example that changes the colors of the axes and figure
+background that the mouse is over::
+
+ """
+ Illustrate the figure and axes enter and leave events by changing the
+ frame colors on enter and leave
+ """
+ import matplotlib.pyplot as plt
+
+ def enter_axes(event):
+ print 'enter_axes', event.inaxes
+ event.inaxes.patch.set_facecolor('yellow')
+ event.canvas.draw()
+
+ def leave_axes(event):
+ print 'leave_axes', event.inaxes
+ event.inaxes.patch.set_facecolor('white')
+ event.canvas.draw()
+
+ def enter_figure(event):
+ print 'enter_figure', event.canvas.figure
+ event.canvas.figure.patch.set_facecolor('red')
+ event.canvas.draw()
+
+ def leave_figure(event):
+ print 'leave_figure', event.canvas.figure
+ event.canvas.figure.patch.set_facecolor('grey')
+ event.canvas.draw()
+
+ fig1 = plt.figure()
+ fig1.suptitle('mouse hover over figure or axes to trigger events')
+ ax1 = fig1.add_subplot(211)
+ ax2 = fig1.add_subplot(212)
+
+ fig1.canvas.mpl_connect('figure_enter_event', enter_figure)
+ fig1.canvas.mpl_connect('figure_leave_event', leave_figure)
+ fig1.canvas.mpl_connect('axes_enter_event', enter_axes)
+ fig1.canvas.mpl_connect('axes_leave_event', leave_axes)
+
+ fig2 = plt.figure()
+ fig2.suptitle('mouse hover over figure or axes to trigger events')
+ ax1 = fig2.add_subplot(211)
+ ax2 = fig2.add_subplot(212)
+
+ fig2.canvas.mpl_connect('figure_enter_event', enter_figure)
+ fig2.canvas.mpl_connect('figure_leave_event', leave_figure)
+ fig2.canvas.mpl_connect('axes_enter_event', enter_axes)
+ fig2.canvas.mpl_connect('axes_leave_event', leave_axes)
+
+ plt.show()
+
+
+
.. _object-picking:
Object picking
Added: trunk/matplotlib/examples/event_handling/figure_axes_enter_leave.py
===================================================================
--- trunk/matplotlib/examples/event_handling/figure_axes_enter_leave.py (rev 0)
+++ trunk/matplotlib/examples/event_handling/figure_axes_enter_leave.py 2008-11-26 17:43:09 UTC (rev 6454)
@@ -0,0 +1,49 @@
+"""
+Illustrate the figure and axes enter and leave events by changing the
+frame colors on enter and leave
+"""
+import matplotlib.pyplot as plt
+
+def enter_axes(event):
+ print 'enter_axes', event.inaxes
+ event.inaxes.patch.set_facecolor('yellow')
+ event.canvas.draw()
+
+def leave_axes(event):
+ print 'leave_axes', event.inaxes
+ event.inaxes.patch.set_facecolor('white')
+ event.canvas.draw()
+
+def enter_figure(event):
+ print 'enter_figure', event.canvas.figure
+ event.canvas.figure.patch.set_facecolor('red')
+ event.canvas.draw()
+
+def leave_figure(event):
+ print 'leave_figure', event.canvas.figure
+ event.canvas.figure.patch.set_facecolor('grey')
+ event.canvas.draw()
+
+fig1 = plt.figure()
+fig1.suptitle('mouse hover over figure or axes to trigger events')
+ax1 = fig1.add_subplot(211)
+ax2 = fig1.add_subplot(212)
+
+fig1.canvas.mpl_connect('figure_enter_event', enter_figure)
+fig1.canvas.mpl_connect('figure_leave_event', leave_figure)
+fig1.canvas.mpl_connect('axes_enter_event', enter_axes)
+fig1.canvas.mpl_connect('axes_leave_event', leave_axes)
+
+fig2 = plt.figure()
+fig2.suptitle('mouse hover over figure or axes to trigger events')
+ax1 = fig2.add_subplot(211)
+ax2 = fig2.add_subplot(212)
+
+fig2.canvas.mpl_connect('figure_enter_event', enter_figure)
+fig2.canvas.mpl_connect('figure_leave_event', leave_figure)
+fig2.canvas.mpl_connect('axes_enter_event', enter_axes)
+fig2.canvas.mpl_connect('axes_leave_event', leave_axes)
+
+plt.show()
+
+
Modified: trunk/matplotlib/lib/matplotlib/backend_bases.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backend_bases.py 2008-11-25 21:43:36 UTC (rev 6453)
+++ trunk/matplotlib/lib/matplotlib/backend_bases.py 2008-11-26 17:43:09 UTC (rev 6454)
@@ -743,6 +743,9 @@
xdata = None # x coord of mouse in data coords
ydata = None # y coord of mouse in data coords
+ # the last event that was triggered before this one
+ _lastevent = None
+
def __init__(self, name, canvas, x, y,guiEvent=None):
"""
*x*, *y* in figure coords, 0,0 = bottom, left
@@ -751,8 +754,12 @@
self.x = x
self.y = y
+
+
if x is None or y is None:
# cannot check if event was in axes if no x,y info
+ self.inaxes = False
+ self._update_enter_leave()
return
# Find all axes containing the mouse
@@ -760,6 +767,7 @@
if len(axes_list) == 0: # None found
self.inaxes = None
+ self._update_enter_leave()
return
elif (len(axes_list) > 1): # Overlap, get the highest zorder
axCmp = lambda _x,_y: cmp(_x.zorder, _y.zorder)
@@ -777,6 +785,36 @@
self.xdata = xdata
self.ydata = ydata
+ self._update_enter_leave()
+
+ def _update_enter_leave(self):
+ 'process the figure/axes enter leave events'
+ if LocationEvent._lastevent is not None:
+ last = LocationEvent._lastevent
+ if last.canvas!=self.canvas:
+ # process figure enter/leave event
+ last.canvas.callbacks.process('figure_leave_event', last)
+ self.canvas.callbacks.process('figure_enter_event', self)
+ if last.inaxes!=self.inaxes:
+ # process axes enter/leave events
+ if last.inaxes is not None:
+ last.canvas.callbacks.process('axes_leave_event', last)
+ if self.inaxes is not None:
+ self.canvas.callbacks.process('axes_enter_event', self)
+
+ else:
+ # process a figure enter event
+ self.canvas.callbacks.process('figure_enter_event', self)
+ # process an axes enter event if we are over an axes
+ if self.inaxes is not None:
+ self.canvas.callbacks.process('axes_enter_event', self)
+
+
+ LocationEvent._lastevent = self
+
+
+
+
class MouseEvent(LocationEvent):
"""
A mouse event ('button_press_event', 'button_release_event', 'scroll_event',
@@ -914,6 +952,12 @@
'motion_notify_event',
'pick_event',
'idle_event',
+ 'figure_enter_event',
+ # todo: we only process this when a mouse enters a different
+ # figure -- we need to connect to the GUI leavel event
+ 'figure_leave_event',
+ 'axes_enter_event',
+ 'axes_leave_event'
]
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mme...@us...> - 2008-12-01 10:10:46
|
Revision: 6459
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6459&view=rev
Author: mmetz_bn
Date: 2008-12-01 10:10:39 +0000 (Mon, 01 Dec 2008)
Log Message:
-----------
Fixed histogram autoscaling bug when bins or range are given explicitly
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/axes.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-11-30 18:33:55 UTC (rev 6458)
+++ trunk/matplotlib/CHANGELOG 2008-12-01 10:10:39 UTC (rev 6459)
@@ -1,3 +1,6 @@
+2008-12-01 Fixed histogram autoscaling bug when bins or range are given
+ explicitly (fixes Debian bug 503148) - MM
+
2008-11-25 Added rcParam axes.unicode_minus which allows plain hypen
for minus when False - JDH
Modified: trunk/matplotlib/lib/matplotlib/axes.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/axes.py 2008-11-30 18:33:55 UTC (rev 6458)
+++ trunk/matplotlib/lib/matplotlib/axes.py 2008-12-01 10:10:39 UTC (rev 6459)
@@ -6510,6 +6510,9 @@
"""
if not self._hold: self.cla()
+ # NOTE: the range keyword overwrites the built-in func range !!!
+ # needs to be fixed in with numpy !!!
+
if kwargs.get('width') is not None:
raise DeprecationWarning(
'hist now uses the rwidth to give relative width '
@@ -6531,6 +6534,10 @@
tx.append( np.array(x[i]) )
x = tx
+ # Check whether bins or range are given explicitly. In that
+ # case do not autoscale axes.
+ binsgiven = (cbook.iterable(bins) or range != None)
+
n = []
for i in xrange(len(x)):
# this will automatically overwrite bins,
@@ -6541,9 +6548,8 @@
if cumulative:
slc = slice(None)
- if cbook.is_numlike(cumulative):
- if cumulative < 0:
- slc = slice(None,None,-1)
+ if cbook.is_numlike(cumulative) and cumulative < 0:
+ slc = slice(None,None,-1)
if normed:
n = [(m * np.diff(bins))[slc].cumsum()[slc] for m in n]
@@ -6675,6 +6681,16 @@
p.set_label(label)
label = '_nolegend_'
+ if binsgiven:
+ self.set_autoscale_on(False)
+ if orientation == 'vertical':
+ self.autoscale_view(scalex=False, scaley=True)
+ XL = self.xaxis.get_major_locator().view_limits(bins[0], bins[-1])
+ self.set_xbound(XL)
+ else:
+ self.autoscale_view(scalex=True, scaley=False)
+ YL = self.yaxis.get_major_locator().view_limits(bins[0], bins[-1])
+ self.set_ybound(YL)
if len(n)==1:
return n[0], bins, cbook.silent_list('Patch', patches[0])
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2008-12-01 14:51:40
|
Revision: 6461
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6461&view=rev
Author: jdh2358
Date: 2008-12-01 14:51:35 +0000 (Mon, 01 Dec 2008)
Log Message:
-----------
added Jae Joon's legend and offsetbox implementation
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/legend.py
trunk/matplotlib/lib/matplotlib/rcsetup.py
Added Paths:
-----------
trunk/matplotlib/examples/pylab_examples/legend_demo3.py
trunk/matplotlib/lib/matplotlib/offsetbox.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-12-01 14:06:49 UTC (rev 6460)
+++ trunk/matplotlib/CHANGELOG 2008-12-01 14:51:35 UTC (rev 6461)
@@ -1,3 +1,6 @@
+2008-11-30 Reimplementaion of the legend which supports baseline alignement,
+ multi-column, and expand mode. - JJL
+
2008-12-01 Fixed histogram autoscaling bug when bins or range are given
explicitly (fixes Debian bug 503148) - MM
Added: trunk/matplotlib/examples/pylab_examples/legend_demo3.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/legend_demo3.py (rev 0)
+++ trunk/matplotlib/examples/pylab_examples/legend_demo3.py 2008-12-01 14:51:35 UTC (rev 6461)
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+
+import matplotlib.pyplot as plt
+import numpy as np
+
+def myplot(ax):
+ t1 = np.arange(0.0, 1.0, 0.1)
+ for n in [1, 2, 3, 4]:
+ ax.plot(t1, t1**n, label="n=%d"%(n,))
+
+ax1 = plt.subplot(3,1,1)
+ax1.plot([1], label="multi\nline")
+ax1.plot([1], label="$2^{2^2}$")
+ax1.plot([1], label=r"$\frac{1}{2}\pi$")
+ax1.legend(loc=1, ncol=3, shadow=True)
+
+ax2 = plt.subplot(3,1,2)
+myplot(ax2)
+ax2.legend(loc=1, ncol=2, shadow=True)
+
+
+ax3 = plt.subplot(3,1,3)
+myplot(ax3)
+ax3.legend(loc=1, ncol=4, mode="expand", shadow=True)
+
+
+#title('Damped oscillation')
+
+plt.draw()
+plt.show()
+
+#plt.savefig("legend_demo3")
+
+
Modified: trunk/matplotlib/lib/matplotlib/legend.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/legend.py 2008-12-01 14:06:49 UTC (rev 6460)
+++ trunk/matplotlib/lib/matplotlib/legend.py 2008-12-01 14:51:35 UTC (rev 6461)
@@ -26,16 +26,21 @@
import numpy as np
from matplotlib import rcParams
-from artist import Artist
-from cbook import is_string_like, iterable, silent_list, safezip
-from font_manager import FontProperties
-from lines import Line2D
-from mlab import segments_intersect
-from patches import Patch, Rectangle, Shadow, bbox_artist
-from collections import LineCollection, RegularPolyCollection
-from text import Text
-from transforms import Affine2D, Bbox, BboxTransformTo
+from matplotlib.artist import Artist
+from matplotlib.cbook import is_string_like, iterable, silent_list, safezip
+from matplotlib.font_manager import FontProperties
+from matplotlib.lines import Line2D
+from matplotlib.mlab import segments_intersect
+from matplotlib.patches import Patch, Rectangle, Shadow, bbox_artist, FancyBboxPatch
+from matplotlib.collections import LineCollection, RegularPolyCollection
+from matplotlib.text import Text
+from matplotlib.transforms import Affine2D, Bbox, BboxTransformTo
+from itertools import cycle, izip
+
+from matplotlib.offsetbox import HPacker, VPacker, TextArea, DrawingArea
+
+
class Legend(Artist):
"""
Place a legend on the axes at location loc. Labels are a
@@ -75,7 +80,6 @@
}
-
zorder = 5
def __str__(self):
return "Legend"
@@ -83,72 +87,132 @@
def __init__(self, parent, handles, labels,
loc = None,
numpoints = None, # the number of points in the legend line
+ markerscale = None, # the relative size of legend markers vs. original
scatterpoints = 3, # TODO: may be an rcParam
- prop = None,
- pad = None, # the fractional whitespace inside the legend border
- borderpad = None,
- markerscale = None, # the relative size of legend markers vs. original
+ scatteryoffsets=None,
+ prop = None, # properties for the legend texts
+
# the following dimensions are in axes coords
- labelsep = None, # the vertical space between the legend entries
- handlelen = None, # the length of the legend lines
- handletextsep = None, # the space between the legend line and legend text
- axespad = None, # the border between the axes and legend edge
+ pad = None, # deprecated; use borderpad
+ labelsep = None, # deprecated; use labelspacing
+ handlelen = None, # deprecated; use handlelength
+ handletextsep = None, # deprecated; use handletextpad
+ axespad = None, # deprecated; use borderaxespad
+
+ # spacing & pad defined as a fractionof the font-size
+ borderpad = None, # the fractional whitespace inside the legend border
+ labelspacing=None, #the vertical space between the legend entries
+ handlelength=None, # the length of the legend handles
+ handletextpad=None, # the pad between the legend handle and text
+ borderaxespad=None, # the pad between the axes and legend border
+ columnspacing=None, # spacing between columns
+
+ ncol=1, # number of columns
+ mode=None, # mode for horizontal distribution of columns. None, "expand"
+
shadow = None,
- scatteryoffsets=None,
):
"""
- parent # the artist that contains the legend
- handles # a list of artists (lines, patches) to add to the legend
- labels # a list of strings to label the legend
- loc # a location code
- numpoints = 4 # the number of points in the legend line
- scatterpoints = 3 # the number of points for the scatterplot legend
- prop = FontProperties(size='smaller') # the font property
- pad = 0.2 # the fractional whitespace inside the legend border
- markerscale = 0.6 # the relative size of legend markers vs. original
- shadow # if True, draw a shadow behind legend
- scatteryoffsets # a list of yoffsets for scatter symbols in legend
+ - *parent* : the artist that contains the legend
+ - *handles* : a list of artists (lines, patches) to add to the legend
+ - *labels* : a list of strings to label the legend
-The following dimensions are in axes coords
- labelsep = 0.005 # the vertical space between the legend entries
- handlelen = 0.05 # the length of the legend lines
- handletextsep = 0.02 # the space between the legend line and legend text
- axespad = 0.02 # the border between the axes and legend edge
+ Optional keyword arguments:
+
+ ================ =========================================
+ Keyword Description
+ ================ =========================================
+
+ loc a location code
+ numpoints the number of points in the legend line
+ prop the font property
+ markerscale the relative size of legend markers vs. original
+ shadow if True, draw a shadow behind legend
+ scatteryoffsets a list of yoffsets for scatter symbols in legend
+
+ borderpad the fractional whitespace inside the legend border
+ labelspacing the vertical space between the legend entries
+ handlelength the length of the legend handles
+ handletextpad the pad between the legend handle and text
+ borderaxespad the pad between the axes and legend border
+ columnspacing the spacing between columns
+
+The dimensions of pad and spacing are given as a fraction of the
+fontsize. Values from rcParams will be used if None.
+
"""
- from axes import Axes # local import only to avoid circularity
- from figure import Figure # local import only to avoid circularity
+ from matplotlib.axes import Axes # local import only to avoid circularity
+ from matplotlib.figure import Figure # local import only to avoid circularity
Artist.__init__(self)
- proplist=[numpoints, scatterpoints, pad, borderpad, markerscale, labelsep,
- handlelen, handletextsep, axespad, shadow]
- propnames=['numpoints','scatterpoints', 'pad', 'borderpad', 'markerscale',
- 'labelsep', 'handlelen', 'handletextsep', 'axespad', 'shadow']
- for name, value in safezip(propnames,proplist):
- if value is None:
- value=rcParams["legend."+name]
- setattr(self,name,value)
- if pad:
- warnings.warn("Use 'borderpad' instead of 'pad'.", DeprecationWarning)
- # 2008/10/04
- if self.numpoints <= 0:
- raise ValueError("numpoints must be > 0; it was %d"% numpoints)
- if self.scatterpoints <= 0:
- raise ValueError("scatterpoints must be > 0; it was %d"% numpoints)
if prop is None:
self.prop=FontProperties(size=rcParams["legend.fontsize"])
else:
self.prop=prop
self.fontsize = self.prop.get_size_in_points()
+ propnames=['numpoints', 'markerscale', 'shadow', "columnspacing",
+ "scatterpoints"]
+
+ localdict = locals()
+
+ for name in propnames:
+ if localdict[name] is None:
+ value = rcParams["legend."+name]
+ else:
+ value = localdict[name]
+ setattr(self, name, value)
+
+ # Take care the deprecated keywords
+ deprecated_kwds = {"pad":"borderpad",
+ "labelsep":"labelspacing",
+ "handlelen":"handlelength",
+ "handletextsep":"handletextpad",
+ "axespad":"borderaxespad"}
+
+ # convert values of deprecated keywords (ginve in axes coords)
+ # to new vaules in a fraction of the font size
+
+ # conversion factor
+ bbox = parent.bbox
+ axessize_fontsize = min(bbox.width, bbox.height)/self.fontsize
+
+ for k, v in deprecated_kwds.items():
+ # use deprecated value if not None and if their newer
+ # counter part is None.
+ if localdict[k] is not None and localdict[v] is None:
+ warnings.warn("Use '%s' instead of '%s'." % (v, k),
+ DeprecationWarning)
+ setattr(self, v, localdict[k]*axessize_fontsize)
+ continue
+
+ # Otherwise, use new keywords
+ if localdict[v] is None:
+ setattr(self, v, rcParams["legend."+v])
+ else:
+ setattr(self, v, localdict[v])
+
+ del localdict
+
+ self._ncol = ncol
+
+ if self.numpoints <= 0:
+ raise ValueError("numpoints must be >= 0; it was %d"% numpoints)
+
# introduce y-offset for handles of the scatter plot
if scatteryoffsets is None:
- self._scatteryoffsets = np.array([4./8., 5./8., 3./8.])
+ self._scatteryoffsets = np.array([3./8., 4./8., 2.5/8.])
else:
self._scatteryoffsets = np.asarray(scatteryoffsets)
- reps = int(self.scatterpoints / len(self._scatteryoffsets)) + 1
+ reps = int(self.numpoints / len(self._scatteryoffsets)) + 1
self._scatteryoffsets = np.tile(self._scatteryoffsets, reps)[:self.scatterpoints]
+ # _legend_box is an OffsetBox instance that contains all
+ # legend items and will be initialized from _init_legend_box()
+ # method.
+ self._legend_box = None
+
if isinstance(parent,Axes):
self.isaxes = True
self.set_figure(parent.figure)
@@ -158,9 +222,6 @@
else:
raise TypeError("Legend needs either Axes or Figure as parent")
self.parent = parent
- self._offsetTransform = Affine2D()
- self._parentTransform = BboxTransformTo(parent.bbox)
- Artist.set_transform(self, self._offsetTransform + self._parentTransform)
if loc is None:
loc = rcParams["legend.loc"]
@@ -186,100 +247,165 @@
loc = 1
self._loc = loc
+ self._mode = mode
- self.legendPatch = Rectangle(
- xy=(0.0, 0.0), width=0.5, height=0.5,
+ # We use FancyBboxPatch to draw a legend frame. The location
+ # and size of the box will be updated during the drawing time.
+ self.legendPatch = FancyBboxPatch(
+ xy=(0.0, 0.0), width=1., height=1.,
facecolor='w', edgecolor='k',
+ mutation_scale=self.fontsize,
)
+
+ # The width and height of the legendPatch will be set (in the
+ # draw()) to the length that includes the padding. Thus we set
+ # pad=0 here.
+ self.legendPatch.set_boxstyle("round",pad=0, #self.borderpad,
+ rounding_size=0.2)
+
self._set_artist_props(self.legendPatch)
- # make a trial box in the middle of the axes. relocate it
- # based on it's bbox
- left, top = 0.5, 0.5
- textleft = left+ self.handlelen+self.handletextsep
- self.texts = self._get_texts(labels, textleft, top)
- self.legendHandles = self._get_handles(handles, self.texts)
-
self._drawFrame = True
+ # populate the legend_box with legend items.
+ self._init_legend_box(handles, labels)
+ self._legend_box.set_figure(self.figure)
+
+
def _set_artist_props(self, a):
+ """
+ set the boilerplate props for artists added to axes
+ """
a.set_figure(self.figure)
+
+ for c in self.get_children():
+ c.set_figure(self.figure)
+
a.set_transform(self.get_transform())
- def _approx_text_height(self):
- return self.fontsize/72.0*self.figure.dpi/self.parent.bbox.height
+ def _findoffset_best(self, width, height, xdescent, ydescent):
+ "Heper function to locate the legend"
+ ox, oy = self._find_best_position(width, height)
+ return ox+xdescent, oy+ydescent
+ def _findoffset_loc(self, width, height, xdescent, ydescent):
+ "Heper function to locate the legend"
+ bbox = Bbox.from_bounds(0, 0, width, height)
+ x, y = self._get_anchored_bbox(self._loc, bbox, self.parent.bbox)
+ return x+xdescent, y+ydescent
def draw(self, renderer):
+ "Draw everything that belongs to the legend"
if not self.get_visible(): return
+
renderer.open_group('legend')
- self._update_positions(renderer)
+
+ # find_offset function will be provided to _legend_box and
+ # _legend_box will draw itself at the location of the return
+ # value of the find_offset.
+ if self._loc == 0:
+ self._legend_box.set_offset(self._findoffset_best)
+ else:
+ self._legend_box.set_offset(self._findoffset_loc)
+
+ # if mode == fill, set the width of the legend_box to the
+ # width of the paret (minus pads)
+ if self._mode in ["expand"]:
+ pad = 2*(self.borderaxespad+self.borderpad)*self.fontsize
+ self._legend_box.set_width(self.parent.bbox.width-pad)
+
if self._drawFrame:
+ # update the location and size of the legend
+ bbox = self._legend_box.get_window_extent(renderer)
+ self.legendPatch.set_bounds(bbox.x0, bbox.y0,
+ bbox.width, bbox.height)
+
if self.shadow:
- shadow = Shadow(self.legendPatch, -0.005, -0.005)
+ shadow = Shadow(self.legendPatch, 2, -2)
shadow.draw(renderer)
+
self.legendPatch.draw(renderer)
+ self._legend_box.draw(renderer)
- if not len(self.legendHandles) and not len(self.texts): return
- for h in self.legendHandles:
- if h is not None:
- h.draw(renderer)
- if hasattr(h, '_legmarker'):
- h._legmarker.draw(renderer)
- if 0: bbox_artist(h, renderer)
-
- for t in self.texts:
- if 0: bbox_artist(t, renderer)
- t.draw(renderer)
renderer.close_group('legend')
- #draw_bbox(self.save, renderer, 'g')
- #draw_bbox(self.ibox, renderer, 'r', self.get_transform())
- def _get_handle_text_bbox(self, renderer):
- 'Get a bbox for the text and lines in axes coords'
- bboxesText = [t.get_window_extent(renderer) for t in self.texts]
- bboxesHandles = [h.get_window_extent(renderer) for h in self.legendHandles if h is not None]
+ def _approx_text_height(self):
+ """
+ Return the approximate height of the text. This is used to place
+ the legend handle.
+ """
+ return self.fontsize/72.0*self.figure.dpi
- bboxesAll = bboxesText
- bboxesAll.extend(bboxesHandles)
- bbox = Bbox.union(bboxesAll)
- self.save = bbox
+ def _init_legend_box(self, handles, labels):
+ """
+ Initiallize the legend_box. The legend_box is an instance of
+ the OffsetBox, which is packed with legend handles and
+ texts. Once packed, their location is calculated during the
+ drawing time.
+ """
- ibox = bbox.inverse_transformed(self.get_transform())
- self.ibox = ibox
+ # legend_box is a HPacker, horizontally packed with
+ # columns. Each column is a VPacker, vertically packed with
+ # legend items. Each legend item is HPacker packed with
+ # legend handleBox and labelBox. handleBox is an instance of
+ # offsetbox.DrawingArea which contains legend handle. labelBox
+ # is an instance of offsetbox.TextArea which contains legend
+ # text.
- return ibox
+
+ text_list = [] # the list of text instances
+ handle_list = [] # the list of text instances
- def _get_handles(self, handles, texts):
- handles = list(handles)
- texts = list(texts)
- HEIGHT = self._approx_text_height()
- left = 0.5
+ label_prop = dict(verticalalignment='baseline',
+ horizontalalignment='left',
+ fontproperties=self.prop,
+ )
- ret = [] # the returned legend lines
+ labelboxes = []
- # we need to pad the text with empties for the numpoints=1
- # centered marker proxy
+ for l in labels:
+ textbox = TextArea(l, textprops=label_prop)
+ text_list.append(textbox._text)
+ labelboxes.append(textbox)
- for handle, label in safezip(handles, texts):
+ handleboxes = []
+
+
+ # The approximate height and descent of text. These values are
+ # only used for plotting the legend handle.
+ height = self._approx_text_height() * 0.6
+ descent = 0. #height/6.
+
+ # each handle needs to be drawn inside a box of
+ # (x, y, w, h) = (0, -descent, width, height).
+ # And their corrdinates should be given in the display coordinates.
+
+ # The transformation of each handle will be automatically set
+ # to self.get_trasnform(). If the artist does not uses its
+ # default trasnform (eg, Collections), you need to
+ # manually set their transform to the self.get_transform().
+
+ for handle in handles:
if isinstance(handle, RegularPolyCollection):
npoints = self.scatterpoints
else:
npoints = self.numpoints
if npoints > 1:
- xdata = np.linspace(left, left + self.handlelen, npoints)
+ # we put some pad here to compensate the size of the
+ # marker
+ xdata = np.linspace(0.3*self.fontsize,
+ (self.handlelength-0.3)*self.fontsize,
+ npoints)
xdata_marker = xdata
elif npoints == 1:
- xdata = np.linspace(left, left + self.handlelen, 2)
- xdata_marker = [left + 0.5*self.handlelen]
+ xdata = np.linspace(0, self.handlelength, 2)
+ xdata_marker = [0.5*self.handlelength*self.fontsize]
- x, y = label.get_position()
- x -= self.handlelen + self.handletextsep
if isinstance(handle, Line2D):
- ydata = (y-HEIGHT/2)*np.ones(xdata.shape, float)
+ ydata = ((height-descent)/2.)*np.ones(xdata.shape, float)
legline = Line2D(xdata, ydata)
legline.update_from(handle)
@@ -288,8 +414,9 @@
legline.set_clip_path(None)
legline.set_drawstyle('default')
legline.set_marker('None')
- ret.append(legline)
+ handle_list.append(legline)
+
legline_marker = Line2D(xdata_marker, ydata[:len(xdata_marker)])
legline_marker.update_from(handle)
self._set_artist_props(legline_marker)
@@ -302,16 +429,17 @@
legline._legmarker = legline_marker
elif isinstance(handle, Patch):
- p = Rectangle(xy=(min(xdata), y-3/4*HEIGHT),
- width = self.handlelen, height=HEIGHT/2,
+ p = Rectangle(xy=(0, -0.*descent),
+ width = self.handlelength*self.fontsize,
+ height=0.*descent+(height-descent)*.9,
)
p.update_from(handle)
self._set_artist_props(p)
p.set_clip_box(None)
p.set_clip_path(None)
- ret.append(p)
+ handle_list.append(p)
elif isinstance(handle, LineCollection):
- ydata = (y-HEIGHT/2)*np.ones(xdata.shape, float)
+ ydata = ((height-descent)/2.)*np.ones(xdata.shape, float)
legline = Line2D(xdata, ydata)
self._set_artist_props(legline)
legline.set_clip_box(None)
@@ -322,13 +450,13 @@
legline.set_color(color)
legline.set_linewidth(lw)
legline.set_dashes(dashes)
- ret.append(legline)
+ handle_list.append(legline)
elif isinstance(handle, RegularPolyCollection):
- # the ydata values set here have no effects as it will
- # be updated in the _update_positions() method.
- ydata = (y-HEIGHT/2)*np.ones(np.asarray(xdata_marker).shape, float)
+ #ydata = self._scatteryoffsets
+ ydata = height*self._scatteryoffsets
+
size_max, size_min = max(handle.get_sizes()),\
min(handle.get_sizes())
# we may need to scale these sizes by "markerscale"
@@ -338,32 +466,86 @@
sizes = [.5*(size_max+size_min), size_max,
size_min]
else:
- sizes = size_max*np.linspace(0,1,self.scatterpoints)+size_min
-
+ sizes = (size_max-size_min)*np.linspace(0,1,self.scatterpoints)+size_min
+
p = type(handle)(handle.get_numsides(),
rotation=handle.get_rotation(),
sizes=sizes,
offsets=zip(xdata_marker,ydata),
- transOffset=self.get_transform())
-
+ transOffset=self.get_transform(),
+ )
+
p.update_from(handle)
p.set_figure(self.figure)
p.set_clip_box(None)
p.set_clip_path(None)
- ret.append(p)
+ handle_list.append(p)
else:
- ret.append(None)
+ handle_list.append(None)
- return ret
+ handlebox = DrawingArea(width=self.handlelength*self.fontsize,
+ height=height,
+ xdescent=0., ydescent=descent)
+ handle = handle_list[-1]
+ handlebox.add_artist(handle)
+ if hasattr(handle, "_legmarker"):
+ handlebox.add_artist(handle._legmarker)
+ handleboxes.append(handlebox)
+
+
+ # We calculate number of lows in each column. The first
+ # (num_largecol) columns will have (nrows+1) rows, and remaing
+ # (num_smallcol) columns will have (nrows) rows.
+ nrows, num_largecol = divmod(len(handleboxes), self._ncol)
+ num_smallcol = self._ncol-num_largecol
+
+ # starting index of each column and number of rows in it.
+ largecol = zip(range(0, num_largecol*(nrows+1), (nrows+1)),
+ [nrows+1] * num_largecol)
+ smallcol = zip(range(num_largecol*(nrows+1), len(handleboxes), nrows),
+ [nrows] * num_smallcol)
+
+ handle_label = zip(handleboxes, labelboxes)
+ columnbox = []
+ for i0, di in largecol+smallcol:
+ # pack handleBox and labelBox into itemBox
+ itemBoxes = [HPacker(pad=0,
+ sep=self.handletextpad*self.fontsize,
+ children=[h, t], align="baseline")
+ for h, t in handle_label[i0:i0+di]]
+
+ # pack columnBox
+ columnbox.append(VPacker(pad=0,
+ sep=self.labelspacing*self.fontsize,
+ align="baseline",
+ children=itemBoxes))
+
+ if self._mode == "expand":
+ mode = "expand"
+ else:
+ mode = "fixed"
+
+ sep = self.columnspacing*self.fontsize
+
+ self._legend_box = HPacker(pad=self.borderpad*self.fontsize,
+ sep=sep, align="baseline",
+ mode=mode,
+ children=columnbox)
+
+ self.texts = text_list
+ self.legendHandles = handle_list
+
+
def _auto_legend_data(self):
- """ Returns list of vertices and extents covered by the plot.
+ """
+ Returns list of vertices and extents covered by the plot.
Returns a two long list.
First element is a list of (x, y) vertices (in
- axes-coordinates) covered by all the lines and line
+ display-coordinates) covered by all the lines and line
collections, in the legend's handles.
Second element is a list of bounding boxes for all the patches in
@@ -377,24 +559,21 @@
bboxes = []
lines = []
- inverse_transform = ax.transAxes.inverted()
-
for handle in ax.lines:
assert isinstance(handle, Line2D)
path = handle.get_path()
trans = handle.get_transform()
tpath = trans.transform_path(path)
- apath = inverse_transform.transform_path(tpath)
- lines.append(apath)
+ lines.append(tpath)
for handle in ax.patches:
assert isinstance(handle, Patch)
if isinstance(handle, Rectangle):
- transform = handle.get_data_transform() + inverse_transform
+ transform = handle.get_data_transform()
bboxes.append(handle.get_bbox().transformed(transform))
else:
- transform = handle.get_transform() + inverse_transform
+ transform = handle.get_transform()
bboxes.append(handle.get_path().get_extents(transform))
return [vertices, bboxes, lines]
@@ -404,9 +583,10 @@
self._drawFrame = b
def get_children(self):
+ 'return a list of child artists'
children = []
- children.extend(self.legendHandles)
- children.extend(self.texts)
+ if self._legend_box:
+ children.append(self._legend_box)
return children
def get_frame(self):
@@ -425,51 +605,61 @@
'return a list of text.Text instance in the legend'
return silent_list('Text', self.texts)
- def _get_texts(self, labels, left, upper):
+ def get_window_extent(self):
+ 'return a extent of the the legend'
+ return self.legendPatch.get_window_extent()
- # height in axes coords
- HEIGHT = self._approx_text_height()
- pos = upper
- x = left
- ret = [] # the returned list of text instances
- for l in labels:
- text = Text(
- x=x, y=pos,
- text=l,
- fontproperties=self.prop,
- verticalalignment='top',
- horizontalalignment='left'
- )
- self._set_artist_props(text)
- ret.append(text)
- pos -= HEIGHT
+ def _get_anchored_bbox(self, loc, bbox, parentbbox):
+ """
+ Place the *bbox* inside the *parentbbox* according to a given
+ location code. Return the (x,y) coordinate of the bbox.
- return ret
+ - loc: a location code in range(1, 11).
+ This corresponds to the possible values for self._loc, excluding "best".
+ - bbox: bbox to be placed, display coodinate units.
+ - parentbbox: a parent box which will ...
[truncated message content] |
|
From: <ds...@us...> - 2008-12-02 17:12:17
|
Revision: 6471
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6471&view=rev
Author: dsdale
Date: 2008-12-02 17:11:07 +0000 (Tue, 02 Dec 2008)
Log Message:
-----------
improved checks for external dependencies
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/__init__.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-12-02 17:07:57 UTC (rev 6470)
+++ trunk/matplotlib/CHANGELOG 2008-12-02 17:11:07 UTC (rev 6471)
@@ -1,3 +1,7 @@
+2008-12-02 Improve checks for external dependencies, using subprocess
+ (instead of deprecated popen*) and distutils (for version
+ checking) - DSD
+
2008-11-30 Reimplementaion of the legend which supports baseline alignement,
multi-column, and expand mode. - JJL
Modified: trunk/matplotlib/lib/matplotlib/__init__.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/__init__.py 2008-12-02 17:07:57 UTC (rev 6470)
+++ trunk/matplotlib/lib/matplotlib/__init__.py 2008-12-02 17:11:07 UTC (rev 6471)
@@ -93,8 +93,9 @@
__revision__ = '$Revision$'
__date__ = '$Date$'
-import os, re, shutil, sys, warnings
+import os, re, shutil, subprocess, sys, warnings
import distutils.sysconfig
+import distutils.version
NEWCONFIG = False
@@ -256,10 +257,10 @@
def checkdep_dvipng():
try:
- stdin, stdout = os.popen4('dvipng -version')
- line = stdout.readlines()[1]
+ s = subprocess.Popen(['dvipng','-version'], stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ line = s.stdout.readlines()[1]
v = line.split()[-1]
- float(v)
return v
except (IndexError, ValueError):
return None
@@ -267,47 +268,45 @@
def checkdep_ghostscript():
try:
if sys.platform == 'win32':
- command = 'gswin32c --version'
+ command_args = ['gswin32c', '--version']
else:
- command = 'gs --version'
- stdin, stdout = os.popen4(command)
- v = stdout.read()[:-1]
- vtest = '.'.join(v.split('.')[:2]) # deal with version numbers like '7.07.1'
- float(vtest)
- return vtest
+ command_args = ['gs', '--version']
+ s = subprocess.Popen(command_args, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ v = s.stdout.read()[:-1]
+ return v
except (IndexError, ValueError):
return None
def checkdep_tex():
try:
- stdin, stdout = os.popen4('tex -version')
- line = stdout.readlines()[0]
+ s = subprocess.Popen(['tex','-version'], stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ line = s.stdout.readlines()[0]
pattern = '3\.1\d+'
match = re.search(pattern, line)
v = match.group(0)
- float(v)
return v
except (IndexError, ValueError, AttributeError):
return None
def checkdep_pdftops():
try:
- stdin, stdout = os.popen4('pdftops -v')
- for line in stdout.readlines():
+ s = subprocess.Popen(['pdftops','-v'], stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ for line in s.stderr:
if 'version' in line:
v = line.split()[-1]
- float(v)
return v
except (IndexError, ValueError, UnboundLocalError):
return None
def compare_versions(a, b):
- "return True if a is greater than b"
+ "return True if a is greater than or equal to b"
if a:
- a = [int(i) for i in a.split('.')]
- b = [int(i) for i in b.split('.')]
- if a[0]>b[0]: return True
- elif (a[0]==b[0]) and (a[1]>=b[1]): return True
+ a = distutils.version.LooseVersion(a)
+ b = distutils.version.LooseVersion(b)
+ if a>=b: return True
else: return False
else: return False
@@ -330,8 +329,13 @@
if s == 'xpdf':
pdftops_req = '3.0'
+ pdftops_req_alt = '0.9' # poppler version numbers, ugh
pdftops_v = checkdep_pdftops()
- if compare_versions(pdftops_v, pdftops_req): pass
+ if compare_versions(pdftops_v, pdftops_req):
+ pass
+ elif compare_versions(pdftops_v, pdftops_req_alt) and not \
+ compare_versions(pdftops_v, '1.0'):
+ pass
else:
flag = False
warnings.warn(('matplotlibrc ps.usedistiller can not be set to '
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <lee...@us...> - 2008-12-02 22:27:43
|
Revision: 6479
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6479&view=rev
Author: leejjoon
Date: 2008-12-02 22:27:38 +0000 (Tue, 02 Dec 2008)
Log Message:
-----------
Fixed a bug in the new legend class that didn't allowed a tuple of coordinate vlaues as loc
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/legend.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-12-02 22:04:41 UTC (rev 6478)
+++ trunk/matplotlib/CHANGELOG 2008-12-02 22:27:38 UTC (rev 6479)
@@ -1,3 +1,6 @@
+2008-12-02 Fixed a bug in the new legend class that didn't allowed
+ a tuple of coordinate vlaues as loc. -JJL
+
2008-12-02 Improve checks for external dependencies, using subprocess
(instead of deprecated popen*) and distutils (for version
checking) - DSD
Modified: trunk/matplotlib/lib/matplotlib/legend.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/legend.py 2008-12-02 22:04:41 UTC (rev 6478)
+++ trunk/matplotlib/lib/matplotlib/legend.py 2008-12-02 22:27:38 UTC (rev 6479)
@@ -61,6 +61,9 @@
'upper center' : 9,
'center' : 10,
+ loc can be a tuple of the noramilzed coordinate values with
+ respect its parent.
+
Return value is a sequence of text, line instances that make
up the legend
"""
@@ -100,7 +103,7 @@
axespad = None, # deprecated; use borderaxespad
# spacing & pad defined as a fractionof the font-size
- borderpad = None, # the fractional whitespace inside the legend border
+ borderpad = None, # the whitespace inside the legend border
labelspacing=None, #the vertical space between the legend entries
handlelength=None, # the length of the legend handles
handletextpad=None, # the pad between the legend handle and text
@@ -119,11 +122,11 @@
Optional keyword arguments:
- ================ =========================================
+ ================ =================================================
Keyword Description
- ================ =========================================
+ ================ =================================================
- loc a location code
+ loc a location code or a tuple of coordinates
numpoints the number of points in the legend line
prop the font property
markerscale the relative size of legend markers vs. original
@@ -284,14 +287,22 @@
a.set_transform(self.get_transform())
def _findoffset_best(self, width, height, xdescent, ydescent):
- "Heper function to locate the legend"
+ "Heper function to locate the legend at its best position"
ox, oy = self._find_best_position(width, height)
return ox+xdescent, oy+ydescent
def _findoffset_loc(self, width, height, xdescent, ydescent):
- "Heper function to locate the legend"
- bbox = Bbox.from_bounds(0, 0, width, height)
- x, y = self._get_anchored_bbox(self._loc, bbox, self.parent.bbox)
+ "Heper function to locate the legend using the location code"
+
+ if iterable(self._loc) and len(self._loc)==2:
+ # when loc is a tuple of axes(or figure) coordinates.
+ fx, fy = self._loc
+ bbox = self.parent.bbox
+ x, y = bbox.x0 + bbox.width * fx, bbox.y0 + bbox.height * fy
+ else:
+ bbox = Bbox.from_bounds(0, 0, width, height)
+ x, y = self._get_anchored_bbox(self._loc, bbox, self.parent.bbox)
+
return x+xdescent, y+ydescent
def draw(self, renderer):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <lee...@us...> - 2008-12-03 07:40:13
|
Revision: 6480
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6480&view=rev
Author: leejjoon
Date: 2008-12-03 07:40:09 +0000 (Wed, 03 Dec 2008)
Log Message:
-----------
reorganization of style classes in patches.py
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/patches.py
Added Paths:
-----------
trunk/matplotlib/examples/pylab_examples/fancyarrow_demo.py
trunk/matplotlib/examples/pylab_examples/fancybox_demo2.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-12-02 22:27:38 UTC (rev 6479)
+++ trunk/matplotlib/CHANGELOG 2008-12-03 07:40:09 UTC (rev 6480)
@@ -1,3 +1,7 @@
+2008-12-02 The transmuter classes in the patches.py are reorganized as
+ subclasses of the Style classes. A few more box and arrow
+ styles are added. -JJL
+
2008-12-02 Fixed a bug in the new legend class that didn't allowed
a tuple of coordinate vlaues as loc. -JJL
Added: trunk/matplotlib/examples/pylab_examples/fancyarrow_demo.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/fancyarrow_demo.py (rev 0)
+++ trunk/matplotlib/examples/pylab_examples/fancyarrow_demo.py 2008-12-03 07:40:09 UTC (rev 6480)
@@ -0,0 +1,43 @@
+import matplotlib.patches as mpatches
+import matplotlib.pyplot as plt
+
+styles = mpatches.ArrowStyle.get_styles()
+
+figheight = (len(styles)+.5)
+fig1 = plt.figure(1, (4, figheight))
+fontsize = 0.3 * fig1.dpi
+
+ax = plt.Axes(fig1, [0, 0, 1, 1], frameon=False, aspect=1.)
+fig1.add_axes(ax)
+
+ax.set_xlim(0, 4)
+ax.set_ylim(0, figheight)
+
+for i, (stylename, styleclass) in enumerate(sorted(styles.items())):
+ y = (float(len(styles)) -0.25 - i) # /figheight
+ p = mpatches.Circle((3.2, y), 0.2, fc="w")
+ ax.add_patch(p)
+ #ax.plot([0.8], [y], "o", mec="b", mfc="w", ms=20, transform=fig1.transFigure)
+ #ax.scatter([0.8], [y], s=20*20, marker="o", edgecolors=["b"], facecolors=["w"],
+ # )
+ ax.annotate(stylename, (3.2, y),
+ (2., y),
+ #xycoords="figure fraction", textcoords="figure fraction",
+ ha="right", va="center",
+ size=fontsize,
+ arrowprops=dict(arrowstyle=stylename,
+ patchB=p,
+ shrinkA=5,
+ shrinkB=5,
+ fc="w", ec="k",
+ connectionstyle="arc3,rad=-0.05",
+ ),
+ bbox=dict(boxstyle="square", fc="w"))
+
+ax.xaxis.set_visible(False)
+ax.yaxis.set_visible(False)
+
+
+
+plt.draw()
+plt.show()
Added: trunk/matplotlib/examples/pylab_examples/fancybox_demo2.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/fancybox_demo2.py (rev 0)
+++ trunk/matplotlib/examples/pylab_examples/fancybox_demo2.py 2008-12-03 07:40:09 UTC (rev 6480)
@@ -0,0 +1,17 @@
+import matplotlib.patches as mpatch
+import matplotlib.pyplot as plt
+
+styles = mpatch.BoxStyle.get_styles()
+
+figheight = (len(styles)+.5)
+fig1 = plt.figure(1, (4, figheight))
+fontsize = 0.4 * fig1.dpi
+
+for i, (stylename, styleclass) in enumerate(styles.items()):
+ fig1.text(0.5, (float(len(styles)) - 0.5 - i)/figheight, stylename,
+ ha="center",
+ size=fontsize,
+ transform=fig1.transFigure,
+ bbox=dict(boxstyle=stylename, fc="w", ec="k"))
+plt.draw()
+plt.show()
Modified: trunk/matplotlib/lib/matplotlib/patches.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/patches.py 2008-12-02 22:27:38 UTC (rev 6479)
+++ trunk/matplotlib/lib/matplotlib/patches.py 2008-12-03 07:40:09 UTC (rev 6480)
@@ -289,6 +289,7 @@
rgbFace = (r, g, b)
gc.set_alpha(a)
+
if self._hatch:
gc.set_hatch(self._hatch )
@@ -1366,319 +1367,576 @@
r.draw(renderer)
-class BboxTransmuterBase(object):
+
+def _pprint_table(_table, leadingspace=2):
"""
- :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.
+ Given the list of list of strings, return a string of REST table format.
"""
+ if leadingspace:
+ pad = ' '*leadingspace
+ else:
+ pad = ''
- # The derived classes are required to be able to be initialized
- # w/o arguments, i.e., all its argument (except self) must have
- # the default values.
+ columns = [[] for cell in _table[0]]
- def __init__(self):
- super(BboxTransmuterBase, self).__init__()
+ for row in _table:
+ for column, cell in zip(columns, row):
+ column.append(cell)
+
+
+ col_len = [max([len(cell) for cell in column]) for column in columns]
+ lines = []
+ table_formatstr = pad + ' '.join([('=' * cl) for cl in col_len])
+ lines.append('')
+ lines.append(table_formatstr)
+ lines.append(pad + ' '.join([cell.ljust(cl) for cell, cl in zip(_table[0], col_len)]))
+ lines.append(table_formatstr)
+
+ lines.extend([(pad + ' '.join([cell.ljust(cl) for cell, cl in zip(row, col_len)]))
+ for row in _table[1:]])
+
+ lines.append(table_formatstr)
+ lines.append('')
+ return "\n".join(lines)
- def transmute(self, x0, y0, width, height, mutation_size):
+
+def _pprint_styles(_styles, leadingspace=2):
+ """
+ A helper function for the _Style class. Given the dictionary of
+ (stylename : styleclass), return a formatted string listing all the
+ styles. Used to update the documentation.
+ """
+ if leadingspace:
+ pad = ' '*leadingspace
+ else:
+ pad = ''
+
+ names, attrss, clss = [], [], []
+
+ import inspect
+
+ _table = [["Class", "Name", "Attrs"]]
+
+ for name, cls in sorted(_styles.items()):
+ args, varargs, varkw, defaults = inspect.getargspec(cls.__init__)
+ if defaults:
+ args = [(argname, argdefault) \
+ for argname, argdefault in zip(args[1:], defaults)]
+ else:
+ args = []
+
+ _table.append([cls.__name__, name,
+ ",".join([("%s=%s" % (an, av)) for an, av in args])])
+
+ return _pprint_table(_table)
+
+
+
+class _Style(object):
+ """
+ A base class for the Styles. It is meant to be a container class,
+ where actual styles are declared as subclass of it, and it
+ provides some helper functions.
+ """
+ def __new__(self, stylename, **kw):
"""
- 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.
+ return the instance of the subclass with the given style name.
"""
- raise NotImplementedError('Derived must override')
+ # the "class" should have the _style_list attribute, which is
+ # a dictionary of stylname, style class paie.
+
+ _list = stylename.replace(" ","").split(",")
+ _name = _list[0].lower()
+ try:
+ _cls = self._style_list[_name]
+ except KeyError:
+ raise ValueError("Unknown style : %s" % stylename)
+ try:
+ _args_pair = [cs.split("=") for cs in _list[1:]]
+ _args = dict([(k, float(v)) for k, v in _args_pair])
+ except ValueError:
+ raise ValueError("Incorrect style argument : %s" % stylename)
+ _args.update(kw)
- def __call__(self, x0, y0, width, height, mutation_size,
- aspect_ratio=1.):
+ return _cls(**_args)
+
+
+ @classmethod
+ def get_styles(klass):
"""
- The __call__ method a thin wrapper around the transmute method
- and take care of the aspect.
+ A class method which returns a dictionary of available styles.
"""
- if aspect_ratio is not None:
- # Squeeze the given height by the aspect_ratio
- y0, height = y0/aspect_ratio, height/aspect_ratio
- # call transmute method with squeezed height.
- path = self.transmute(x0, y0, width, height, mutation_size)
- vertices, codes = path.vertices, path.codes
- # Restore the height
- vertices[:,1] = vertices[:,1] * aspect_ratio
- return Path(vertices, codes)
- else:
- return self.transmute(x0, y0, width, height, mutation_size)
+ return klass._style_list
+ @classmethod
+ def pprint_styles(klass):
+ """
+ A class method which returns a string of the available styles.
+ """
+ return _pprint_styles(klass._style_list)
-class SquareBoxTransmuter(BboxTransmuterBase):
+
+
+class BoxStyle(_Style):
"""
- Simple square box.
+ :class:`BoxStyle` is a container class which defines several
+ boxstyle classes, which are used for :class:`FancyBoxPatch`.
- *pad*: an amount of padding.
+ A style object can be created as
+
+ BoxStyle.Round(pad=0.2)
+
+ or
+
+ BoxStyle("Round", pad=0.2)
+
+ or
+
+ BoxStyle("Round, pad=0.2")
+
+ Following boxstyle classes are defined.
+
+ %(AvailableBoxstyles)s
+
+ An instance of any boxstyle class is an callable object,
+ whose call signature is
+
+ __call__(self, x0, y0, width, height, mutation_size, aspect_ratio=1.)
+
+ and returns a :class:`Path` instance. *x0*, *y0*, *width* and
+ *height* specify the location and size of the box to be
+ drawn. *mutation_scale* determines the overall size of the
+ mutation (by which I mean the transformation of the rectangle to
+ the fancy box). *mutation_aspect* determines the aspect-ratio of
+ the mutation.
+
"""
+
+ _style_list = {}
- def __init__(self, pad=0.3):
- self.pad = pad
- super(SquareBoxTransmuter, self).__init__()
- def transmute(self, x0, y0, width, height, mutation_size):
+ class _Base(object):
+ """
+ :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.
+ """
- # padding
- pad = mutation_size * self.pad
+ # The derived classes are required to be able to be initialized
+ # w/o arguments, i.e., all its argument (except self) must have
+ # the default values.
- # width and height with padding added.
- width, height = width + 2.*pad, \
- height + 2.*pad,
+ def __init__(self):
+ """
+ initializtion.
+ """
+ super(BoxStyle._Base, self).__init__()
- # boundary of the padded box
- x0, y0 = x0-pad, y0-pad,
- x1, y1 = x0+width, y0 + height
- cp = [(x0, y0), (x1, y0), (x1, y1), (x0, y1),
- (x0, y0), (x0, y0)]
- com = [Path.MOVETO,
- Path.LINETO,
- Path.LINETO,
- Path.LINETO,
- Path.LINETO,
- Path.CLOSEPOLY]
- path = Path(cp, com)
+ def transmute(self, x0, y0, width, height, mutation_size):
+ """
+ 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')
- return path
-class RoundBoxTransmuter(BboxTransmuterBase):
- """
- A box with round corners.
- """
+ def __call__(self, x0, y0, width, height, mutation_size,
+ aspect_ratio=1.):
+ """
+ Given the location and size of the box, return the path of
+ the box around it.
- def __init__(self, pad=0.3, rounding_size=None):
- self.pad = pad
- self.rounding_size = rounding_size
- BboxTransmuterBase.__init__(self)
+ - *x0*, *y0*, *width*, *height* : location and size of the box
+ - *mutation_size* : a reference scale for the mutation.
+ - *aspect_ratio* : aspect-ration for the mutation.
+ """
+ # The __call__ method is a thin wrapper around the transmute method
+ # and take care of the aspect.
- def transmute(self, x0, y0, width, height, mutation_size):
+ if aspect_ratio is not None:
+ # Squeeze the given height by the aspect_ratio
+ y0, height = y0/aspect_ratio, height/aspect_ratio
+ # call transmute method with squeezed height.
+ path = self.transmute(x0, y0, width, height, mutation_size)
+ vertices, codes = path.vertices, path.codes
+ # Restore the height
+ vertices[:,1] = vertices[:,1] * aspect_ratio
+ return Path(vertices, codes)
+ else:
+ return self.transmute(x0, y0, width, height, mutation_size)
- # padding
- pad = mutation_size * self.pad
- # size of the roudning corner
- if self.rounding_size:
- dr = mutation_size * self.rounding_size
- else:
- dr = pad
- width, height = width + 2.*pad, \
- height + 2.*pad,
+ class Square(_Base):
+ """
+ A simple square box.
+ """
+ def __init__(self, pad=0.3):
+ """
+ *pad*
+ amount of padding
+ """
+
+ self.pad = pad
+ super(BoxStyle.Square, self).__init__()
- x0, y0 = x0-pad, y0-pad,
- x1, y1 = x0+width, y0 + height
+ def transmute(self, x0, y0, width, height, mutation_size):
- # Round corners are implemented as quadratic bezier. eg.
- # [(x0, y0-dr), (x0, y0), (x0+dr, y0)] for lower left corner.
- cp = [(x0+dr, y0),
- (x1-dr, y0),
- (x1, y0), (x1, y0+dr),
- (x1, y1-dr),
- (x1, y1), (x1-dr, y1),
- (x0+dr, y1),
- (x0, y1), (x0, y1-dr),
- (x0, y0+dr),
- (x0, y0), (x0+dr, y0),
- (x0+dr, y0)]
+ # padding
+ pad = mutation_size * self.pad
- com = [Path.MOVETO,
- Path.LINETO,
- Path.CURVE3, Path.CURVE3,
- Path.LINETO,
- Path.CURVE3, Path.CURVE3,
- Path.LINETO,
- Path.CURVE3, Path.CURVE3,
- Path.LINETO,
- Path.CURVE3, Path.CURVE3,
- Path.CLOSEPOLY]
+ # width and height with padding added.
+ width, height = width + 2.*pad, \
+ height + 2.*pad,
- path = Path(cp, com)
+ # boundary of the padded box
+ x0, y0 = x0-pad, y0-pad,
+ x1, y1 = x0+width, y0 + height
- return path
+ cp = [(x0, y0), (x1, y0), (x1, y1), (x0, y1),
+ (x0, y0), (x0, y0)]
+ com = [Path.MOVETO,
+ Path.LINETO,
+ Path.LINETO,
+ Path.LINETO,
+ Path.LINETO,
+ Path.CLOSEPOLY]
-class Round4BoxTransmuter(BboxTransmuterBase):
- """
- A box with round edges.
- """
+ path = Path(cp, com)
- def __init__(self, pad=0.3, rounding_size=None):
- self.pad = pad
- self.rounding_size = rounding_size
- BboxTransmuterBase.__init__(self)
+ return path
- def transmute(self, x0, y0, width, height, mutation_size):
+ _style_list["square"] = Square
- # padding
- pad = mutation_size * self.pad
- # roudning size. Use a half of the pad if not set.
- if self.rounding_size:
- dr = mutation_size * self.rounding_size
- else:
- dr = pad / 2.
+ class LArrow(_Base):
+ """
+ (left) Arrow Box
+ """
- width, height = width + 2.*pad - 2*dr, \
- height + 2.*pad - 2*dr,
+ def __init__(self, pad=0.3):
+ self.pad = pad
+ super(BoxStyle.LArrow, self).__init__()
+ def transmute(self, x0, y0, width, height, mutation_size):
- x0, y0 = x0-pad+dr, y0-pad+dr,
- x1, y1 = x0+width, y0 + height
+ # padding
+ pad = mutation_size * self.pad
+ # width and height with padding added.
+ width, height = width + 2.*pad, \
+ height + 2.*pad,
- cp = [(x0, y0),
- (x0+dr, y0-dr), (x1-dr, y0-dr), (x1, y0),
- (x1+dr, y0+dr), (x1+dr, y1-dr), (x1, y1),
- (x1-dr, y1+dr), (x0+dr, y1+dr), (x0, y1),
- (x0-dr, y1-dr), (x0-dr, y0+dr), (x0, y0),
- (x0, y0)]
+ # boundary of the padded box
+ x0, y0 = x0-pad, y0-pad,
+ x1, y1 = x0+width, y0 + height
- com = [Path.MOVETO,
- Path.CURVE4, Path.CURVE4, Path.CURVE4,
- Path.CURVE4, Path.CURVE4, Path.CURVE4,
- Path.CURVE4, Path.CURVE4, Path.CURVE4,
- Path.CURVE4, Path.CURVE4, Path.CURVE4,
- Path.CLOSEPOLY]
+ dx = (y1-y0)/2.
+ dxx = dx*.5
+ # adjust x0. 1.4 <- sqrt(2)
+ x0 = x0 + pad / 1.4
+
+ cp = [(x0+dxx, y0), (x1, y0), (x1, y1), (x0+dxx, y1),
+ (x0+dxx, y1+dxx), (x0-dx, y0+dx), (x0+dxx, y0-dxx), # arrow
+ (x0+dxx, y0), (x0+dxx, y0)]
- path = Path(cp, com)
+ com = [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO,
+ Path.LINETO, Path.LINETO, Path.LINETO,
+ Path.LINETO, Path.CLOSEPOLY]
- return path
+ path = Path(cp, com)
+ return path
+ _style_list["larrow"] = LArrow
-class SawtoothBoxTransmuter(BboxTransmuterBase):
- """
- A sawtooth box.
- """
+ class RArrow(LArrow):
+ """
+ (right) Arrow Box
+ """
- def __init__(self, pad=0.3, tooth_size=None):
- self.pad = pad
- self.tooth_size = tooth_size
- BboxTransmuterBase.__init__(self)
+ def __init__(self, pad=0.3):
+ self.pad = pad
+ super(BoxStyle.RArrow, self).__init__()
- def _get_sawtooth_vertices(self, x0, y0, width, height, mutation_size):
+ def transmute(self, x0, y0, width, height, mutation_size):
+ p = BoxStyle.LArrow.transmute(self, x0, y0,
+ width, height, mutation_size)
- # padding
- pad = mutation_size * self.pad
+ p.vertices[:,0] = 2*x0 + width - p.vertices[:,0]
- # size of sawtooth
- if self.tooth_size is None:
- tooth_size = self.pad * .5 * mutation_size
- else:
- tooth_size = self.tooth_size * mutation_size
+ return p
- tooth_size2 = tooth_size / 2.
- width, height = width + 2.*pad - tooth_size, \
- height + 2.*pad - tooth_size,
+
+ _style_list["rarrow"] = RArrow
- # the sizes of the vertical and horizontal sawtooth are
- # separately adjusted to fit the given box size.
- dsx_n = int(round((width - tooth_size) / (tooth_size * 2))) * 2
- dsx = (width - tooth_size) / dsx_n
- dsy_n = int(round((height - tooth_size) / (tooth_size * 2))) * 2
- dsy = (height - tooth_size) / dsy_n
+ class Round(_Base):
+ """
+ A box with round corners.
+ """
- x0, y0 = x0-pad+tooth_size2, y0-pad+tooth_size2
- x1, y1 = x0+width, y0 + height
+ def __init__(self, pad=0.3, rounding_size=None):
+ """
+ *pad*
+ amount of padding
+ *rounding_size*
+ rounding radius of corners. *pad* if None
+ """
+ self.pad = pad
+ self.rounding_size = rounding_size
+ super(BoxStyle.Round, self).__init__()
- bottom_saw_x = [x0] + \
- [x0 + tooth_size2 + dsx*.5* i for i in range(dsx_n*2)] + \
- [x1 - tooth_size2]
- bottom_saw_y = [y0] + \
- [y0 - tooth_size2, y0, y0 + tooth_size2, y0] * dsx_n + \
- [y0 - tooth_size2]
+ def transmute(self, x0, y0, width, height, mutation_size):
- right_saw_x = [x1] + \
- [x1 + tooth_size2, x1, x1 - tooth_size2, x1] * dsx_n + \
- [x1 + tooth_size2]
- right_saw_y = [y0] + \
- [y0 + tooth_size2 + dsy*.5* i for i in range(dsy_n*2)] + \
- [y1 - tooth_size2]
+ # padding
+ pad = mutation_size * self.pad
- top_saw_x = [x1] + \
- [x1 - tooth_size2 - dsx*.5* i for i in range(dsx_n*2)] + \
- [x0 + tooth_size2]
- top_saw_y = [y1] + \
- [y1 + tooth_size2, y1, y1 - tooth_size2, y1] * dsx_n + \
- [y1 + tooth_size2]
+ # size of the roudning corner
+ if self.rounding_size:
+ dr = mutation_size * self.rounding_size
+ else:
+ dr = pad
- left_saw_x = [x0] + \
- [x0 - tooth_size2, x0, x0 + tooth_size2, x0] * dsy_n + \
- [x0 - tooth_size2]
- left_saw_y = [y1] + \
- [y1 - tooth_size2 - dsy*.5* i for i in range(dsy_n*2)] + \
- [y0 + tooth_size2]
+ width, height = width + 2.*pad, \
+ height + 2.*pad,
- saw_vertices = zip(bottom_saw_x, bottom_saw_y) + \
- zip(right_saw_x, right_saw_y) + \
- zip(top_saw_x, top_saw_y) + \
- zip(left_saw_x, left_saw_y) + \
- [(bottom_saw_x[0], bottom_saw_y[0])]
- return saw_vertices
+ x0, y0 = x0-pad, y0-pad,
+ x1, y1 = x0+width, y0 + height
+ # Round corners are implemented as quadratic bezier. eg.
+ # [(x0, y0-dr), (x0, y0), (x0+dr, y0)] for lower left corner.
+ cp = [(x0+dr, y0),
+ (x1-dr, y0),
+ (x1, y0), (x1, y0+dr),
+ (x1, y1-dr),
+ (x1, y1), (x1-dr, y1),
+ (x0+dr, y1),
+ (x0, y1), (x0, y1-dr),
+ (x0, y0+dr),
+ (x0, y0), (x0+dr, y0),
+ (x0+dr, y0)]
- def transmute(self, x0, y0, width, height, mutation_size):
+ com = [Path.MOVETO,
+ Path.LINETO,
+ Path.CURVE3, Path.CURVE3,
+ Path.LINETO,
+ Path.CURVE3, Path.CURVE3,
+ Path.LINETO,
+ Path.CURVE3, Path.CURVE3,
+ Path.LINETO,
+ Path.CURVE3, Path.CURVE3,
+ Path.CLOSEPOLY]
- saw_vertices = self._get_sawtooth_vertices(x0, y0, width, height, mutation_size)
- path = Path(saw_vertices)
- return path
+ path = Path(cp, com)
+ return path
-class RoundtoothBoxTransmuter(SawtoothBoxTransmuter):
- """
- A roundtooth(?) box.
- """
+ _style_list["round"] = Round
- def transmute(self, x0, y0, width, height, mutation_size):
- saw_vertices = self._get_sawtooth_vertices(x0, y0, width, height, mutation_size)
+ class Round4(_Base):
+ """
+ Another box with round edges.
+ """
- cp = [Path.MOVETO] + ([Path.CURVE3, Path.CURVE3] * ((len(saw_vertices)-1)//2))
- path = Path(saw_vertices, cp)
+ def __init__(self, pad=0.3, rounding_size=None):
+ """
+ *pad*
+ amount of padding
- return path
+ *rounding_size*
+ rounding size of edges. *pad* if None
+ """
+
+ self.pad = pad
+ self.rounding_size = rounding_size
+ super(BoxStyle.Round4, self).__init__()
+ def transmute(self, x0, y0, width, height, mutation_size):
-def _list_available_boxstyles(transmuters):
- """ a helper function of the :class:`FancyBboxPatch` to list the available
- box styles. It inspects the arguments of the __init__ methods of
- each classes and report them
- """
- import inspect
- s = []
- for name, cls in transmuters.items():
- args, varargs, varkw, defaults = inspect.getargspec(cls.__init__)
- args_string = ["%s=%s" % (argname, str(argdefault)) \
- for argname, argdefault in zip(args[1:], defaults)]
- s.append(",".join([name]+args_string))
- return s
+ # padding
+ pad = mutation_size * self.pad
+ # roudning size. Use a half of the pad if not set.
+ if self.rounding_size:
+ dr = mutation_size * self.rounding_size
+ else:
+ dr = pad / 2.
+ width, height = width + 2.*pad - 2*dr, \
+ height + 2.*pad - 2*dr,
+ x0, y0 = x0-pad+dr, y0-pad+dr,
+ x1, y1 = x0+width, y0 + height
+
+ cp = [(x0, y0),
+ (x0+dr, y0-dr), (x1-dr, y0-dr), (x1, y0),
+ (x1+dr, y0+dr), (x1+dr, y1-dr), (x1, y1),
+ (x1-dr, y1+dr), (x0+dr, y1+dr), (x0, y1),
+ (x0-dr, y1-dr), (x0-dr, y0+dr), (x0, y0),
+ (x0, y0)]
+
+ com = [Path.MOVETO,
+ Path.CURVE4, Path.CURVE4, Path.CURVE4,
+ Path.CURVE4, Path.CURVE4, Path.CURVE4,
+ Path.CURVE4, Path.CURVE4, Path.CURVE4,
+ Path.CURVE4, Path.CURVE4, Path.CURVE4,
+ Path.CLOSEPOLY]
+
+ path = Path(cp, com)
+
+ return path
+
+ _style_list["round4"] = Round4
+
+
+ class Sawtooth(_Base):
+ """
+ A sawtooth box.
+ """
+
+ def __init__(self, pad=0.3, tooth_size=None):
+ """
+ *pad*
+ amount of padding
+
+ *tooth_size*
+ size of the sawtooth. pad* if None
+ """
+ self.pad = pad
+ self.tooth_size = tooth_size
+ super(BoxStyle.Sawtooth, self).__init__()
+
+ def _get_sawtooth_vertices(self, x0, y0, width, height, mutation_size):
+
+
+ # padding
+ pad = mutation_size * self.pad
+
+ # size of sawtooth
+ if self.tooth_size is None:
+ tooth_size = self.pad * .5 * mutation_size
+ else:
+ tooth_size = self.tooth_size * mutation_size
+
+ tooth_size2 = tooth_size / 2.
+ width, height = width + 2.*pad - tooth_size, \
+ height + 2.*pad - tooth_size,
+
+ # the sizes of the vertical and horizontal sawtooth are
+ # separately adjusted to fit the given box size.
+ dsx_n = int(round((width - tooth_size) / (tooth_size * 2))) * 2
+ dsx = (width - tooth_size) / dsx_n
+ dsy_n = int(round((height - tooth_size) / (tooth_size * 2))) * 2
+ dsy = (height - tooth_size) / dsy_n
+
+
+ x0, y0 = x0-pad+tooth_size2, y0-pad+tooth_size2
+ x1, y1 = x0+width, y0 + height
+
+
+ bottom_saw_x = [x0] + \
+ [x0 + tooth_size2 + dsx*.5* i for i in range(dsx_n*2)] + \
+ [x1 - tooth_size2]
+ bottom_saw_y = [y0] + \
+ [y0 - tooth_size2, y0, y0 + tooth_size2, y0] * dsx_n + \
+ [y0 - tooth_size2]
+
+ right_saw_x = [x1] + \
+ [x1 + tooth_size2, x1, x1 - tooth_size2, x1] * dsx_n + \
+ [x1 + tooth_size2]
+ right_saw_y = [y0] + \
+ [y0 + tooth_size2 + dsy*.5* i for i in range(dsy_n*2)] + \
+ [y1 - tooth_size2]
+
+ top_saw_x = [x1] + \
+ [x1 - tooth_size2 - dsx*.5* i for i in range(dsx_n*2)] + \
+ [x0 + tooth_size2]
+ top_saw_y = [y1] + \
+ [y1 + tooth_size2, y1, y1 - tooth_size2, y1] * dsx_n + \
+ [y1 + tooth_size2]
+
+ left_saw_x = [x0] + \
+ [x0 - tooth_size2, x0, x0 + tooth_size2, x0] * dsy_n + \
+ [x0 - tooth_size2]
+ left_saw_y = [y1] + \
+ [y1 - tooth_size2 - dsy*.5* i for i in range(dsy_n*2)] + \
+ [y0 + tooth_size2]
+
+ saw_vertices = zip(bottom_saw_x, bottom_saw_y) + \
+ zip(right_saw_x, right_saw_y) + \
+ zip(top_saw_x, top_saw_y) + \
+ zip(left_saw_x, left_saw_y) + \
+ [(bottom_saw_x[0], bottom_saw_y[0])]
+
+ return saw_v...
[truncated message content] |
|
From: <as...@us...> - 2008-12-04 18:49:20
|
Revision: 6488
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6488&view=rev
Author: astraw
Date: 2008-12-04 18:49:16 +0000 (Thu, 04 Dec 2008)
Log Message:
-----------
git documentation: remove README.git and add to FAQ
Modified Paths:
--------------
trunk/matplotlib/doc/faq/installing_faq.rst
Removed Paths:
-------------
trunk/matplotlib/README.git
Deleted: trunk/matplotlib/README.git
===================================================================
--- trunk/matplotlib/README.git 2008-12-04 01:58:58 UTC (rev 6487)
+++ trunk/matplotlib/README.git 2008-12-04 18:49:16 UTC (rev 6488)
@@ -1,29 +0,0 @@
-There is an experimental `matplotlib github mirror`_ of the subversion
-repository. To make a local clone it the directory ``mpl.git``, enter
-the following commands. These instructions assume you already have a
-github login (-- they use the personal gi...@gi... clone URL
-instead of the git://github.com clone URL)::
-
- # This will create your copy in the mpl.git directory
- git clone gi...@gi...:astraw/matplotlib.git mpl.git
- cd mpl.git
- git config --add remote.origin.fetch +refs/remotes/*:refs/remotes/*
- git fetch
- git svn init --trunk=trunk/matplotlib --tags=tags https://matplotlib.svn.sourceforge.net/svnroot/matplotlib
-
- # Now just get the latest svn revisions from the SourceForge SVN repository
- git svn fetch -r 6300:HEAD
-
-.. _matplotlib github mirror: http://github.com/astraw/matplotlib
-
-To update your git repository with the latest svn updates from SourceForge::
-
- git svn rebase
-
-To list what changes will be committed to svn::
-
- git svn dcommit -n
-
-To commit your changes to svn::
-
- git svn dcommit
Modified: trunk/matplotlib/doc/faq/installing_faq.rst
===================================================================
--- trunk/matplotlib/doc/faq/installing_faq.rst 2008-12-04 01:58:58 UTC (rev 6487)
+++ trunk/matplotlib/doc/faq/installing_faq.rst 2008-12-04 18:49:16 UTC (rev 6488)
@@ -106,8 +106,50 @@
> cd matplotlib
> python setup.py install
+Install from git
+================
+There is an experimental `matplotlib github mirror`_ of the subversion
+repository. To make a local clone it the directory ``mpl.git``, enter
+the following commands::
+ # This will create your copy in the mpl.git directory
+ git clone git://github.com/astraw/matplotlib.git mpl.git
+ cd mpl.git
+ git config --add remote.origin.fetch +refs/remotes/*:refs/remotes/*
+ git fetch
+ git svn init --trunk=trunk/matplotlib --tags=tags https://matplotlib.svn.sourceforge.net/svnroot/matplotlib
+
+ # Now just get the latest svn revisions from the SourceForge SVN repository
+ git svn fetch -r 6300:HEAD
+
+.. _matplotlib github mirror: http://github.com/astraw/matplotlib
+
+To update your git repository with the latest svn updates from SourceForge::
+
+ git svn rebase
+
+To list what changes will be committed to svn::
+
+ git svn dcommit -n
+
+To commit your changes to svn::
+
+ git svn dcommit
+
+A note about git write access
+-----------------------------
+
+The matplotlib developers need to figure out if there should be write
+access to the git repository. This implies using the personal URL
+(``gi...@gi...:astraw/matplotlib.git``) rather than the public URL
+(``git://github.com/astraw/matplotlib.git``) for the
+repository. However, doing so may make life complicated in the sense
+that then there are two writeable matplotlib repositories, which must
+be synced to prevent divergence. This is probably not an
+insurmountable problem, but it is a problem that the developers should
+reach a consensus about. Watch this space...
+
Backends
========
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <lee...@us...> - 2008-12-05 00:06:31
|
Revision: 6494
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6494&view=rev
Author: leejjoon
Date: 2008-12-05 00:06:26 +0000 (Fri, 05 Dec 2008)
Log Message:
-----------
some minor changes for the legend
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/examples/pylab_examples/legend_demo3.py
trunk/matplotlib/lib/matplotlib/legend.py
trunk/matplotlib/lib/matplotlib/offsetbox.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-12-04 22:13:57 UTC (rev 6493)
+++ trunk/matplotlib/CHANGELOG 2008-12-05 00:06:26 UTC (rev 6494)
@@ -1,3 +1,7 @@
+2008-12-04 Added fancybox keyword to legend. Also applied some changes
+ for better look, including baseline adjustment of the
+ multiline texts so that it is center aligned. -JJL
+
2008-12-02 The transmuter classes in the patches.py are reorganized as
subclasses of the Style classes. A few more box and arrow
styles are added. -JJL
Modified: trunk/matplotlib/examples/pylab_examples/legend_demo3.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/legend_demo3.py 2008-12-04 22:13:57 UTC (rev 6493)
+++ trunk/matplotlib/examples/pylab_examples/legend_demo3.py 2008-12-05 00:06:26 UTC (rev 6494)
@@ -2,6 +2,7 @@
import matplotlib.pyplot as plt
import numpy as np
+import pylab
def myplot(ax):
t1 = np.arange(0.0, 1.0, 0.1)
@@ -21,7 +22,7 @@
ax3 = plt.subplot(3,1,3)
myplot(ax3)
-ax3.legend(loc=1, ncol=4, mode="expand", shadow=True)
+ax3.legend(loc=1, ncol=4, mode="expand", fancybox=False, shadow=True)
#title('Damped oscillation')
Modified: trunk/matplotlib/lib/matplotlib/legend.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/legend.py 2008-12-04 22:13:57 UTC (rev 6493)
+++ trunk/matplotlib/lib/matplotlib/legend.py 2008-12-05 00:06:26 UTC (rev 6494)
@@ -113,6 +113,7 @@
ncol=1, # number of columns
mode=None, # mode for horizontal distribution of columns. None, "expand"
+ fancybox=True,
shadow = None,
):
"""
@@ -130,6 +131,7 @@
numpoints the number of points in the legend line
prop the font property
markerscale the relative size of legend markers vs. original
+ fancybox if True, draw a frame with a round fancybox.
shadow if True, draw a shadow behind legend
scatteryoffsets a list of yoffsets for scatter symbols in legend
@@ -263,8 +265,11 @@
# The width and height of the legendPatch will be set (in the
# draw()) to the length that includes the padding. Thus we set
# pad=0 here.
- self.legendPatch.set_boxstyle("round",pad=0, #self.borderpad,
- rounding_size=0.2)
+ if fancybox == True:
+ self.legendPatch.set_boxstyle("round",pad=0,
+ rounding_size=0.2)
+ else:
+ self.legendPatch.set_boxstyle("square",pad=0)
self._set_artist_props(self.legendPatch)
@@ -378,7 +383,8 @@
labelboxes = []
for l in labels:
- textbox = TextArea(l, textprops=label_prop)
+ textbox = TextArea(l, textprops=label_prop
+ multilinebaseline=True, minimumdescent=True)
text_list.append(textbox._text)
labelboxes.append(textbox)
@@ -387,8 +393,8 @@
# The approximate height and descent of text. These values are
# only used for plotting the legend handle.
- height = self._approx_text_height() * 0.6
- descent = 0. #height/6.
+ height = self._approx_text_height() * 0.7
+ descent = 0.
# each handle needs to be drawn inside a box of
# (x, y, w, h) = (0, -descent, width, height).
@@ -440,9 +446,9 @@
legline._legmarker = legline_marker
elif isinstance(handle, Patch):
- p = Rectangle(xy=(0, -0.*descent),
+ p = Rectangle(xy=(0., 0.),
width = self.handlelength*self.fontsize,
- height=0.*descent+(height-descent)*.9,
+ height=(height-descent),
)
p.update_from(handle)
self._set_artist_props(p)
@@ -513,12 +519,12 @@
num_smallcol = self._ncol-num_largecol
# starting index of each column and number of rows in it.
- largecol = zip(range(0, num_largecol*(nrows+1), (nrows+1)),
- [nrows+1] * num_largecol)
- smallcol = zip(range(num_largecol*(nrows+1), len(handleboxes), nrows),
- [nrows] * num_smallcol)
+ largecol = safezip(range(0, num_largecol*(nrows+1), (nrows+1)),
+ [nrows+1] * num_largecol)
+ smallcol = safezip(range(num_largecol*(nrows+1), len(handleboxes), nrows),
+ [nrows] * num_smallcol)
- handle_label = zip(handleboxes, labelboxes)
+ handle_label = safezip(handleboxes, labelboxes)
columnbox = []
for i0, di in largecol+smallcol:
# pack handleBox and labelBox into itemBox
@@ -526,6 +532,8 @@
sep=self.handletextpad*self.fontsize,
children=[h, t], align="baseline")
for h, t in handle_label[i0:i0+di]]
+ # minimumdescent=False for the text of the last row of the column
+ itemBoxes[-1].get_children()[1].set_minimumdescent(False)
# pack columnBox
columnbox.append(VPacker(pad=0,
Modified: trunk/matplotlib/lib/matplotlib/offsetbox.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/offsetbox.py 2008-12-04 22:13:57 UTC (rev 6493)
+++ trunk/matplotlib/lib/matplotlib/offsetbox.py 2008-12-05 00:06:26 UTC (rev 6494)
@@ -23,9 +23,9 @@
from matplotlib.patches import bbox_artist as mbbox_artist
DEBUG=False
# for debuging use
-def bbox_artist(*kl, **kw):
+def bbox_artist(*args, **kwargs):
if DEBUG:
- mbbox_artist(*kl, **kw)
+ mbbox_artist(*args, **kwargs)
# _get_packed_offsets() and _get_aligned_offsets() are coded assuming
@@ -122,9 +122,9 @@
The OffsetBox is a simple container artist. The child artist are meant
to be drawn at a relative position to its parent.
"""
- def __init__(self, *kl, **kw):
+ def __init__(self, *args, **kwargs):
- super(OffsetBox, self).__init__(*kl, **kw)
+ super(OffsetBox, self).__init__(*args, **kwargs)
self._children = []
self._offset = (0, 0)
@@ -441,10 +441,18 @@
- def __init__(self, s, textprops=None, **kw):
+ def __init__(self, s,
+ textprops=None,
+ multilinebaseline=None,
+ minimumdescent=True,
+ ):
"""
- *s* : a string to be displayer.
- *trnaspose* : transformation matrrix
+ *s* : a string to be displayed.
+ *textprops* : property dictionary for the text
+ *multilinebaseline* : If True, baseline for multiline text is
+ adjusted so that it is (approximatedly)
+ center-aligned with singleline text.
+ *minimumdescent* : If True, the box has a minimum descent of "p".
"""
if textprops is None:
textprops = {}
@@ -462,9 +470,48 @@
self.offset_transform = mtransforms.Affine2D()
self.offset_transform.clear()
self.offset_transform.translate(0, 0)
- self._text.set_transform(self.offset_transform)
+ self._baseline_transform = mtransforms.Affine2D()
+ self._text.set_transform(self.offset_transform+self._baseline_transform)
+ self._multilinebaseline = multilinebaseline
+ self._minimumdescent = minimumdescent
+
+ def set_multilinebaseline(self, t):
+ """
+ Set multilinebaseline .
+
+ If True, baseline for multiline text is
+ adjusted so that it is (approximatedly) center-aligned with
+ singleline text.
+ """
+ self._multilinebaseline = t
+
+
+ def get_multilinebaseline(self):
+ """
+ get multilinebaseline .
+ """
+ return self._multilinebaseline
+
+
+ def set_minimumdescent(self, t):
+ """
+ Set minimumdescent .
+
+ If True, extent of the single line text is adjusted so that
+ it has minimum descent of "p"
+ """
+ self._minimumdescent = t
+
+
+ def get_minimumdescent(self):
+ """
+ get minimumdescent.
+ """
+ return self._minimumdescent
+
+
def set_transform(self, t):
"""
set_transform is ignored.
@@ -507,17 +554,34 @@
bbox, info = self._text._get_layout(renderer)
w, h = bbox.width, bbox.height
+
line = info[0][0] # first line
_, hh, dd = renderer.get_text_width_height_descent(
line, self._text._fontproperties, ismath=ismath)
- d = h-(hh-dd) # the baseline of the first line
- # for multiple lines, h or d may greater than h_ or d_.
- h_d = max(h_ - d_, h-d)
- d = max(d, d_)
- h = h_d + d
+ self._baseline_transform.clear()
+ if len(info) > 1 and self._multilinebaseline: # multi line
+ d = h-(hh-dd) # the baseline of the first line
+ d_new = 0.5 * h - 0.5 * (h_ - d_)
+
+ self._baseline_transform.translate(0, d - d_new)
+ d = d_new
+
+ else: # single line
+
+ h_d = max(h_ - d_, h-dd)
+
+ if self.get_minimumdescent():
+ ## to have a minimum descent, #i.e., "l" and "p" have same
+ ## descents.
+ d = max(dd, d_)
+ else:
+ d = dd
+
+ h = h_d + d
+
return w, h, 0., d
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <lee...@us...> - 2008-12-05 21:09:45
|
Revision: 6499
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6499&view=rev
Author: leejjoon
Date: 2008-12-05 21:09:42 +0000 (Fri, 05 Dec 2008)
Log Message:
-----------
Fixed a handlelegth bug in the legend class
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/legend.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-12-05 19:30:28 UTC (rev 6498)
+++ trunk/matplotlib/CHANGELOG 2008-12-05 21:09:42 UTC (rev 6499)
@@ -1,3 +1,6 @@
+2008-12-05 Fixed a bug that the handlelength of the new legend class
+ set too short when numpoints=1 -JJL
+
2008-12-04 Added support for data with units (e.g. dates) to
Axes.fill_between. -RM
Modified: trunk/matplotlib/lib/matplotlib/legend.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/legend.py 2008-12-05 19:30:28 UTC (rev 6498)
+++ trunk/matplotlib/lib/matplotlib/legend.py 2008-12-05 21:09:42 UTC (rev 6499)
@@ -418,7 +418,7 @@
npoints)
xdata_marker = xdata
elif npoints == 1:
- xdata = np.linspace(0, self.handlelength, 2)
+ xdata = np.linspace(0, self.handlelength*self.fontsize, 2)
xdata_marker = [0.5*self.handlelength*self.fontsize]
if isinstance(handle, Line2D):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <lee...@us...> - 2008-12-06 23:17:16
|
Revision: 6502
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6502&view=rev
Author: leejjoon
Date: 2008-12-06 23:17:10 +0000 (Sat, 06 Dec 2008)
Log Message:
-----------
Fixed a small bug in svg backend
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/backends/backend_svg.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-12-06 14:36:35 UTC (rev 6501)
+++ trunk/matplotlib/CHANGELOG 2008-12-06 23:17:10 UTC (rev 6502)
@@ -1,3 +1,6 @@
+2008-12-06 Fixed a bug in svg backend that new_figure_manager()
+ ignores keywords arguments such as figsize, etc. -JJL
+
2008-12-05 Fixed a bug that the handlelength of the new legend class
set too short when numpoints=1 -JJL
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_svg.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2008-12-06 14:36:35 UTC (rev 6501)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2008-12-06 23:17:10 UTC (rev 6502)
@@ -27,7 +27,7 @@
def new_figure_manager(num, *args, **kwargs):
FigureClass = kwargs.pop('FigureClass', Figure)
- thisFig = FigureClass(*args)
+ thisFig = FigureClass(*args, **kwargs)
canvas = FigureCanvasSVG(thisFig)
manager = FigureManagerSVG(canvas, num)
return manager
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <lee...@us...> - 2008-12-07 20:40:17
|
Revision: 6503
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6503&view=rev
Author: leejjoon
Date: 2008-12-07 20:40:12 +0000 (Sun, 07 Dec 2008)
Log Message:
-----------
drop "new" keyword of np.histogram() for numpy 1.2 or later
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/axes.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-12-06 23:17:10 UTC (rev 6502)
+++ trunk/matplotlib/CHANGELOG 2008-12-07 20:40:12 UTC (rev 6503)
@@ -1,3 +1,6 @@
+2008-12-07 drop the deprecated "new" keyword of np.histogram() for
+ numpy 1.2 or later. -JJL
+
2008-12-06 Fixed a bug in svg backend that new_figure_manager()
ignores keywords arguments such as figsize, etc. -JJL
Modified: trunk/matplotlib/lib/matplotlib/axes.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/axes.py 2008-12-06 23:17:10 UTC (rev 6502)
+++ trunk/matplotlib/lib/matplotlib/axes.py 2008-12-07 20:40:12 UTC (rev 6503)
@@ -6550,12 +6550,20 @@
# case do not autoscale axes.
binsgiven = (cbook.iterable(bins) or range != None)
+ # check the version of the numpy
+ np_version = float(".".join(np.__version__.split(".")[:2]))
+ if np_version < 1.2: # version 1.1
+ hist_kwargs = dict(range=range,
+ normed=bool(normed), new=True)
+ else: # version 1.2 and later, drop new=True
+ hist_kwargs = dict(range=range,
+ normed=bool(normed))
+
n = []
for i in xrange(len(x)):
# this will automatically overwrite bins,
# so that each histogram uses the same bins
- m, bins = np.histogram(x[i], bins, range=range,
- normed=bool(normed), new=True)
+ m, bins = np.histogram(x[i], bins, **hist_kwargs)
n.append(m)
if cumulative:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2008-12-08 15:30:58
|
Revision: 6511
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6511&view=rev
Author: jdh2358
Date: 2008-12-08 15:30:56 +0000 (Mon, 08 Dec 2008)
Log Message:
-----------
added rc param to control legend fancybox
Modified Paths:
--------------
trunk/matplotlib/examples/pylab_examples/legend_demo.py
trunk/matplotlib/examples/pylab_examples/legend_demo3.py
trunk/matplotlib/lib/matplotlib/legend.py
trunk/matplotlib/lib/matplotlib/rcsetup.py
trunk/matplotlib/matplotlibrc.template
Modified: trunk/matplotlib/examples/pylab_examples/legend_demo.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/legend_demo.py 2008-12-08 15:10:20 UTC (rev 6510)
+++ trunk/matplotlib/examples/pylab_examples/legend_demo.py 2008-12-08 15:30:56 UTC (rev 6511)
@@ -15,7 +15,7 @@
ax = plt.subplot(111)
plt.plot(a,c,'k--',a,d,'k:',a,c+d,'k')
plt.legend(('Model length', 'Data length', 'Total message length'),
- 'upper center', shadow=True)
+ 'upper center', shadow=True, fancybox=True)
plt.ylim([-1,20])
plt.grid(False)
plt.xlabel('Model complexity --->')
Modified: trunk/matplotlib/examples/pylab_examples/legend_demo3.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/legend_demo3.py 2008-12-08 15:10:20 UTC (rev 6510)
+++ trunk/matplotlib/examples/pylab_examples/legend_demo3.py 2008-12-08 15:30:56 UTC (rev 6511)
@@ -1,5 +1,6 @@
#!/usr/bin/env python
-
+import matplotlib
+matplotlib.rcParams['legend.fancybox'] = True
import matplotlib.pyplot as plt
import numpy as np
import pylab
@@ -22,7 +23,7 @@
ax3 = plt.subplot(3,1,3)
myplot(ax3)
-ax3.legend(loc=1, ncol=4, mode="expand", fancybox=False, shadow=True)
+ax3.legend(loc=1, ncol=4, mode="expand", shadow=True)
#title('Damped oscillation')
Modified: trunk/matplotlib/lib/matplotlib/legend.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/legend.py 2008-12-08 15:10:20 UTC (rev 6510)
+++ trunk/matplotlib/lib/matplotlib/legend.py 2008-12-08 15:30:56 UTC (rev 6511)
@@ -63,7 +63,7 @@
loc can be a tuple of the noramilzed coordinate values with
respect its parent.
-
+
Return value is a sequence of text, line instances that make
up the legend
"""
@@ -94,15 +94,15 @@
scatterpoints = 3, # TODO: may be an rcParam
scatteryoffsets=None,
prop = None, # properties for the legend texts
-
+
# the following dimensions are in axes coords
pad = None, # deprecated; use borderpad
- labelsep = None, # deprecated; use labelspacing
- handlelen = None, # deprecated; use handlelength
- handletextsep = None, # deprecated; use handletextpad
+ labelsep = None, # deprecated; use labelspacing
+ handlelen = None, # deprecated; use handlelength
+ handletextsep = None, # deprecated; use handletextpad
axespad = None, # deprecated; use borderaxespad
- # spacing & pad defined as a fractionof the font-size
+ # spacing & pad defined as a fractionof the font-size
borderpad = None, # the whitespace inside the legend border
labelspacing=None, #the vertical space between the legend entries
handlelength=None, # the length of the legend handles
@@ -113,7 +113,7 @@
ncol=1, # number of columns
mode=None, # mode for horizontal distribution of columns. None, "expand"
- fancybox=True,
+ fancybox=None, # True use a fancy box, false use a rounded box, none use rc
shadow = None,
):
"""
@@ -131,7 +131,7 @@
numpoints the number of points in the legend line
prop the font property
markerscale the relative size of legend markers vs. original
- fancybox if True, draw a frame with a round fancybox.
+ fancybox if True, draw a frame with a round fancybox. If None, use rc
shadow if True, draw a shadow behind legend
scatteryoffsets a list of yoffsets for scatter symbols in legend
@@ -144,7 +144,7 @@
The dimensions of pad and spacing are given as a fraction of the
fontsize. Values from rcParams will be used if None.
-
+
"""
from matplotlib.axes import Axes # local import only to avoid circularity
from matplotlib.figure import Figure # local import only to avoid circularity
@@ -172,7 +172,7 @@
# Take care the deprecated keywords
deprecated_kwds = {"pad":"borderpad",
"labelsep":"labelspacing",
- "handlelen":"handlelength",
+ "handlelen":"handlelength",
"handletextsep":"handletextpad",
"axespad":"borderaxespad"}
@@ -182,7 +182,7 @@
# conversion factor
bbox = parent.bbox
axessize_fontsize = min(bbox.width, bbox.height)/self.fontsize
-
+
for k, v in deprecated_kwds.items():
# use deprecated value if not None and if their newer
# counter part is None.
@@ -199,7 +199,7 @@
setattr(self, v, localdict[v])
del localdict
-
+
self._ncol = ncol
if self.numpoints <= 0:
@@ -265,6 +265,9 @@
# The width and height of the legendPatch will be set (in the
# draw()) to the length that includes the padding. Thus we set
# pad=0 here.
+ if fancybox is None:
+ fancybox = rcParams["legend.fancybox"]
+
if fancybox == True:
self.legendPatch.set_boxstyle("round",pad=0,
rounding_size=0.2)
@@ -318,7 +321,7 @@
# find_offset function will be provided to _legend_box and
# _legend_box will draw itself at the location of the return
- # value of the find_offset.
+ # value of the find_offset.
if self._loc == 0:
self._legend_box.set_offset(self._findoffset_best)
else:
@@ -339,7 +342,7 @@
if self.shadow:
shadow = Shadow(self.legendPatch, 2, -2)
shadow.draw(renderer)
-
+
self.legendPatch.draw(renderer)
self._legend_box.draw(renderer)
@@ -360,7 +363,7 @@
Initiallize the legend_box. The legend_box is an instance of
the OffsetBox, which is packed with legend handles and
texts. Once packed, their location is calculated during the
- drawing time.
+ drawing time.
"""
# legend_box is a HPacker, horizontally packed with
@@ -371,7 +374,7 @@
# is an instance of offsetbox.TextArea which contains legend
# text.
-
+
text_list = [] # the list of text instances
handle_list = [] # the list of text instances
@@ -394,12 +397,12 @@
# The approximate height and descent of text. These values are
# only used for plotting the legend handle.
height = self._approx_text_height() * 0.7
- descent = 0.
+ descent = 0.
# each handle needs to be drawn inside a box of
# (x, y, w, h) = (0, -descent, width, height).
# And their corrdinates should be given in the display coordinates.
-
+
# The transformation of each handle will be automatically set
# to self.get_trasnform(). If the artist does not uses its
# default trasnform (eg, Collections), you need to
@@ -413,7 +416,7 @@
if npoints > 1:
# we put some pad here to compensate the size of the
# marker
- xdata = np.linspace(0.3*self.fontsize,
+ xdata = np.linspace(0.3*self.fontsize,
(self.handlelength-0.3)*self.fontsize,
npoints)
xdata_marker = xdata
@@ -484,14 +487,14 @@
size_min]
else:
sizes = (size_max-size_min)*np.linspace(0,1,self.scatterpoints)+size_min
-
+
p = type(handle)(handle.get_numsides(),
rotation=handle.get_rotation(),
sizes=sizes,
offsets=zip(xdata_marker,ydata),
transOffset=self.get_transform(),
)
-
+
p.update_from(handle)
p.set_figure(self.figure)
p.set_clip_box(None)
@@ -534,7 +537,7 @@
for h, t in handle_label[i0:i0+di]]
# minimumdescent=False for the text of the last row of the column
itemBoxes[-1].get_children()[1].set_minimumdescent(False)
-
+
# pack columnBox
columnbox.append(VPacker(pad=0,
sep=self.labelspacing*self.fontsize,
@@ -547,7 +550,7 @@
mode = "fixed"
sep = self.columnspacing*self.fontsize
-
+
self._legend_box = HPacker(pad=self.borderpad*self.fontsize,
sep=sep, align="baseline",
mode=mode,
@@ -555,8 +558,8 @@
self.texts = text_list
self.legendHandles = handle_list
-
+
def _auto_legend_data(self):
"""
Returns list of vertices and extents covered by the plot.
@@ -655,12 +658,12 @@
LC:"S",
UC:"N",
C:"C"}
-
+
c = anchor_coefs[loc]
container = parentbbox.padded(-(self.borderaxespad) * self.fontsize)
anchored_box = bbox.anchored(c, container=container)
- return anchored_box.x0, anchored_box.y0
+ return anchored_box.x0, anchored_box.y0
def _find_best_position(self, width, height, consider=None):
Modified: trunk/matplotlib/lib/matplotlib/rcsetup.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/rcsetup.py 2008-12-08 15:10:20 UTC (rev 6510)
+++ trunk/matplotlib/lib/matplotlib/rcsetup.py 2008-12-08 15:30:56 UTC (rev 6511)
@@ -417,6 +417,7 @@
'polaraxes.grid' : [True, validate_bool], # display polar grid or not
#legend properties
+ 'legend.fancybox' : [False,validate_bool],
'legend.loc' : ['upper right',validate_legend_loc], # at some point, this should be changed to 'best'
'legend.isaxes' : [True,validate_bool], # this option is internally ignored - it never served any useful purpose
'legend.numpoints' : [2, validate_int], # the number of points in the legend line
Modified: trunk/matplotlib/matplotlibrc.template
===================================================================
--- trunk/matplotlib/matplotlibrc.template 2008-12-08 15:10:20 UTC (rev 6510)
+++ trunk/matplotlib/matplotlibrc.template 2008-12-08 15:30:56 UTC (rev 6511)
@@ -235,6 +235,8 @@
#grid.linewidth : 0.5 # in points
### Legend
+#legend.fancybox : False # if True, use a rounded box for the
+ # legend, else a rectangle
#legend.isaxes : True
#legend.numpoints : 2 # the number of points in the legend line
#legend.fontsize : large
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|