You can subscribe to this list here.
| 2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(115) |
Aug
(120) |
Sep
(137) |
Oct
(170) |
Nov
(461) |
Dec
(263) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2008 |
Jan
(120) |
Feb
(74) |
Mar
(35) |
Apr
(74) |
May
(245) |
Jun
(356) |
Jul
(240) |
Aug
(115) |
Sep
(78) |
Oct
(225) |
Nov
(98) |
Dec
(271) |
| 2009 |
Jan
(132) |
Feb
(84) |
Mar
(74) |
Apr
(56) |
May
(90) |
Jun
(79) |
Jul
(83) |
Aug
(296) |
Sep
(214) |
Oct
(76) |
Nov
(82) |
Dec
(66) |
| 2010 |
Jan
(46) |
Feb
(58) |
Mar
(51) |
Apr
(77) |
May
(58) |
Jun
(126) |
Jul
(128) |
Aug
(64) |
Sep
(50) |
Oct
(44) |
Nov
(48) |
Dec
(54) |
| 2011 |
Jan
(68) |
Feb
(52) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
| 2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <md...@us...> - 2008-12-01 15:23:52
|
Revision: 6462
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6462&view=rev
Author: mdboom
Date: 2008-12-01 15:23:49 +0000 (Mon, 01 Dec 2008)
Log Message:
-----------
Fix disappearing small markers problem.
Modified Paths:
--------------
trunk/matplotlib/src/_backend_agg.cpp
Modified: trunk/matplotlib/src/_backend_agg.cpp
===================================================================
--- trunk/matplotlib/src/_backend_agg.cpp 2008-12-01 14:51:35 UTC (rev 6461)
+++ trunk/matplotlib/src/_backend_agg.cpp 2008-12-01 15:23:49 UTC (rev 6462)
@@ -493,9 +493,11 @@
trans *= agg::trans_affine_translation(0.0, (double)height);
PathIterator marker_path(marker_path_obj);
- // The built-in markers look better if snapping is turned on.
- const bool marker_snap = true;
- // bool marker_snap = should_snap(marker_path, marker_trans);
+ // The built-in markers look better if snapping is turned on, but
+ // unfortunately, it can cause really small things to disappear.
+ // Disabling for now to revisit at a later date.
+ // const bool marker_snap = true;
+ bool marker_snap = should_snap(marker_path, marker_trans);
transformed_path_t marker_path_transformed(marker_path, marker_trans);
simplify_t marker_path_simplified(marker_path_transformed, marker_snap, false, width, height);
curve_t marker_path_curve(marker_path_simplified);
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 contain the bbox. In
+ display coordinates.
+ """
+ assert loc in range(1,11) # called only internally
- def get_window_extent(self):
- return self.legendPatch.get_window_extent()
+ BEST, UR, UL, LL, LR, R, CL, CR, LC, UC, C = range(11)
+ anchor_coefs={UR:"NE",
+ UL:"NW",
+ LL:"SW",
+ LR:"SE",
+ R:"E",
+ CL:"W",
+ CR:"E",
+ LC:"S",
+ UC:"N",
+ C:"C"}
+
+ c = anchor_coefs[loc]
- def _offset(self, ox, oy):
- 'Move all the artists by ox,oy (axes coords)'
- self._offsetTransform.clear().translate(ox, oy)
+ container = parentbbox.padded(-(self.borderaxespad) * self.fontsize)
+ anchored_box = bbox.anchored(c, container=container)
+ return anchored_box.x0, anchored_box.y0
+
def _find_best_position(self, width, height, consider=None):
- """Determine the best location to place the legend.
+ """
+ Determine the best location to place the legend.
`consider` is a list of (x, y) pairs to consider as a potential
- lower-left corner of the legend. All are axes coords.
+ lower-left corner of the legend. All are display coords.
"""
assert self.isaxes # should always hold because function is only called internally
verts, bboxes, lines = self._auto_legend_data()
- consider = [self._loc_to_axes_coords(x, width, height) for x in range(1, len(self.codes))]
+ bbox = Bbox.from_bounds(0, 0, width, height)
+ consider = [self._get_anchored_bbox(x, bbox, self.parent.bbox) for x in range(1, len(self.codes))]
- tx, ty = self.legendPatch.get_x(), self.legendPatch.get_y()
+ #tx, ty = self.legendPatch.get_x(), self.legendPatch.get_y()
candidates = []
for l, b in consider:
@@ -481,15 +671,16 @@
if line.intersects_bbox(legendBox):
badness += 1
- ox, oy = l-tx, b-ty
+ ox, oy = l, b
if badness == 0:
return ox, oy
- candidates.append((badness, (ox, oy)))
+ candidates.append((badness, (l, b)))
# rather than use min() or list.sort(), do this so that we are assured
# that in the case of two equal badnesses, the one first considered is
# returned.
+ # NOTE: list.sort() is stable.But leave as it is for now. -JJL
minCandidate = candidates[0]
for candidate in candidates:
if candidate[0] < minCandidate[0]:
@@ -499,103 +690,3 @@
return ox, oy
-
- def _loc_to_axes_coords(self, loc, width, height):
- """Convert a location code to axes coordinates.
-
- - loc: a location code in range(1, 11).
- This corresponds to the possible values for self._loc, excluding "best".
-
- - width, height: the final size of the legend, axes units.
- """
- assert loc in range(1,11) # called only internally
-
- BEST, UR, UL, LL, LR, R, CL, CR, LC, UC, C = range(11)
-
- if loc in (UL, LL, CL): # left
- x = self.axespad
- elif loc in (UR, LR, CR, R): # right
- x = 1.0 - (width + self.axespad)
- elif loc in (LC, UC, C): # center x
- x = (0.5 - width/2.0)
-
- if loc in (UR, UL, UC): # upper
- y = 1.0 - (height + self.axespad)
- elif loc in (LL, LR, LC): # lower
- y = self.axespad
- elif loc in (CL, CR, C, R): # center y
- y = (0.5 - height/2.0)
-
- return x,y
-
-
- def _update_positions(self, renderer):
- # called from renderer to allow more precise estimates of
- # widths and heights with get_window_extent
-
- if not len(self.legendHandles) and not len(self.texts): return
- def get_tbounds(text): #get text bounds in axes coords
- bbox = text.get_window_extent(renderer)
- bboxa = bbox.inverse_transformed(self.get_transform())
- return bboxa.bounds
-
- hpos = []
- for t, tabove in safezip(self.texts[1:], self.texts[:-1]):
- x,y = t.get_position()
- l,b,w,h = get_tbounds(tabove)
- b -= self.labelsep
- h += 2*self.labelsep
- hpos.append( (b,h) )
- t.set_position( (x, b-0.1*h) )
-
- # now do the same for last line
-
- l,b,w,h = get_tbounds(self.texts[-1])
- b -= self.labelsep
- h += 2*self.labelsep
- hpos.append( (b,h) )
-
- for handle, tup in safezip(self.legendHandles, hpos):
- y,h = tup
- if isinstance(handle, Line2D):
- ydata = y*np.ones(handle.get_xdata().shape, float)
- handle.set_ydata(ydata+h/2.)
- if hasattr(handle, '_legmarker'):
- handle._legmarker.set_ydata(ydata+h/2.)
- elif isinstance(handle, Rectangle):
- handle.set_y(y+1/4*h)
- handle.set_height(h/2)
- elif isinstance(handle,RegularPolyCollection):
- offsets = handle.get_offsets()
- offsets[:,1] = y+h*self._scatteryoffsets
- handle.set_offsets(offsets)
-
- # Set the data for the legend patch
- bbox = self._get_handle_text_bbox(renderer)
-
- if self.pad:
- bbox = bbox.expanded(1 + self.pad, 1 + self.pad)
- else:
- bbox = bbox.transformed(self.get_transform())
- bbox = bbox.padded(self.borderpad*self.fontsize)
- bbox = bbox.inverse_transformed(self.get_transform())
- l, b, w, h = bbox.bounds
-
- self.legendPatch.set_bounds(l, b, w, h)
-
- ox, oy = 0, 0 # center
-
- if iterable(self._loc) and len(self._loc)==2:
- xo = self.legendPatch.get_x()
- yo = self.legendPatch.get_y()
- x, y = self._loc
- ox, oy = x-xo, y-yo
- elif self._loc == 0: # "best"
- ox, oy = self._find_best_position(w, h)
- else:
- x, y = self._loc_to_axes_coords(self._loc, w, h)
- ox, oy = x-l, y-b
-
- self._offset(ox, oy)
-
-#artist.kwdocd['Legend'] = kwdoc(Legend)
Added: trunk/matplotlib/lib/matplotlib/offsetbox.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/offsetbox.py (rev 0)
+++ trunk/matplotlib/lib/matplotlib/offsetbox.py 2008-12-01 14:51:35 UTC (rev 6461)
@@ -0,0 +1,532 @@
+"""
+The OffsetBox is a simple container artist. The child artist are meant
+to be drawn at a relative position to its parent. The [VH]Packer,
+DrawingArea and TextArea are derived from the OffsetBox.
+
+The [VH]Packer automatically adjust the relative postisions of their
+children, which should be instances of the OffsetBox. This is used to
+align similar artists together, e.g., in legend.
+
+The DrawingArea can contain any Artist as a child. The
+DrawingArea has a fixed width and height. The position of children
+relative to the parent is fixed. The TextArea is contains a single
+Text instance. The width and height of the TextArea instance is the
+width and height of the its child text.
+"""
+
+
+import matplotlib.transforms as mtransforms
+import matplotlib.artist as martist
+import matplotlib.text as mtext
+import numpy as np
+
+from matplotlib.patches import bbox_artist as mbbox_artist
+DEBUG=False
+# for debuging use
+def bbox_artist(*kl, **kw):
+ if DEBUG:
+ mbbox_artist(*kl, **kw)
+
+
+# _get_packed_offsets() and _get_aligned_offsets() are coded assuming
+# that we are packing boxes horizontally. But same function will be
+# used with vertical packing.
+
+def _get_packed_offsets(wd_list, total, sep, mode="fixed"):
+ """
+ Geiven a list of (width, xdescent) of each boxes, calculate the
+ total width and the x-offset positions of each items according to
+ *mode*. xdescent is analagous to the usual descent, but along the
+ x-direction. xdescent values are currently ignored.
+
+ *wd_list* : list of (width, xdescent) of boxes to be packed.
+ *sep* : spacing between boxes
+ *total* : Intended total length. None if not used.
+ *mode* : packing mode. 'fixed', 'expand', or 'equal'.
+ """
+
+ w_list, d_list = zip(*wd_list)
+ # d_list is currently not used.
+
+ if mode == "fixed":
+ offsets_ = np.add.accumulate([0]+[w + sep for w in w_list])
+ offsets = offsets_[:-1]
+
+ if total is None:
+ total = offsets_[-1] - sep
+
+ return total, offsets
+
+ elif mode == "expand":
+ sep = (total - sum(w_list))/(len(w_list)-1.)
+ offsets_ = np.add.accumulate([0]+[w + sep for w in w_list])
+ offsets = offsets_[:-1]
+
+ return total, offsets
+
+ elif mode == "equal":
+ maxh = max(w_list)
+ if total is None:
+ total = (maxh+sep)*len(w_list)
+ else:
+ sep = float(total)/(len(w_list)) - maxh
+
+ offsets = np.array([(maxh+sep)*i for i in range(len(w_list))])
+
+ return total, offsets
+
+ else:
+ raise ValueError("Unknown mode : %s" % (mode,))
+
+
+def _get_aligned_offsets(hd_list, height, align="baseline"):
+ """
+ Geiven a list of (height, descent) of each boxes, align the boxes
+ with *align* and calculate the y-offsets of each boxes.
+ total width and the offset positions of each items according to
+ *mode*. xdescent is analagous to the usual descent, but along the
+ x-direction. xdescent values are currently ignored.
+
+ *hd_list* : list of (width, xdescent) of boxes to be aligned.
+ *sep* : spacing between boxes
+ *height* : Intended total length. None if not used.
+ *align* : align mode. 'baseline', 'top', 'bottom', or 'center'.
+ """
+
+ if height is None:
+ height = max([h for h, d in hd_list])
+
+ if align == "baseline":
+ height_descent = max([h-d for h, d in hd_list])
+ descent = max([d for h, d in hd_list])
+ height = height_descent + descent
+ offsets = [0. for h, d in hd_list]
+ elif align in ["left","top"]:
+ descent=0.
+ offsets = [d for h, d in hd_list]
+ elif align in ["right","bottom"]:
+ descent=0.
+ offsets = [height-h+d for h, d in hd_list]
+ elif align == "center":
+ descent=0.
+ offsets = [(height-h)*.5+d for h, d in hd_list]
+ else:
+ raise ValueError("Unknown Align mode : %s" % (align,))
+
+ return height, descent, offsets
+
+
+
+class OffsetBox(martist.Artist):
+ """
+ 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):
+
+ super(OffsetBox, self).__init__(*kl, **kw)
+
+ self._children = []
+ self._offset = (0, 0)
+
+ def set_figure(self, fig):
+ """
+ Set the figure
+
+ accepts a class:`~matplotlib.figure.Figure` instance
+ """
+ martist.Artist.set_figure(self, fig)
+ for c in self.get_children():
+ c.set_figure(fig)
+
+ def set_offset(self, xy):
+ """
+ Set the offset
+
+ accepts x, y, tuple, or a callable object.
+ """
+ self._offset = xy
+
+ def get_offset(self, width, height, xdescent, ydescent):
+ """
+ Get the offset
+
+ accepts extent of the box
+ """
+ if callable(self._offset):
+ return self._offset(width, height, xdescent, ydescent)
+ else:
+ return self._offset
+
+ def set_width(self, width):
+ """
+ Set the width
+
+ accepts float
+ """
+ self._width = width
+
+ def set_height(self, height):
+ """
+ Set the height
+
+ accepts float
+ """
+ self._height = height
+
+ def get_children(self):
+ """
+ Return a list of artists it contains.
+ """
+ return self._children
+
+ def get_extent_offsets(self, renderer):
+ raise Exception("")
+
+ def get_extent(self, renderer):
+ """
+ Return with, height, xdescent, ydescent of box
+ """
+ w, h, xd, yd, offsets = self.get_extent_offsets(renderer)
+ return w, h, xd, yd
+
+ def get_window_extent(self, renderer):
+ '''
+ get the bounding box in display space.
+ '''
+ w, h, xd, yd, offsets = self.get_extent_offsets(renderer)
+ px, py = self.get_offset(w, h, xd, yd)
+ return mtransforms.Bbox.from_bounds(px-xd, py-yd, w, h)
+
+ def draw(self, renderer):
+ """
+ Update the location of children if necessary and draw them
+ to the given *renderer*.
+ """
+
+ width, height, xdescent, ydescent, offsets = self.get_extent_offsets(renderer)
+
+ px, py = self.get_offset(width, height, xdescent, ydescent)
+
+ for c, (ox, oy) in zip(self.get_children(), offsets):
+ c.set_offset((px+ox, py+oy))
+ c.draw(renderer)
+
+ bbox_artist(self, renderer, fill=False, props=dict(pad=0.))
+
+
+class VPacker(OffsetBox):
+ """
+ The VPacker has its children packed vertically. It automatically
+ adjust the relative postisions of children in the drawing time.
+ """
+ def __init__(self, pad=None, sep=None, width=None, height=None,
+ align="baseline", mode="fixed",
+ children=None):
+ """
+ *pad* : boundary pad
+ *sep* : spacing between items
+ *width*, *height* : width and height of the container box.
+ calculated if None.
+ *align* : alignment of boxes
+ *mode* : packing mode
+ """
+ super(VPacker, self).__init__()
+
+ self._height = height
+ self._width = width
+ self._align = align
+ self._sep = sep
+ self._pad = pad
+ self._mode = mode
+
+ self._children = children
+
+
+ def get_extent_offsets(self, renderer):
+ """
+ update offset of childrens and return the extents of the box
+ """
+
+ whd_list = [c.get_extent(renderer) for c in self.get_children()]
+ whd_list = [(w, h, xd, (h-yd)) for w, h, xd, yd in whd_list]
+
+
+ wd_list = [(w, xd) for w, h, xd, yd in whd_list]
+ width, xdescent, xoffsets = _get_aligned_offsets(wd_list,
+ self._width,
+ self._align)
+
+ pack_list = [(h, yd) for w,h,xd,yd in whd_list]
+ height, yoffsets_ = _get_packed_offsets(pack_list, self._height,
+ self._sep, self._mode)
+
+ yoffsets = yoffsets_ + [yd for w,h,xd,yd in whd_list]
+ ydescent = height - yoffsets[0]
+ yoffsets = height - yoffsets
+
+ #w, h, xd, h_yd = whd_list[-1]
+ yoffsets = yoffsets - ydescent
+
+ return width + 2*self._pad, height + 2*self._pad, \
+ xdescent+self._pad, ydescent+self._pad, \
+ zip(xoffsets, yoffsets)
+
+
+
+class HPacker(OffsetBox):
+ """
+ The HPacker has its children packed horizontally. It automatically
+ adjust the relative postisions of children in the drawing time.
+ """
+ def __init__(self, pad=None, width=None, height=None, sep=None,
+ align="baseline", mode="fixed",
+ children=None):
+ """
+ *pad* : boundary pad
+ *sep* : spacing between items
+ *width*, *height* : width and height of the container box.
+ calculated if None.
+ *align* : alignment of boxes
+ *mode* : packing mode
+ """
+ super(HPacker, self).__init__()
+
+ self._height = height
+ self._width = width
+ self._align = align
+
+ self._sep = sep
+ self._pad = pad
+ self._mode = mode
+
+ self._children = children
+
+
+ def get_extent_offsets(self, renderer):
+ """
+ update offset of childrens and return the extents of the box
+ """
+
+ whd_list = [c.get_extent(renderer) for c in self.get_children()]
+
+ if self._height is None:
+ height_descent = max([h-yd for w,h,xd,yd in whd_list])
+ ydescent = max([yd for w,h,xd,yd in whd_list])
+ height = height_descent + ydescent
+ else:
+ height = self._height - 2*self._pad # width w/o pad
+
+ hd_list = [(h, yd) for w, h, xd, yd in whd_list]
+ height, ydescent, yoffsets = _get_aligned_offsets(hd_list,
+ self._height,
+ self._align)
+
+
+ pack_list = [(w, xd) for w,h,xd,yd in whd_list]
+ width, xoffsets_ = _get_packed_offsets(pack_list, self._width,
+ self._sep, self._mode)
+
+ xoffsets = xoffsets_ + [xd for w,h,xd,yd in whd_list]
+
+ xdescent=whd_list[0][2]
+ xoffsets = xoffsets - xdescent
+
+ return width + 2*self._pad, height + 2*self._pad, \
+ xdescent + self._pad, ydescent + self._pad, \
+ zip(xoffsets, yoffsets)
+
+
+
+class DrawingArea(OffsetBox):
+ """
+ The DrawingArea can contain any Artist as a child. The DrawingArea
+ has a fixed width and height. The position of children relative to
+ the parent is fixed.
+ """
+
+ def __init__(self, width, height, xdescent=0.,
+ ydescent=0., clip=True):
+ """
+ *width*, *height* : width and height of the container box.
+ *xdescent*, *ydescent* : descent of the box in x- and y-direction.
+ """
+
+ super(DrawingArea, self).__init__()
+
+ self.width = width
+ self.height = height
+ self.xdescent = xdescent
+ self.ydescent = ydescent
+
+ self.offset_transform = mtransforms.Affine2D()
+ self.offset_transform.clear()
+ self.offset_transform.translate(0, 0)
+
+
+ def get_transform(self):
+ """
+ Return the :class:`~matplotlib.transforms.Transform` applied
+ to the children
+ """
+ return self.offset_transform
+
+ def set_transform(self, t):
+ """
+ set_transform is ignored.
+ """
+ pass
+
+
+ def set_offset(self, xy):
+ """
+ set offset of the container.
+
+ Accept : tuple of x,y cooridnate in disokay units.
+ """
+ self._offset = xy
+
+ self.offset_transform.clear()
+ self.offset_transform.translate(xy[0], xy[1])
+
+
+ def get_offset(self):
+ """
+ return offset of the container.
+ """
+ return self._offset
+
+
+ def get_window_extent(self, renderer):
+ '''
+ get the bounding box in display space.
+ '''
+ w, h, xd, yd = self.get_extent(renderer)
+ ox, oy = self.get_offset() #w, h, xd, yd)
+ return mtransforms.Bbox.from_bounds(ox-xd, oy-yd, w, h)
+
+
+ def get_extent(self, renderer):
+ """
+ Return with, height, xdescent, ydescent of box
+ """
+ return self.width, self.height, self.xdescent, self.ydescent
+
+
+
+ def add_artist(self, a):
+ 'Add any :class:`~matplotlib.artist.Artist` to the container box'
+ self._children.append(a)
+ a.set_transform(self.get_transform())
+
+
+ def draw(self, renderer):
+ """
+ Draw the children
+ """
+
+ for c in self._children:
+ c.draw(renderer)
+
+ bbox_artist(self, renderer, fill=False, props=dict(pad=0.))
+
+
+class TextArea(OffsetBox):
+ """
+ The TextArea is contains a single Text instance. The text is
+ placed at (0,0) with baseline+left alignment. The width and height
+ of the TextArea instance is the width and height of the its child
+ text.
+ """
+
+
+
+ def __init__(self, s, textprops=None, **kw):
+ """
+ *s* : a string to be displayer.
+ *trnaspose* : transformation matrrix
+ """
+ if textprops is None:
+ textprops = {}
+
+ if not textprops.has_key("va"):
+ textprops["va"]="baseline"
+
+ self._text = mtext.Text(0, 0, s, **textprops)
+
+ OffsetBox.__init__(self)
+
+ self._children = [self._text]
+
+
+ self.offset_transform = mtransforms.Affine2D()
+ self.offset_transform.clear()
+ self.offset_transform.translate(0, 0)
+ self._text.set_transform(self.offset_transform)
+
+
+ def set_transform(self, t):
+ """
+ set_transform is ignored.
+ """
+ pass
+
+
+ def set_offset(self, xy):
+ """
+ set offset of the container.
+
+ Accept : tuple of x,y cooridnate in disokay units.
+ """
+ self._offset = xy
+
+ self.offset_transform.clear()
+ self.offset_transform.translate(xy[0], xy[1])
+
+
+ def get_offset(self):
+ """
+ return offset of the container.
+ """
+ return self._offset
+
+
+ def get_window_extent(self, renderer):
+ '''
+ get the bounding box in display space.
+ '''
+ w, h, xd, yd = self.get_extent(renderer)
+ ox, oy = self.get_offset() #w, h, xd, yd)
+ return mtransforms.Bbox.from_bounds(ox-xd, oy-yd, w, h)
+
+
+ def get_extent(self, renderer):
+ ismath = self._text.is_math_text(self._text._text)
+ _, h_, d_ = renderer.get_text_width_height_descent(
+ "lp", self._text._fontproperties, ismath=False)
+
+ 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
+
+ return w, h, 0., d
+
+
+ def draw(self, renderer):
+ """
+ Draw the children
+ """
+
+ self._text.draw(renderer)
+
+ bbox_artist(self, renderer, fill=False, props=dict(pad=0.))
+
Modified: trunk/matplotlib/lib/matplotlib/rcsetup.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/rcsetup.py 2008-12-01 14:06:49 UTC (rev 6460)
+++ trunk/matplotlib/lib/matplotlib/rcsetup.py 2008-12-01 14:51:35 UTC (rev 6461)
@@ -422,7 +422,7 @@
'legend.numpoints' : [2, validate_int], # the number of points in the legend line
'legend.fontsize' : ['large', validate_fontsize],
'legend.pad' : [0, validate_float], # was 0.2, deprecated; the fractional whitespace inside the legend border
- 'legend.borderpad' : [0.5, validate_float], # units are fontsize
+ 'legend.borderpad' : [0.4, validate_float], # units are fontsize
'legend.markerscale' : [1.0, validate_float], # the relative size of legend markers vs. original
# the following dimensions are in axes coords
@@ -433,6 +433,25 @@
'legend.shadow' : [False, validate_bool],
+ 'legend.labelspacing' : [0.5, validate_float], # the vertical space between the legend entries
+ 'legend.handlelength' : [2., validate_float], # the length of the legend lines
+ 'legend.handletextpad' : [.8, validate_float], # the space between the legend line and legend text
+ 'legend.borderaxespad' : [0.5, validate_float], # the border between the axes and legend edge
+ 'legend.columnspacing' : [2., validate_float], # the border between the axes and legend edge
+
+
+ 'legend.markerscale' : [1.0, validate_float], # the relative size of legend markers vs. original
+
+ # the following dimensions are in axes coords
+ 'legend.labelsep' : [0.010, validate_float], # the vertical space between the legend entries
+ 'legend.handlelen' : [0.05, validate_float], # the length of the legend lines
+ 'legend.handletextsep' : [0.02, validate_float], # the space between the legend line and legend text
+ 'legend.axespad' : [0.5, validate_float], # the border between the axes and legend edge
+ 'legend.shadow' : [False, validate_bool],
+
+
+
+
# tick properties
'xtick.major.size' : [4, validate_float], # major xtick size in points
'xtick.minor.size' : [2, validate_float], # minor xtick size in points
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mme...@us...> - 2008-12-01 14:07:05
|
Revision: 6460
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6460&view=rev
Author: mmetz_bn
Date: 2008-12-01 14:06:49 +0000 (Mon, 01 Dec 2008)
Log Message:
-----------
typo, close bug #2358133
Modified Paths:
--------------
trunk/matplotlib/doc/users/pyplot_tutorial.rst
Modified: trunk/matplotlib/doc/users/pyplot_tutorial.rst
===================================================================
--- trunk/matplotlib/doc/users/pyplot_tutorial.rst 2008-12-01 10:10:39 UTC (rev 6459)
+++ trunk/matplotlib/doc/users/pyplot_tutorial.rst 2008-12-01 14:06:49 UTC (rev 6460)
@@ -17,7 +17,7 @@
You may be wondering why the x-axis ranges from 0-2 and the y-axis
from 1-3. If you provide a single list or array to the
-:func:`~matplotlib.pyplot.plot` command, matplotlib assumes it a
+:func:`~matplotlib.pyplot.plot` command, matplotlib assumes it is a
sequence of y values, and automatically generates the x values for
you. Since python ranges start with 0, the default x vector has the
same length as y but starts with 0. Hence the x data are
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: <as...@us...> - 2008-11-30 18:34:04
|
Revision: 6458
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6458&view=rev
Author: astraw
Date: 2008-11-30 18:33:55 +0000 (Sun, 30 Nov 2008)
Log Message:
-----------
axes.py: Shorten source code lines so all are less than 80 chars long.
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/axes.py
Modified: trunk/matplotlib/lib/matplotlib/axes.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/axes.py 2008-11-29 21:14:26 UTC (rev 6457)
+++ trunk/matplotlib/lib/matplotlib/axes.py 2008-11-30 18:33:55 UTC (rev 6458)
@@ -266,7 +266,8 @@
ret = []
if is_string_like(tup2[1]):
- assert self.command == 'plot', 'fill needs at least 2 non-string arguments'
+ assert self.command == 'plot', ('fill needs at least 2 non-string '
+ 'arguments')
y, fmt = tup2
x, y, multicol = self._xy_from_y(y)
@@ -545,10 +546,12 @@
if len(kwargs): martist.setp(self, **kwargs)
if self.xaxis is not None:
- self._xcid = self.xaxis.callbacks.connect('units finalize', self.relim)
+ self._xcid = self.xaxis.callbacks.connect('units finalize',
+ self.relim)
if self.yaxis is not None:
- self._ycid = self.yaxis.callbacks.connect('units finalize', self.relim)
+ self._ycid = self.yaxis.callbacks.connect('units finalize',
+ self.relim)
def get_window_extent(self, *args, **kwargs):
'''
@@ -575,7 +578,8 @@
#these will be updated later as data is added
self.dataLim = mtransforms.Bbox.unit()
self.viewLim = mtransforms.Bbox.unit()
- self.transScale = mtransforms.TransformWrapper(mtransforms.IdentityTransform())
+ self.transScale = mtransforms.TransformWrapper(
+ mtransforms.IdentityTransform())
self._set_lim_and_transforms()
@@ -590,7 +594,8 @@
# Transforms the x and y axis separately by a scale factor
# It is assumed that this part will have non-linear components
- self.transScale = mtransforms.TransformWrapper(mtransforms.IdentityTransform())
+ self.transScale = mtransforms.TransformWrapper(
+ mtransforms.IdentityTransform())
# An affine transformation on the data, generally to limit the
# range of the axes
@@ -815,7 +820,8 @@
self.yaxis.cla()
self.ignore_existing_data_limits = True
- self.callbacks = cbook.CallbackRegistry(('xlim_changed', 'ylim_changed'))
+ self.callbacks = cbook.CallbackRegistry(('xlim_changed',
+ 'ylim_changed'))
if self._sharex is not None:
# major and minor are class instances with
@@ -1128,7 +1134,8 @@
changey = (self in self._shared_x_axes
and self not in self._shared_y_axes)
if changex and changey:
- warnings.warn("adjustable='datalim' cannot work with shared x and y axes")
+ warnings.warn("adjustable='datalim' cannot work with shared "
+ "x and y axes")
return
if changex:
adjust_y = False
@@ -1187,7 +1194,8 @@
self.set_aspect('equal', adjustable='box', anchor='C')
else:
- raise ValueError('Unrecognized string %s to axis; try on or off' % s)
+ raise ValueError('Unrecognized string %s to axis; '
+ 'try on or off' % s)
xmin, xmax = self.get_xlim()
ymin, ymax = self.get_ylim()
return xmin, xmax, ymin, ymax
@@ -1439,7 +1447,8 @@
if xunits!=self.xaxis.units:
#print '\tkw setting xunits', xunits
self.xaxis.set_units(xunits)
- # If the units being set imply a different converter, we need to update.
+ # If the units being set imply a different converter,
+ # we need to update.
if xdata is not None:
self.xaxis.update_units(xdata)
@@ -1447,7 +1456,8 @@
if yunits!=self.yaxis.units:
#print '\tkw setting yunits', yunits
self.yaxis.set_units(yunits)
- # If the units being set imply a different converter, we need to update.
+ # If the units being set imply a different converter,
+ # we need to update.
if ydata is not None:
self.yaxis.update_units(ydata)
@@ -1875,7 +1885,8 @@
for other in self._shared_x_axes.get_siblings(self):
if other is not self:
other.set_xlim(self.viewLim.intervalx, emit=False)
- if other.figure != self.figure and other.figure.canvas is not None:
+ if (other.figure != self.figure and
+ other.figure.canvas is not None):
other.figure.canvas.draw_idle()
return xmin, xmax
@@ -1920,15 +1931,18 @@
def get_xmajorticklabels(self):
'Get the xtick labels as a list of Text instances'
- return cbook.silent_list('Text xticklabel', self.xaxis.get_majorticklabels())
+ return cbook.silent_list('Text xticklabel',
+ self.xaxis.get_majorticklabels())
def get_xminorticklabels(self):
'Get the xtick labels as a list of Text instances'
- return cbook.silent_list('Text xticklabel', self.xaxis.get_minorticklabels())
+ return cbook.silent_list('Text xticklabel',
+ self.xaxis.get_minorticklabels())
def get_xticklabels(self, minor=False):
'Get the xtick labels as a list of Text instances'
- return cbook.silent_list('Text xticklabel', self.xaxis.get_ticklabels(minor=minor))
+ return cbook.silent_list('Text xticklabel',
+ self.xaxis.get_ticklabels(minor=minor))
def set_xticklabels(self, labels, fontdict=None, minor=False, **kwargs):
"""
@@ -1945,8 +1959,10 @@
ACCEPTS: sequence of strings
"""
- return self.xaxis.set_ticklabels(labels, fontdict, minor=minor, **kwargs)
- set_xticklabels.__doc__ = cbook.dedent(set_xticklabels.__doc__) % martist.kwdocd
+ return self.xaxis.set_ticklabels(labels, fontdict,
+ minor=minor, **kwargs)
+ set_xticklabels.__doc__ = cbook.dedent(
+ set_xticklabels.__doc__) % martist.kwdocd
def invert_yaxis(self):
"Invert the y-axis."
@@ -1959,7 +1975,7 @@
return right < left
def get_ybound(self):
- "Returns the y-axis numerical bounds in the form of lowerBound < upperBound"
+ "Return y-axis numerical bounds in the form of lowerBound < upperBound"
left, right = self.get_ylim()
if left < right:
return left, right
@@ -2044,7 +2060,8 @@
for other in self._shared_y_axes.get_siblings(self):
if other is not self:
other.set_ylim(self.viewLim.intervaly, emit=False)
- if other.figure != self.figure and other.figure.canvas is not None:
+ if (other.figure != self.figure and
+ other.figure.canvas is not None):
other.figure.canvas.draw_idle()
return ymin, ymax
@@ -2093,15 +2110,18 @@
def get_ymajorticklabels(self):
'Get the xtick labels as a list of Text instances'
- return cbook.silent_list('Text yticklabel', self.yaxis.get_majorticklabels())
+ return cbook.silent_list('Text yticklabel',
+ self.yaxis.get_majorticklabels())
def get_yminorticklabels(self):
'Get the xtick labels as a list of Text instances'
- return cbook.silent_list('Text yticklabel', self.yaxis.get_minorticklabels())
+ return cbook.silent_list('Text yticklabel',
+ self.yaxis.get_minorticklabels())
def get_yticklabels(self, minor=False):
'Get the xtick labels as a list of Text instances'
- return cbook.silent_list('Text yticklabel', self.yaxis.get_ticklabels(minor=minor))
+ return cbook.silent_list('Text yticklabel',
+ self.yaxis.get_ticklabels(minor=minor))
def set_yticklabels(self, labels, fontdict=None, minor=False, **kwargs):
"""
@@ -2118,8 +2138,10 @@
ACCEPTS: sequence of strings
"""
- return self.yaxis.set_ticklabels(labels, fontdict, minor=minor, **kwargs)
- set_yticklabels.__doc__ = cbook.dedent(set_yticklabels.__doc__) % martist.kwdocd
+ return self.yaxis.set_ticklabels(labels, fontdict,
+ minor=minor, **kwargs)
+ set_yticklabels.__doc__ = cbook.dedent(
+ set_yticklabels.__doc__) % martist.kwdocd
def xaxis_date(self, tz=None):
"""Sets up x-axis ticks and labels that treat the x data as dates.
@@ -2412,11 +2434,13 @@
disconnect to disconnect from the axes event
"""
- raise DeprecationWarning('use the callbacks CallbackRegistry instance instead')
+ raise DeprecationWarning('use the callbacks CallbackRegistry instance '
+ 'instead')
def disconnect(self, cid):
'disconnect from the Axes event.'
- raise DeprecationWarning('use the callbacks CallbackRegistry instance instead')
+ raise DeprecationWarning('use the callbacks CallbackRegistry instance '
+ 'instead')
def get_children(self):
'return a list of child artists'
@@ -2456,8 +2480,8 @@
the artist and the artist has picker set
"""
if len(args)>1:
- raise DeprecationWarning(
- 'New pick API implemented -- see API_CHANGES in the src distribution')
+ raise DeprecationWarning('New pick API implemented -- '
+ 'see API_CHANGES in the src distribution')
martist.Artist.pick(self,args[0])
def __pick(self, x, y, trans=None, among=None):
@@ -2773,7 +2797,8 @@
ymin, ymax = self.get_ybound()
- # We need to strip away the units for comparison with non-unitized bounds
+ # We need to strip away the units for comparison with
+ # non-unitized bounds
yy = self.convert_yunits( y )
scaley = (yy<ymin) or (yy>ymax)
@@ -2831,7 +2856,8 @@
xmin, xmax = self.get_xbound()
- # We need to strip away the units for comparison with non-unitized bounds
+ # We need to strip away the units for comparison with
+ # non-unitized bounds
xx = self.convert_xunits( x )
scalex = (xx<xmin) or (xx>xmax)
@@ -2993,8 +3019,9 @@
.. plot:: mpl_examples/pylab_examples/hline_demo.py
"""
if kwargs.get('fmt') is not None:
- raise DeprecationWarning(
- 'hlines now uses a collections.LineCollection and not a list of Line2D to draw; see API_CHANGES')
+ raise DeprecationWarning('hlines now uses a '
+ 'collections.LineCollection and not a '
+ 'list of Line2D to draw; see API_CHANGES')
# We do the conversion first since not all unitized data is uniform
y = self.convert_yunits( y )
@@ -3069,8 +3096,9 @@
"""
if kwargs.get('fmt') is not None:
- raise DeprecationWarning(
- 'vlines now uses a collections.LineCollection and not a list of Line2D to draw; see API_CHANGES')
+ raise DeprecationWarning('vlines now uses a '
+ 'collections.LineCollection and not a '
+ 'list of Line2D to draw; see API_CHANGES')
self._process_unit_info(xdata=x, ydata=ymin, kwargs=kwargs)
@@ -3128,10 +3156,10 @@
optional format string. For example, each of the following is
legal::
- plot(x, y) # plot x and y using the default line style and color
- plot(x, y, 'bo') # plot x and y using blue circle markers
- plot(y) # plot y using x as index array 0..N-1
- plot(y, 'r+') # ditto, but with red plusses
+ plot(x, y) # plot x and y using default line style and color
+ plot(x, y, 'bo') # plot x and y using blue circle markers
+ plot(y) # plot y using x as index array 0..N-1
+ plot(y, 'r+') # ditto, but with red plusses
If *x* and/or *y* is 2-dimensional, then the corresponding columns
will be plotted.
@@ -3247,8 +3275,8 @@
the *x* or *y* (or both) data is considered to be dates, and the
axis is labeled accordingly.
- *x* and/or *y* can be a sequence of dates represented as float days since
- 0001-01-01 UTC.
+ *x* and/or *y* can be a sequence of dates represented as float
+ days since 0001-01-01 UTC.
Keyword arguments:
@@ -3317,7 +3345,8 @@
:func:`~matplotlib.pyplot.loglog` supports all the keyword
arguments of :func:`~matplotlib.pyplot.plot` and
- :meth:`matplotlib.axes.Axes.set_xscale`/:meth:`matplotlib.axes.Axes.set_yscale`.
+ :meth:`matplotlib.axes.Axes.set_xscale` /
+ :meth:`matplotlib.axes.Axes.set_yscale`.
Notable keyword arguments:
@@ -3327,9 +3356,8 @@
*subsx*/*subsy*: [ None | sequence ]
the location of the minor *x*/*y* ticks; *None* defaults
to autosubs, which depend on the number of decades in the
- plot; see
- :meth:`matplotlib.axes.Axes.set_xscale`/:meth:`matplotlib.axes.Axes.set_yscale`
- for details
+ plot; see :meth:`matplotlib.axes.Axes.set_xscale` /
+ :meth:`matplotlib.axes.Axes.set_yscale` for details
The remaining valid kwargs are
:class:`~matplotlib.lines.Line2D` properties:
@@ -3497,8 +3525,9 @@
- *b* is the *x*-axis.
.. seealso::
- :meth:`~matplotlib.axes.Axes.plot` or :meth:`~matplotlib.axes.Axes.vlines`:
- For documentation on valid kwargs.
+ :meth:`~matplotlib.axes.Axes.plot` or
+ :meth:`~matplotlib.axes.Axes.vlines`: For documentation on
+ valid kwargs.
**Example:**
@@ -3512,8 +3541,8 @@
return self.xcorr(x, x, **kwargs)
acorr.__doc__ = cbook.dedent(acorr.__doc__) % martist.kwdocd
- def xcorr(self, x, y, normed=False, detrend=mlab.detrend_none, usevlines=False,
- maxlags=None, **kwargs):
+ def xcorr(self, x, y, normed=False, detrend=mlab.detrend_none,
+ usevlines=False, maxlags=None, **kwargs):
"""
call signature::
@@ -3581,7 +3610,8 @@
if maxlags is None: maxlags = Nx - 1
if maxlags >= Nx or maxlags < 1:
- raise ValueError('maglags must be None or strictly positive < %d'%Nx)
+ raise ValueError('maglags must be None or strictly '
+ 'positive < %d'%Nx)
lags = np.arange(-maxlags,maxlags+1)
c = c[Nx-1-maxlags:Nx+maxlags]
@@ -3723,11 +3753,13 @@
labels = []
for handle in get_handles():
label = handle.get_label()
- if label is not None and label != '' and not label.startswith('_'):
+ if (label is not None and
+ label != '' and not label.startswith('_')):
handles.append(handle)
labels.append(label)
if len(handles) == 0:
- warnings.warn("No labeled objects found. Use label='...' kwarg on individual plots.")
+ warnings.warn("No labeled objects found. "
+ "Use label='...' kwarg on individual plots.")
return None
elif len(args)==1:
@@ -3784,7 +3816,8 @@
where = kwargs.pop('where', 'pre')
if where not in ('pre', 'post', 'mid'):
- raise ValueError("'where' argument to step must be 'pre', 'post' or 'mid'")
+ raise ValueError("'where' argument to step must be "
+ "'pre', 'post' or 'mid'")
kwargs['linestyle'] = 'steps-' + where
return self.plot(x, y, *args, **kwargs)
@@ -3960,18 +3993,24 @@
# FIXME: convert the following to proper input validation
# raising ValueError; don't use assert for this.
assert len(left)==nbars, "argument 'left' must be %d or scalar" % nbars
- assert len(height)==nbars, "argument 'height' must be %d or scalar" % nbars
- assert len(width)==nbars, "argument 'width' must be %d or scalar" % nbars
- assert len(bottom)==nbars, "argument 'bottom' must be %d or scalar" % nbars
+ assert len(height)==nbars, ("argument 'height' must be %d or scalar" %
+ nbars)
+ assert len(width)==nbars, ("argument 'width' must be %d or scalar" %
+ nbars)
+ assert len(bottom)==nbars, ("argument 'bottom' must be %d or scalar" %
+ nbars)
if yerr is not None and len(yerr)!=nbars:
- raise ValueError("bar() argument 'yerr' must be len(%s) or scalar" % nbars)
+ raise ValueError(
+ "bar() argument 'yerr' must be len(%s) or scalar" % nbars)
if xerr is not None and len(xerr)!=nbars:
- raise ValueError("bar() argument 'xerr' must be len(%s) or scalar" % nbars)
+ raise ValueError(
+ "bar() argument 'xerr' must be len(%s) or scalar" % nbars)
patches = []
- # lets do some conversions now since some types cannot be subtracted uniformly
+ # lets do some conversions now since some types cannot be
+ # subtracted uniformly
if self.xaxis is not None:
xconv = self.xaxis.converter
if xconv is not None:
@@ -4189,12 +4228,13 @@
*baseline*).
.. seealso::
- `this document
- <http://www.mathworks.com/access/helpdesk/help/techdoc/ref/stem.html>`_:
- for details
+ `this document`__ for details
:file:`examples/pylab_examples/stem_plot.py`:
for a demo
+
+ __ http://www.mathworks.com/access/helpdesk/help/techdoc/ref/stem.html
+
"""
remember_hold=self._hold
if not self._hold: self.cla()
@@ -4344,7 +4384,8 @@
elif callable(autopct):
s = autopct(100.*frac)
else:
- raise TypeError('autopct must be callable or a format string')
+ raise TypeError(
+ 'autopct must be callable or a format string')
t = self.text(xt, yt, s,
horizontalalignment='center',
@@ -4449,7 +4490,8 @@
self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs)
if not self._hold: self.cla()
- # make sure all the args are iterable; use lists not arrays to preserve units
+ # make sure all the args are iterable; use lists not arrays to
+ # preserve units
if not iterable(x):
x = [x]
@@ -4521,14 +4563,19 @@
plot_kw['transform'] = kwargs['transform']
if xerr is not None:
- if iterable(xerr) and len(xerr)==2 and iterable(xerr[0]) and iterable(xerr[1]):
+ if (iterable(xerr) and len(xerr)==2 and
+ iterable(xerr[0]) and iterable(xerr[1])):
# using list comps rather than arrays to preserve units
- left = [thisx-thiserr for (thisx, thiserr) in cbook.safezip(x,xerr[0])]
- right = [thisx+thiserr for (thisx, thiserr) in cbook.safezip(x,xerr[1])]
+ left = [thisx-thiserr for (thisx, thiserr)
+ in cbook.safezip(x,xerr[0])]
+ right = [thisx+thiserr for (thisx, thiserr)
+ in cbook.safezip(x,xerr[1])]
else:
# using list comps rather than arrays to preserve units
- left = [thisx-thiserr for (thisx, thiserr) in cbook.safezip(x,xerr)]
- right = [thisx+thiserr for (thisx, thiserr) in cbook.safezip(x,xerr)]
+ left = [thisx-thiserr for (thisx, thiserr)
+ in cbook.safezip(x,xerr)]
+ right = [thisx+thiserr for (thisx, thiserr)
+ in cbook.safezip(x,xerr)]
barcols.append( self.hlines(y, left, right, **lines_kw ) )
if capsize > 0:
@@ -4537,7 +4584,9 @@
# y are lists
leftlo, ylo = xywhere(left, y, xlolims)
- caplines.extend( self.plot(leftlo, ylo, ls='None', marker=mlines.CARETLEFT, **plot_kw) )
+ caplines.extend(
+ self.plot(leftlo, ylo, ls='None',
+ marker=mlines.CARETLEFT, **plot_kw) )
xlolims = ~xlolims
leftlo, ylo = xywhere(left, y, xlolims)
caplines.extend( self.plot(leftlo, ylo, 'k|', **plot_kw) )
@@ -4547,7 +4596,9 @@
if xuplims.any():
rightup, yup = xywhere(right, y, xuplims)
- caplines.extend( self.plot(rightup, yup, ls='None', marker=mlines.CARETRIGHT, **plot_kw) )
+ caplines.extend(
+ self.plot(rightup, yup, ls='None',
+ marker=mlines.CARETRIGHT, **plot_kw) )
xuplims = ~xuplims
rightup, yup = xywhere(right, y, xuplims)
caplines.extend( self.plot(rightup, yup, 'k|', **plot_kw) )
@@ -4555,21 +4606,28 @@
caplines.extend( self.plot(right, y, 'k|', **plot_kw) )
if yerr is not None:
- if iterable(yerr) and len(yerr)==2 and iterable(yerr[0]) and iterable(yerr[1]):
+ if (iterable(yerr) and len(yerr)==2 and
+ iterable(yerr[0]) and iterable(yerr[1])):
# using list comps rather than arrays to preserve units
- lower = [thisy-thiserr for (thisy, thiserr) in cbook.safezip(y,yerr[0])]
- upper = [thisy+thiserr for (thisy, thiserr) in cbook.safezip(y,yerr[1])]
+ lower = [thisy-thiserr for (thisy, thiserr)
+ in cbook.safezip(y,yerr[0])]
+ upper = [thisy+thiserr for (thisy, thiserr)
+ in cbook.safezip(y,yerr[1])]
else:
# using list comps rather than arrays to preserve units
- lower = [thisy-thiserr for (thisy, thiserr) in cbook.safezip(y,yerr)]
- upper = [thisy+thiserr for (thisy, thiserr) in cbook.safezip(y,yerr)]
+ lower = [thisy-thiserr for (thisy, thiserr)
+ in cbook.safezip(y,yerr)]
+ upper = [thisy+thiserr for (thisy, thiserr)
+ in cbook.safezip(y,yerr)]
barcols.append( self.vlines(x, lower, upper, **lines_kw) )
if capsize > 0:
if lolims.any():
xlo, lowerlo = xywhere(x, lower, lolims)
- caplines.extend( self.plot(xlo, lowerlo, ls='None', marker=mlines.CARETDOWN, **plot_kw) )
+ caplines.extend(
+ self.plot(xlo, lowerlo, ls='None',
+ marker=mlines.CARETDOWN, **plot_kw) )
lolims = ~lolims
xlo, lowerlo = xywhere(x, lower, lolims)
caplines.extend( self.plot(xlo, lowerlo, 'k_', **plot_kw) )
@@ -4579,7 +4637,9 @@
if uplims.any():
xup, upperup = xywhere(x, upper, uplims)
- caplines.extend( self.plot(xup, upperup, ls='None', marker=mlines.CARETUP, **plot_kw) )
+ caplines.extend(
+ self.plot(xup, upperup, ls='None',
+ marker=mlines.CARETUP, **plot_kw) )
uplims = ~uplims
xup, upperup = xywhere(x, upper, uplims)
caplines.extend( self.plot(xup, upperup, 'k_', **plot_kw) )
@@ -4962,8 +5022,9 @@
edgecolors = None
else:
edgecolors = 'none'
- warnings.warn('''replace "faceted=False" with "edgecolors='none'"''',
- DeprecationWarning) #2008/04/18
+ warnings.warn(
+ '''replace "faceted=False" with "edgecolors='none'"''',
+ DeprecationWarning) #2008/04/18
sym = None
symstyle = 0
@@ -5302,7 +5363,8 @@
else:
lattice2[i,j] = np.nan
- accum = np.hstack(( lattice1.astype(float).ravel(), lattice2.astype(float).ravel() ))
+ accum = np.hstack((
+ lattice1.astype(float).ravel(), lattice2.astype(float).ravel()))
good_idxs = ~np.isnan(accum)
px = xmin + sx * np.array([ 0.5, 0.5, 0.0, -0.5, -0.5, 0.0])
@@ -5734,7 +5796,8 @@
Y = y.repeat(Nx, axis=1)
if X.shape != Y.shape:
raise TypeError(
- 'Incompatible X, Y inputs to %s; see help(%s)' % (funcname, funcname))
+ 'Incompatible X, Y inputs to %s; see help(%s)' % (
+ funcname, funcname))
return X, Y, C
def pcolor(self, *args, **kwargs):
@@ -6025,7 +6088,8 @@
Ny, Nx = X.shape
# convert to one dimensional arrays
- C = ma.ravel(C[0:Ny-1, 0:Nx-1]) # data point in each cell is value at lower left corner
+ C = ma.ravel(C[0:Ny-1, 0:Nx-1]) # data point in each cell is value at
+ # lower left corner
X = X.ravel()
Y = Y.ravel()
@@ -6039,7 +6103,8 @@
showedges = 0
collection = mcoll.QuadMesh(
- Nx - 1, Ny - 1, coords, showedges, antialiased=antialiased) # kwargs are not used
+ Nx - 1, Ny - 1, coords, showedges,
+ antialiased=antialiased) # kwargs are not used
collection.set_alpha(alpha)
collection.set_array(C)
if norm is not None: assert(isinstance(norm, mcolors.Normalize))
@@ -6184,7 +6249,8 @@
# convert to one dimensional arrays
# This should also be moved to the QuadMesh class
- C = ma.ravel(C) # data point in each cell is value at lower left corner
+ C = ma.ravel(C) # data point in each cell is value
+ # at lower left corner
X = x.ravel()
Y = y.ravel()
Nx = nc+1
@@ -6446,7 +6512,8 @@
if kwargs.get('width') is not None:
raise DeprecationWarning(
- 'hist now uses the rwidth to give relative width and not absolute width')
+ 'hist now uses the rwidth to give relative width '
+ 'and not absolute width')
try:
# make sure a copy is created: don't use asarray
@@ -6454,7 +6521,8 @@
if len(x.shape)==1:
x.shape = (1,x.shape[0])
elif len(x.shape)==2 and x.shape[1]<x.shape[0]:
- warnings.warn('2D hist should be nsamples x nvariables; this looks transposed')
+ warnings.warn('2D hist should be nsamples x nvariables; '
+ 'this looks transposed')
except ValueError:
# multiple hist with data of different length
if iterable(x[0]) and not is_string_like(x[0]):
@@ -6957,7 +7025,8 @@
mask = np.absolute(Z)>precision
if 'cmap' not in kwargs:
- kwargs['cmap'] = mcolors.ListedColormap(['w', 'k'], name='binary')
+ kwargs['cmap'] = mcolors.ListedColormap(['w', 'k'],
+ name='binary')
nr, nc = Z.shape
extent = [-0.5, nc-0.5, nr-0.5, -0.5]
ret = self.imshow(mask, interpolation='nearest', aspect=aspect,
@@ -7072,7 +7141,8 @@
total = rows*cols
- num -= 1 # convert from matlab to python indexing ie num in range(0,total)
+ num -= 1 # convert from matlab to python indexing
+ # ie num in range(0,total)
if num >= total:
raise ValueError( 'Subplot number exceeds total subplots')
self._rows = rows
@@ -7125,7 +7195,8 @@
figBottom = top - (rowNum+1)*figH - rowNum*sepH
figLeft = left + colNum*(figW + sepW)
- self.figbox = mtransforms.Bbox.from_bounds(figLeft, figBottom, figW, figH)
+ self.figbox = mtransforms.Bbox.from_bounds(figLeft, figBottom,
+ figW, figH)
self.rowNum = rowNum
self.colNum = colNum
self.numRows = rows
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ds...@us...> - 2008-11-29 21:14:33
|
Revision: 6457
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6457&view=rev
Author: dsdale
Date: 2008-11-29 21:14:26 +0000 (Sat, 29 Nov 2008)
Log Message:
-----------
added support for leave_notify_event in backend_qt4
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py 2008-11-29 02:20:56 UTC (rev 6456)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py 2008-11-29 21:14:26 UTC (rev 6457)
@@ -105,6 +105,9 @@
def __timerEvent(self, event):
# hide until we can test and fix
self.mpl_idle_event(event)
+
+ def leaveEvent(self, event):
+ FigureCanvasBase.leave_notify_event(self, event)
def mousePressEvent( self, event ):
x = event.pos().x()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ef...@us...> - 2008-11-29 02:21:03
|
Revision: 6456
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6456&view=rev
Author: efiring
Date: 2008-11-29 02:20:56 +0000 (Sat, 29 Nov 2008)
Log Message:
-----------
Make scale colors match line colors in two_scales.py
Modified Paths:
--------------
trunk/matplotlib/examples/api/two_scales.py
Modified: trunk/matplotlib/examples/api/two_scales.py
===================================================================
--- trunk/matplotlib/examples/api/two_scales.py 2008-11-26 18:59:58 UTC (rev 6455)
+++ trunk/matplotlib/examples/api/two_scales.py 2008-11-29 02:20:56 UTC (rev 6456)
@@ -30,13 +30,17 @@
s1 = np.exp(t)
ax1.plot(t, s1, 'b-')
ax1.set_xlabel('time (s)')
-ax1.set_ylabel('exp')
+# Make the y-axis label and tick labels match the line color.
+ax1.set_ylabel('exp', color='b')
+for tl in ax1.get_yticklabels():
+ tl.set_color('b')
-# turn off the 2nd axes rectangle with frameon kwarg
ax2 = ax1.twinx()
s2 = np.sin(2*np.pi*t)
ax2.plot(t, s2, 'r.')
-ax2.set_ylabel('sin')
+ax2.set_ylabel('sin', color='r')
+for tl in ax2.get_yticklabels():
+ tl.set_color('r')
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-26 19:00:03
|
Revision: 6455
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6455&view=rev
Author: jdh2358
Date: 2008-11-26 18:59:58 +0000 (Wed, 26 Nov 2008)
Log Message:
-----------
fixed leave_notify_event for gtk -- need support for other UIs
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/backend_bases.py
trunk/matplotlib/lib/matplotlib/backends/backend_gtk.py
Modified: trunk/matplotlib/lib/matplotlib/backend_bases.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backend_bases.py 2008-11-26 17:43:09 UTC (rev 6454)
+++ trunk/matplotlib/lib/matplotlib/backend_bases.py 2008-11-26 18:59:58 UTC (rev 6455)
@@ -744,7 +744,7 @@
ydata = None # y coord of mouse in data coords
# the last event that was triggered before this one
- _lastevent = None
+ lastevent = None
def __init__(self, name, canvas, x, y,guiEvent=None):
"""
@@ -789,11 +789,10 @@
def _update_enter_leave(self):
'process the figure/axes enter leave events'
- if LocationEvent._lastevent is not None:
- last = LocationEvent._lastevent
+ 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
@@ -810,7 +809,7 @@
self.canvas.callbacks.process('axes_enter_event', self)
- LocationEvent._lastevent = self
+ LocationEvent.lastevent = self
@@ -1205,6 +1204,19 @@
guiEvent=guiEvent)
self.callbacks.process(s, event)
+ def leave_notify_event(self, guiEvent=None):
+ """
+ Backend derived classes should call this function when leaving
+ canvas
+
+ *guiEvent*
+ the native UI event that generated the mpl event
+
+ """
+ self.callbacks.process('figure_leave_event', LocationEvent.lastevent)
+ LocationEvent.lastevent = None
+
+
def idle_event(self, guiEvent=None):
'call when GUI is idle'
s = 'idle_event'
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_gtk.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_gtk.py 2008-11-26 17:43:09 UTC (rev 6454)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_gtk.py 2008-11-26 18:59:58 UTC (rev 6455)
@@ -170,6 +170,7 @@
self.connect('key_press_event', self.key_press_event)
self.connect('key_release_event', self.key_release_event)
self.connect('motion_notify_event', self.motion_notify_event)
+ self.connect('leave_notify_event', self.leave_notify_event)
self.set_events(self.__class__.event_mask)
@@ -239,6 +240,9 @@
FigureCanvasBase.motion_notify_event(self, x, y)
return False # finish event propagation?
+ def leave_notify_event(self, widget, event):
+ FigureCanvasBase.leave_notify_event(self, event)
+
def _get_key(self, event):
if event.keyval in self.keyvald:
key = self.keyvald[event.keyval]
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: <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-25 21:14:22
|
Revision: 6452
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6452&view=rev
Author: jdh2358
Date: 2008-11-25 21:14:13 +0000 (Tue, 25 Nov 2008)
Log Message:
-----------
added a chance for polar with usetex to remove unicode symbol
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/projections/polar.py
Modified: trunk/matplotlib/lib/matplotlib/projections/polar.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/projections/polar.py 2008-11-25 21:13:09 UTC (rev 6451)
+++ trunk/matplotlib/lib/matplotlib/projections/polar.py 2008-11-25 21:14:13 UTC (rev 6452)
@@ -136,7 +136,7 @@
"""
def __call__(self, x, pos=None):
# \u00b0 : degree symbol
- if rcParams['text.usetex']:
+ if rcParams['text.usetex'] and not rcParams['text.latex.unicode']:
return r"$%d^\circ$" % ((x / npy.pi) * 180.0)
else:
return u"%d\u00b0" % ((x / npy.pi) * 180.0)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2008-11-25 21:13:17
|
Revision: 6451
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6451&view=rev
Author: jdh2358
Date: 2008-11-25 21:13:09 +0000 (Tue, 25 Nov 2008)
Log Message:
-----------
added a chance for polar with usetex to remove unicode symbol
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/projections/polar.py
Modified: trunk/matplotlib/lib/matplotlib/projections/polar.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/projections/polar.py 2008-11-25 19:56:39 UTC (rev 6450)
+++ trunk/matplotlib/lib/matplotlib/projections/polar.py 2008-11-25 21:13:09 UTC (rev 6451)
@@ -136,7 +136,10 @@
"""
def __call__(self, x, pos=None):
# \u00b0 : degree symbol
- return u"%d\u00b0" % ((x / npy.pi) * 180.0)
+ if rcParams['text.usetex']:
+ return r"$%d^\circ$" % ((x / npy.pi) * 180.0)
+ else:
+ return u"%d\u00b0" % ((x / npy.pi) * 180.0)
class RadialLocator(Locator):
"""
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2008-11-25 19:56:44
|
Revision: 6450
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6450&view=rev
Author: jdh2358
Date: 2008-11-25 19:56:39 +0000 (Tue, 25 Nov 2008)
Log Message:
-----------
removed comment from invalid shared axis merge
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/mlab.py
Modified: trunk/matplotlib/lib/matplotlib/mlab.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/mlab.py 2008-11-25 19:33:05 UTC (rev 6449)
+++ trunk/matplotlib/lib/matplotlib/mlab.py 2008-11-25 19:56:39 UTC (rev 6450)
@@ -2460,8 +2460,10 @@
# Get header and remove invalid characters
needheader = names is None
+
if needheader:
for row in reader:
+ #print 'csv2rec', row
if len(row) and row[0].startswith(comments):
continue
headers = row
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2008-11-25 19:33:15
|
Revision: 6449
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6449&view=rev
Author: mdboom
Date: 2008-11-25 19:33:05 +0000 (Tue, 25 Nov 2008)
Log Message:
-----------
Remove code that was inadvertently merged from branch.
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/backend_bases.py
Modified: trunk/matplotlib/lib/matplotlib/backend_bases.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backend_bases.py 2008-11-25 18:56:57 UTC (rev 6448)
+++ trunk/matplotlib/lib/matplotlib/backend_bases.py 2008-11-25 19:33:05 UTC (rev 6449)
@@ -1883,14 +1883,7 @@
for cur_xypress in self._xypress:
x, y = event.x, event.y
lastx, lasty, a, ind, lim, trans = cur_xypress
- # JDH: I don't know why this is here but I expect to be
- # able to zoomo on any axis that is shared. This was
- # breaking zoom-to-rect on sharex_axis_demo if the zoom
- # happened in ax2 or ax3 so i am replacing the continue
- # with a pass until this is sorted out
- if a._sharex or a._sharey:
- #continue
- pass
+
# ignore singular clicks - 5 pixels is a threshold
if abs(x-lastx)<5 or abs(y-lasty)<5:
self._xypress = None
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 18:28:20
|
Revision: 6447
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6447&view=rev
Author: jdh2358
Date: 2008-11-25 18:28:13 +0000 (Tue, 25 Nov 2008)
Log Message:
-----------
fixed a zoom bug in sharex axis
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/backend_bases.py
Modified: trunk/matplotlib/lib/matplotlib/backend_bases.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backend_bases.py 2008-11-25 15:23:28 UTC (rev 6446)
+++ trunk/matplotlib/lib/matplotlib/backend_bases.py 2008-11-25 18:28:13 UTC (rev 6447)
@@ -269,7 +269,7 @@
gc.set_alpha(rgbFace[-1])
rgbFace = rgbFace[:3]
gc.set_antialiased(antialiaseds[i % Naa])
-
+
if Nurls:
gc.set_url(urls[i % Nurls])
@@ -527,7 +527,7 @@
matlab format string, a html hex color string, or a rgb tuple
"""
return self._rgb
-
+
def get_url(self):
"""
returns a url if one is set, None otherwise
@@ -633,7 +633,7 @@
raise ValueError('Unrecognized linestyle: %s' % style)
self._linestyle = style
self.set_dashes(offset, dashes)
-
+
def set_url(self, url):
"""
Sets the url for links in compatible backends
@@ -1531,7 +1531,7 @@
if event.key == 'f':
self.full_screen_toggle()
-
+
# *h*ome or *r*eset mnemonic
elif event.key == 'h' or event.key == 'r' or event.key == "home":
self.canvas.toolbar.home()
@@ -1883,8 +1883,14 @@
for cur_xypress in self._xypress:
x, y = event.x, event.y
lastx, lasty, a, ind, lim, trans = cur_xypress
+ # JDH: I don't know why this is here but I expect to be
+ # able to zoomo on any axis that is shared. This was
+ # breaking zoom-to-rect on sharex_axis_demo if the zoom
+ # happened in ax2 or ax3 so i am replacing the continue
+ # with a pass until this is sorted out
if a._sharex or a._sharey:
- continue
+ #continue
+ pass
# ignore singular clicks - 5 pixels is a threshold
if abs(x-lastx)<5 or abs(y-lasty)<5:
self._xypress = None
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2008-11-25 15:23:32
|
Revision: 6446
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6446&view=rev
Author: mdboom
Date: 2008-11-25 15:23:28 +0000 (Tue, 25 Nov 2008)
Log Message:
-----------
Fix mathtext (bug has existed since r6400 11/12/2008)
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/font_manager.py
Modified: trunk/matplotlib/lib/matplotlib/font_manager.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/font_manager.py 2008-11-25 04:03:59 UTC (rev 6445)
+++ trunk/matplotlib/lib/matplotlib/font_manager.py 2008-11-25 15:23:28 UTC (rev 6446)
@@ -592,7 +592,7 @@
verbose.report("Cannot handle unicode filenames")
#print >> sys.stderr, 'Bad file is', fpath
continue
- try: prop = ttfFontProperty(fpath, font)
+ try: prop = ttfFontProperty(font)
except: continue
fontlist.append(prop)
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: <md...@us...> - 2008-11-24 20:18:42
|
Revision: 6444
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6444&view=rev
Author: mdboom
Date: 2008-11-24 20:18:38 +0000 (Mon, 24 Nov 2008)
Log Message:
-----------
Remove conflict markers from CHANGELOG.
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-11-24 20:14:21 UTC (rev 6443)
+++ trunk/matplotlib/CHANGELOG 2008-11-24 20:18:38 UTC (rev 6444)
@@ -29,6 +29,8 @@
2008-11-09 Fix a possible EINTR problem in dviread, which might help
when saving pdf files from the qt backend. - JKS
+2008-11-05 Fix bug with zoom to rectangle and twin axes - MGD
+
2008-10-24 Added Jae Joon's fancy arrow, box and annotation
enhancements -- see
examples/pylab_examples/annotation_demo2.py
@@ -53,10 +55,6 @@
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
@@ -100,9 +98,6 @@
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
-
2008-09-07 Changed full arrows slightly to avoid an xpdf rendering
problem reported by Friedrich Hagedorn. - JKS
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:14:24
|
Revision: 6443
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6443&view=rev
Author: mdboom
Date: 2008-11-24 20:14:21 +0000 (Mon, 24 Nov 2008)
Log Message:
-----------
[ 2314869 ] Log base-2 axes fail with certain axis limits
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-11-24 20:12:55 UTC (rev 6442)
+++ trunk/matplotlib/CHANGELOG 2008-11-24 20:14:21 UTC (rev 6443)
@@ -103,7 +103,6 @@
=======
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
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-24 03:53:17
|
Revision: 6441
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6441&view=rev
Author: jdh2358
Date: 2008-11-24 03:53:14 +0000 (Mon, 24 Nov 2008)
Log Message:
-----------
fixed a small bug in fill_between
Modified Paths:
--------------
trunk/matplotlib/examples/pylab_examples/fill_between.py
Modified: trunk/matplotlib/examples/pylab_examples/fill_between.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/fill_between.py 2008-11-23 20:15:36 UTC (rev 6440)
+++ trunk/matplotlib/examples/pylab_examples/fill_between.py 2008-11-24 03:53:14 UTC (rev 6441)
@@ -28,7 +28,7 @@
# because of edge effects over multiple contiguous regions.
fig = figure()
ax = fig.add_subplot(111)
-ax1.plot(x, y1, x, y2, color='black')
+ax.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')
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2008-11-23 20:15:39
|
Revision: 6440
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6440&view=rev
Author: jdh2358
Date: 2008-11-23 20:15:36 +0000 (Sun, 23 Nov 2008)
Log Message:
-----------
fixed datalim update for fill_between
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/axes.py
Modified: trunk/matplotlib/lib/matplotlib/axes.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/axes.py 2008-11-23 20:09:08 UTC (rev 6439)
+++ trunk/matplotlib/lib/matplotlib/axes.py 2008-11-23 20:15:36 UTC (rev 6440)
@@ -5559,8 +5559,14 @@
collection = mcoll.PolyCollection(polys, **kwargs)
- self.update_datalim_numerix(x[where], y1[where])
- self.update_datalim_numerix(x[where], y2[where])
+ # now update the datalim and autoscale
+ XY1 = np.array([x[where], y1[where]]).T
+ XY2 = np.array([x[where], y2[where]]).T
+ self.dataLim.update_from_data_xy(XY1, self.ignore_existing_data_limits,
+ updatex=True, updatey=True)
+
+ self.dataLim.update_from_data_xy(XY2, self.ignore_existing_data_limits,
+ updatex=False, updatey=True)
self.add_collection(collection)
self.autoscale_view()
return collection
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2008-11-23 20:09:11
|
Revision: 6439
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6439&view=rev
Author: jdh2358
Date: 2008-11-23 20:09:08 +0000 (Sun, 23 Nov 2008)
Log Message:
-----------
removed deprecated example
Modified Paths:
--------------
trunk/matplotlib/examples/pylab_examples/fill_between.py
Modified: trunk/matplotlib/examples/pylab_examples/fill_between.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/fill_between.py 2008-11-23 19:57:18 UTC (rev 6438)
+++ trunk/matplotlib/examples/pylab_examples/fill_between.py 2008-11-23 20:09:08 UTC (rev 6439)
@@ -22,6 +22,10 @@
ax3.set_ylabel('between y1 and y2')
ax3.set_xlabel('x')
+# now fill between y1 and y2 where a logical condition is met. Note
+# this is different than calling
+# fill_between(x[where], y1[where],y2[where]
+# because of edge effects over multiple contiguous regions.
fig = figure()
ax = fig.add_subplot(111)
ax1.plot(x, y1, x, y2, color='black')
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:57:21
|
Revision: 6438
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6438&view=rev
Author: jdh2358
Date: 2008-11-23 19:57:18 +0000 (Sun, 23 Nov 2008)
Log Message:
-----------
removed deprecated example
Removed Paths:
-------------
trunk/matplotlib/examples/api/fill_where_demo.py
Deleted: trunk/matplotlib/examples/api/fill_where_demo.py
===================================================================
--- trunk/matplotlib/examples/api/fill_where_demo.py 2008-11-23 19:56:37 UTC (rev 6437)
+++ trunk/matplotlib/examples/api/fill_where_demo.py 2008-11-23 19:57:18 UTC (rev 6438)
@@ -1,53 +0,0 @@
-"""
-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
-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, color='black')
-ax.axhline(0, color='black', lw=2)
-
-collection = collections.PolyCollection.fill_between_where(
- t, s1, s2, where=s1>=s2, color='green', alpha=0.5)
-ax.add_collection(collection)
-
-collection = collections.PolyCollection.fill_between_where(
- 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_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()
-
-
-
-
-
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|