From: <jd...@us...> - 2010-02-22 23:23:11
|
Revision: 8149 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8149&view=rev Author: jdh2358 Date: 2010-02-22 23:23:05 +0000 (Mon, 22 Feb 2010) Log Message: ----------- support LogNorm as arg to hexbin Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/axes.py trunk/matplotlib/lib/matplotlib/colorbar.py trunk/matplotlib/lib/matplotlib/ticker.py trunk/matplotlib/make.osx Modified: trunk/matplotlib/lib/matplotlib/axes.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axes.py 2010-02-22 16:41:11 UTC (rev 8148) +++ trunk/matplotlib/lib/matplotlib/axes.py 2010-02-22 23:23:05 UTC (rev 8149) @@ -5769,9 +5769,22 @@ transOffset = self.transData, ) + if isinstance(norm, mcolors.LogNorm): + if (accum==0).any(): + # make sure we have not zeros + accum += 1 + + # Transform accum if needed if bins=='log': accum = np.log10(accum+1) + + # autoscale the norm with curren accum values if it hasn't + # been set + if norm is not None: + if norm.vmin is None and norm.vmax is None: + norm.autoscale(accum) + elif bins!=None: if not iterable(bins): minimum, maximum = min(accum), max(accum) Modified: trunk/matplotlib/lib/matplotlib/colorbar.py =================================================================== --- trunk/matplotlib/lib/matplotlib/colorbar.py 2010-02-22 16:41:11 UTC (rev 8148) +++ trunk/matplotlib/lib/matplotlib/colorbar.py 2010-02-22 23:23:05 UTC (rev 8149) @@ -455,6 +455,10 @@ locator.set_data_interval(*intv) formatter.set_view_interval(*intv) formatter.set_data_interval(*intv) + + # the dummy axis is expecting a minpos + locator.axis.get_minpos = lambda : intv[0] + formatter.axis.get_minpos = lambda : intv[0] b = np.array(locator()) b, ticks = self._locate(b) formatter.set_locs(b) Modified: trunk/matplotlib/lib/matplotlib/ticker.py =================================================================== --- trunk/matplotlib/lib/matplotlib/ticker.py 2010-02-22 16:41:11 UTC (rev 8148) +++ trunk/matplotlib/lib/matplotlib/ticker.py 2010-02-22 23:23:05 UTC (rev 8149) @@ -147,6 +147,7 @@ def set_data_interval(self, vmin, vmax): self.dataLim.intervalx = vmin, vmax + def set_axis(self, axis): self.axis = axis Modified: trunk/matplotlib/make.osx =================================================================== --- trunk/matplotlib/make.osx 2010-02-22 16:41:11 UTC (rev 8148) +++ trunk/matplotlib/make.osx 2010-02-22 23:23:05 UTC (rev 8149) @@ -25,7 +25,7 @@ fetch: ${PYTHON} -c 'import urllib; urllib.urlretrieve("http://www.zlib.net/zlib-${ZLIBVERSION}.tar.gz", "zlib-${ZLIBVERSION}.tar.gz")' &&\ - ${PYTHON} -c 'import urllib; urllib.urlretrieve("http://internap.dl.sourceforge.net/sourceforge/libpng/libpng-${PNGVERSION}.tar.bz2", "libpng-${PNGVERSION}.tar.bz2")' &&\ + ${PYTHON} -c 'import urllib; urllib.urlretrieve("http://download.sourceforge.net/libpng/libpng-${PNGVERSION}.tar.gz", "libpng-${PNGVERSION}.tar.bz2")' &&\ ${PYTHON} -c 'import urllib; urllib.urlretrieve("http://download.savannah.gnu.org/releases/freetype/freetype-${FREETYPEVERSION}.tar.bz2", "freetype-${FREETYPEVERSION}.tar.bz2")' @@ -46,7 +46,7 @@ png: zlib export PKG_CONFIG_PATH=${PKG_CONFIG_PATH} &&\ rm -rf libpng-${PNGVERSION} &&\ - tar xvfj libpng-${PNGVERSION}.tar.bz2 + tar xvfz libpng-${PNGVERSION}.tar.gz cd libpng-${PNGVERSION} &&\ export MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET} &&\ export CFLAGS=${CFLAGS} &&\ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jd...@us...> - 2010-02-23 17:02:19
|
Revision: 8150 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8150&view=rev Author: jdh2358 Date: 2010-02-23 17:02:11 +0000 (Tue, 23 Feb 2010) Log Message: ----------- add Ben Axelrod's button patch for RectangleSelector Modified Paths: -------------- trunk/matplotlib/examples/widgets/rectangle_selector.py trunk/matplotlib/lib/matplotlib/widgets.py Modified: trunk/matplotlib/examples/widgets/rectangle_selector.py =================================================================== --- trunk/matplotlib/examples/widgets/rectangle_selector.py 2010-02-22 23:23:05 UTC (rev 8149) +++ trunk/matplotlib/examples/widgets/rectangle_selector.py 2010-02-23 17:02:11 UTC (rev 8150) @@ -30,5 +30,6 @@ # drawtype is 'box' or 'line' or 'none' LS = RectangleSelector(current_ax, line_select_callback, drawtype='box',useblit=True, + button = [1, 3], # don't use center mouse button minspanx=5,minspany=5,spancoords='pixels') show() Modified: trunk/matplotlib/lib/matplotlib/widgets.py =================================================================== --- trunk/matplotlib/lib/matplotlib/widgets.py 2010-02-22 23:23:05 UTC (rev 8149) +++ trunk/matplotlib/lib/matplotlib/widgets.py 2010-02-23 17:02:11 UTC (rev 8150) @@ -1017,7 +1017,8 @@ """ def __init__(self, ax, onselect, drawtype='box', minspanx=None, minspany=None, useblit=False, - lineprops=None, rectprops=None, spancoords='data'): + lineprops=None, rectprops=None, spancoords='data', + button=None): """ Create a selector in ax. When a selection is made, clear @@ -1047,6 +1048,15 @@ spancoords is one of 'data' or 'pixels'. If 'data', minspanx and minspanx will be interpreted in the same coordinates as the x and ya axis, if 'pixels', they are in pixels + + button is a list of integers indicating which mouse buttons should + be used for rectangle selection. You can also specify a single + integer if only a single button is desired. Default is None, which + does not limit which button can be used. + Note, typically: + 1 = left mouse button + 2 = center mouse button (scroll wheel) + 3 = right mouse button """ self.ax = ax self.visible = True @@ -1084,6 +1094,11 @@ self.minspanx = minspanx self.minspany = minspany + if button is None or isinstance(button, list): + self.validButtons = button + elif isinstance(button, int): + self.validButtons = [button] + assert(spancoords in ('data', 'pixels')) self.spancoords = spancoords @@ -1109,6 +1124,12 @@ if not self.canvas.widgetlock.available(self): return True + # Only do rectangle selection if event was triggered + # with a desired button + if self.validButtons is not None: + if not event.button in self.validButtons: + return True + # If no button was pressed yet ignore the event if it was out # of the axes if self.eventpress == None: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fer...@us...> - 2010-02-24 19:09:49
|
Revision: 8151 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8151&view=rev Author: fer_perez Date: 2010-02-24 18:25:49 +0000 (Wed, 24 Feb 2010) Log Message: ----------- Add pyplot.fig_subplot, for easier creation of figures with multiple subplots. Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/pyplot.py Added Paths: ----------- trunk/matplotlib/examples/pylab_examples/fig_subplot_demo.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2010-02-23 17:02:11 UTC (rev 8150) +++ trunk/matplotlib/CHANGELOG 2010-02-24 18:25:49 UTC (rev 8151) @@ -1,3 +1,7 @@ +2010-02-24 Added pyplot.fig_subplot(), to create a figure and a group of + subplots in a single call. This offers an easier pattern than + manually making figures and calling add_subplot() multiple times. FP + 2010-02-17 Added Gokhan's and Mattias' customizable keybindings patch for the toolbar. You can now set the keymap.* properties in the matplotlibrc file. Newbindings were added for Added: trunk/matplotlib/examples/pylab_examples/fig_subplot_demo.py =================================================================== --- trunk/matplotlib/examples/pylab_examples/fig_subplot_demo.py (rev 0) +++ trunk/matplotlib/examples/pylab_examples/fig_subplot_demo.py 2010-02-24 18:25:49 UTC (rev 8151) @@ -0,0 +1,42 @@ +""" +""" +import matplotlib.pyplot as plt +import numpy as np + +x = np.linspace(0, 2*np.pi, 400) +y = np.sin(x**2) + +plt.close('all') + +# Just a figure and one subplot +f, ax = plt.fig_subplot() +ax.plot(x, y) +ax.set_title('Simple plot') + +# Two subplots, grab the whole fig_axes list +fax = plt.fig_subplot(2, sharex=True) +fax[1].plot(x, y) +fax[1].set_title('Sharing X axis') +fax[2].scatter(x, y) + +# Two subplots, unpack the output immediately +f, ax1, ax2 = plt.fig_subplot(1, 2, sharey=True) +ax1.plot(x, y) +ax1.set_title('Sharing Y axis') +ax2.scatter(x, y) + +# Three subplots sharing both x/y axes +f, ax1, ax2, ax3 = plt.fig_subplot(3, sharex=True, sharey=True) +ax1.plot(x, y) +ax1.set_title('Sharing both axes') +ax2.scatter(x, y) +ax3.scatter(x, 2*y**2-1,color='r') +# Fine-tune figure; make subplots close to each other and hide x ticks for +# all but bottom plot. +f.subplots_adjust(hspace=0) +plt.setp([a.get_xticklabels() for a in f.axes[:-1]], visible=False) + +# Four polar axes +plt.fig_subplot(2, 2, subplot_kw=dict(polar=True)) + +plt.show() Modified: trunk/matplotlib/lib/matplotlib/pyplot.py =================================================================== --- trunk/matplotlib/lib/matplotlib/pyplot.py 2010-02-23 17:02:11 UTC (rev 8150) +++ trunk/matplotlib/lib/matplotlib/pyplot.py 2010-02-24 18:25:49 UTC (rev 8151) @@ -649,6 +649,80 @@ return a +def fig_subplot(nrows=1, ncols=1, sharex=False, sharey=False, + subplot_kw=None, **fig_kw): + """Create a figure with a set of subplots already made. + + This utility wrapper makes it convenient to create common layouts of + subplots, including the enclosing figure object, in a single call. + + Keyword arguments: + + nrows : int + Number of rows of the subplot grid. Defaults to 1. + + nrows : int + Number of columns of the subplot grid. Defaults to 1. + + sharex : bool + If True, the X axis will be shared amongst all subplots. + + sharex : bool + If True, the Y axis will be shared amongst all subplots. + + subplot_kw : dict + Dict with keywords passed to the add_subplot() call used to create each + subplots. + + fig_kw : dict + Dict with keywords passed to the figure() call. Note that all keywords + not recognized above will be automatically included here. + + Returns: + + fig_axes : list + A list containing [fig, ax1, ax2, ...], where fig is the Matplotlib + Figure object and the rest are the axes. + + **Examples:** + + x = np.linspace(0, 2*np.pi, 400) + y = np.sin(x**2) + + # Just a figure and one subplot + f, ax = plt.fig_subplot() + ax.plot(x, y) + ax.set_title('Simple plot') + + # Two subplots, unpack the output immediately + f, ax1, ax2 = plt.fig_subplot(1, 2, sharey=True) + ax1.plot(x, y) + ax1.set_title('Sharing Y axis') + ax2.scatter(x, y) + + # Four polar axes + plt.fig_subplot(2, 2, subplot_kw=dict(polar=True)) + """ + + if subplot_kw is None: + subplot_kw = {} + + fig = figure(**fig_kw) + + # Create first subplot separately, so we can share it if requested + ax1 = fig.add_subplot(nrows, ncols, 1, **subplot_kw) + if sharex: + subplot_kw['sharex'] = ax1 + if sharey: + subplot_kw['sharey'] = ax1 + + # Valid indices for axes start at 1, since fig is at 0: + axes = [ fig.add_subplot(nrows, ncols, i, **subplot_kw) + for i in range(2, nrows*ncols+1)] + + return [fig, ax1] + axes + + def twinx(ax=None): """ Make a second axes overlay *ax* (or the current axes if *ax* is This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <lee...@us...> - 2010-02-26 00:31:49
|
Revision: 8158 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8158&view=rev Author: leejjoon Date: 2010-02-26 00:28:14 +0000 (Fri, 26 Feb 2010) Log Message: ----------- add annotation_demo3.py Modified Paths: -------------- trunk/matplotlib/CHANGELOG Added Paths: ----------- trunk/matplotlib/examples/pylab_examples/annotation_demo3.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2010-02-26 00:28:07 UTC (rev 8157) +++ trunk/matplotlib/CHANGELOG 2010-02-26 00:28:14 UTC (rev 8158) @@ -1,3 +1,5 @@ +2010-02-25 add annotation_demo3.py that demonstrates new functionality. -JJL + 2010-02-25 refactor Annotation to support arbitrary Transform as xycoords or textcoords. Also, if a tuple of two coordinates is provided, they are interpreted as coordinates for each x and y position. Added: trunk/matplotlib/examples/pylab_examples/annotation_demo3.py =================================================================== --- trunk/matplotlib/examples/pylab_examples/annotation_demo3.py (rev 0) +++ trunk/matplotlib/examples/pylab_examples/annotation_demo3.py 2010-02-26 00:28:14 UTC (rev 8158) @@ -0,0 +1,102 @@ +import matplotlib.pyplot as plt + +fig = plt.figure(1) +fig.clf() + +ax1 = plt.subplot(121) +ax2 = plt.subplot(122) + +bbox_args = dict(boxstyle="round", fc="0.8") +arrow_args = dict(arrowstyle="->") + +ax1.annotate('figure fraction : 0, 0', xy=(0, 0), xycoords='figure fraction', + xytext=(20, 20), textcoords='offset points', + ha="left", va="bottom", + bbox=bbox_args, + arrowprops=arrow_args + ) + +ax1.annotate('figure fraction : 1, 1', xy=(1, 1), xycoords='figure fraction', + xytext=(-20, -20), textcoords='offset points', + ha="right", va="top", + bbox=bbox_args, + arrowprops=arrow_args + ) + +ax1.annotate('axes fraction : 0, 0', xy=(0, 0), xycoords='axes fraction', + xytext=(20, 20), textcoords='offset points', + ha="left", va="bottom", + bbox=bbox_args, + arrowprops=arrow_args + ) + +ax1.annotate('axes fraction : 1, 1', xy=(1, 1), xycoords='axes fraction', + xytext=(-20, -20), textcoords='offset points', + ha="right", va="top", + bbox=bbox_args, + arrowprops=arrow_args + ) + + +an1 = ax1.annotate('Drag me 1', xy=(.5, .7), xycoords='data', + #xytext=(.5, .7), textcoords='data', + ha="center", va="center", + bbox=bbox_args, + #arrowprops=arrow_args + ) + +an2 = ax1.annotate('Drag me 2', xy=(.5, .5), xycoords=an1, + xytext=(.5, .3), textcoords='axes fraction', + ha="center", va="center", + bbox=bbox_args, + arrowprops=dict(patchB=an1.get_bbox_patch(), + connectionstyle="arc3,rad=0.2", + **arrow_args) + ) + +an3 = ax1.annotate('', xy=(.5, .5), xycoords=an2, + xytext=(.5, .5), textcoords=an1, + ha="center", va="center", + bbox=bbox_args, + arrowprops=dict(patchA=an1.get_bbox_patch(), + patchB=an2.get_bbox_patch(), + connectionstyle="arc3,rad=0.2", + **arrow_args) + ) + + + +t = ax2.annotate('xy=(0, 1)\nxycoords=("data", "axes fraction")', + xy=(0, 1), xycoords=("data", 'axes fraction'), + xytext=(0, -20), textcoords='offset points', + ha="center", va="top", + bbox=bbox_args, + arrowprops=arrow_args + ) + +from matplotlib.text import OffsetFrom + +ax2.annotate('xy=(0.5, 0)\nxycoords="bbox fraction"\nxybbox=artist', + xy=(0.5, 0.), xycoords=t.get_window_extent, + xytext=(0, -20), textcoords='offset points', + ha="center", va="top", + bbox=bbox_args, + arrowprops=arrow_args + ) + +ax2.annotate('xy=(0.8, 0.5)\nxycoords="bbox"\nxybbox=ax1.transData', + xy=(0.8, 0.5), xycoords=ax1.transData, + #xytext=(0, 0), textcoords='data', + xytext=(10, 10), textcoords=OffsetFrom(ax2.bbox, (0, 0), "points"), + ha="left", va="bottom", + bbox=bbox_args, + arrowprops=arrow_args + ) + +ax2.set_xlim(-2, 2) +ax2.set_ylim(-2, 2) + +an1.draggable() +an2.draggable() + +plt.show() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <lee...@us...> - 2010-02-26 00:32:20
|
Revision: 8157 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8157&view=rev Author: leejjoon Date: 2010-02-26 00:28:07 +0000 (Fri, 26 Feb 2010) Log Message: ----------- refactor Annotation to support arbitrary transformation. Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/offsetbox.py trunk/matplotlib/lib/matplotlib/text.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2010-02-25 15:57:15 UTC (rev 8156) +++ trunk/matplotlib/CHANGELOG 2010-02-26 00:28:07 UTC (rev 8157) @@ -1,3 +1,8 @@ +2010-02-25 refactor Annotation to support arbitrary Transform as xycoords + or textcoords. Also, if a tuple of two coordinates is provided, + they are interpreted as coordinates for each x and y position. + -JJL + 2010-02-24 Added pyplot.fig_subplot(), to create a figure and a group of subplots in a single call. This offers an easier pattern than manually making figures and calling add_subplot() multiple times. FP Modified: trunk/matplotlib/lib/matplotlib/offsetbox.py =================================================================== --- trunk/matplotlib/lib/matplotlib/offsetbox.py 2010-02-25 15:57:15 UTC (rev 8156) +++ trunk/matplotlib/lib/matplotlib/offsetbox.py 2010-02-26 00:28:07 UTC (rev 8157) @@ -1301,11 +1301,11 @@ x, y = self.xytext if isinstance(self.textcoords, tuple): xcoord, ycoord = self.textcoords - x1, y1 = self._get_xy(x, y, xcoord) - x2, y2 = self._get_xy(x, y, ycoord) + x1, y1 = self._get_xy(renderer, x, y, xcoord) + x2, y2 = self._get_xy(renderer, x, y, ycoord) ox0, oy0 = x1, y2 else: - ox0, oy0 = self._get_xy(x, y, self.textcoords) + ox0, oy0 = self._get_xy(renderer, x, y, self.textcoords) #self.offsetbox.set_bbox_to_anchor((ox0, oy0)) w, h, xd, yd = self.offsetbox.get_extent(renderer) @@ -1526,11 +1526,11 @@ x, y = ann.xytext if isinstance(ann.textcoords, tuple): xcoord, ycoord = ann.textcoords - x1, y1 = ann._get_xy(x, y, xcoord) - x2, y2 = ann._get_xy(x, y, ycoord) + x1, y1 = ann._get_xy(self.canvas.renderer, x, y, xcoord) + x2, y2 = ann._get_xy(self.canvas.renderer, x, y, ycoord) ox0, oy0 = x1, y2 else: - ox0, oy0 = ann._get_xy(x, y, ann.textcoords) + ox0, oy0 = ann._get_xy(self.canvas.renderer, x, y, ann.textcoords) self.ox, self.oy = ox0, oy0 self.annotation.textcoords = "figure pixels" @@ -1539,7 +1539,7 @@ ann = self.annotation ann.xytext = self.ox + dx, self.oy + dy x, y = ann.xytext - xy = ann._get_xy(x, y, ann.textcoords) + xy = ann._get_xy(self.canvas.renderer, x, y, ann.textcoords) def finalize_offset(self): loc_in_canvas = self.annotation.xytext Modified: trunk/matplotlib/lib/matplotlib/text.py =================================================================== --- trunk/matplotlib/lib/matplotlib/text.py 2010-02-25 15:57:15 UTC (rev 8156) +++ trunk/matplotlib/lib/matplotlib/text.py 2010-02-26 00:28:07 UTC (rev 8157) @@ -16,7 +16,8 @@ from matplotlib.patches import bbox_artist, YAArrow, FancyBboxPatch, \ FancyArrowPatch, Rectangle import matplotlib.transforms as mtransforms -from matplotlib.transforms import Affine2D, Bbox +from matplotlib.transforms import Affine2D, Bbox, Transform ,\ + BboxBase, BboxTransformTo from matplotlib.lines import Line2D from matplotlib.artist import allow_rasterization @@ -306,7 +307,7 @@ ismath=ismath) else: w, h, d = 0, 0, 0 - + if baseline is None: baseline = h - d whs[i] = w, h @@ -1389,6 +1390,45 @@ docstring.interpd.update(TextWithDash=artist.kwdoc(TextWithDash)) + +class OffsetFrom(object): + def __init__(self, artist, ref_coord, unit="points"): + self._artist = artist + self._ref_coord= ref_coord + self.set_unit(unit) + + def set_unit(self, unit): + assert unit in ["points", "pixels"] + self._unit = unit + + def get_unit(self): + return self._unit + + def _get_scale(self, renderer): + unit = self.get_unit() + if unit == "pixels": + return 1. + else: + return renderer.points_to_pixels(1.) + + def __call__(self, renderer): + if isinstance(self._artist, Artist): + bbox = self._artist.get_window_extent(renderer) + l, b, w, h = bbox.bounds + xf, yf = self._ref_coord + x, y = l+w*xf, b+h*yf + elif isinstance(self._artist, BboxBase): + l, b, w, h = self._artist.bounds + xf, yf = self._ref_coord + x, y = l+w*xf, b+h*yf + elif isinstance(self._artist, Transform): + x, y = self._artist.transform_point(self._ref_coord) + + sc = self._get_scale(renderer) + tr = Affine2D().scale(sc, sc).translate(x, y) + + return tr + class _AnnotationBase(object): def __init__(self, xy, xytext=None, @@ -1408,102 +1448,169 @@ self._draggable = None + def _get_xy(self, renderer, x, y, s): + if isinstance(s, tuple): + s1, s2 = s + else: + s1, s2 = s, s - def _get_xy(self, x, y, s): - if s=='data': - trans = self.axes.transData + if s1 == 'data': x = float(self.convert_xunits(x)) + if s2 == 'data': y = float(self.convert_yunits(y)) - return trans.transform_point((x, y)) - elif s=='offset points': - # convert the data point - dx, dy = self.xy - # prevent recursion - if self.xycoords == 'offset points': - return self._get_xy(dx, dy, 'data') - dx, dy = self._get_xy(dx, dy, self.xycoords) + tr = self._get_xy_transform(renderer, s) + x1, y1 = tr.transform_point((x, y)) + return x1, y1 - # convert the offset - dpi = self.figure.get_dpi() - x *= dpi/72. - y *= dpi/72. + def _get_xy_transform(self, renderer, s): - # add the offset to the data point - x += dx - y += dy + if isinstance(s, tuple): + s1, s2 = s + from matplotlib.transforms import blended_transform_factory + tr1 = self._get_xy_transform(renderer, s1) + tr2 = self._get_xy_transform(renderer, s2) + tr = blended_transform_factory(tr1, tr2) + return tr - return x, y + if callable(s): + tr = s(renderer) + if isinstance(tr, BboxBase): + return BboxTransformTo(tr) + elif isinstance(tr, Transform): + return tr + else: + raise RuntimeError("unknown return type ...") + if isinstance(s, Artist): + bbox = s.get_window_extent(renderer) + return BboxTransformTo(bbox) + elif isinstance(s, BboxBase): + return BboxTransformTo(s) + elif isinstance(s, Transform): + return s + elif not is_string_like(s): + raise RuntimeError("unknown coordinate type : %s" % (s,)) + + if s=='data': + return self.axes.transData elif s=='polar': - theta, r = x, y - x = r*np.cos(theta) - y = r*np.sin(theta) - trans = self.axes.transData - return trans.transform_point((x,y)) - elif s=='figure points': - #points from the lower left corner of the figure - dpi = self.figure.dpi - l,b,w,h = self.figure.bbox.bounds - r = l+w - t = b+h + from matplotlib.projections import PolarAxes + tr = PolarAxes.PolarTransform() + trans = tr + self.axes.transData + return trans + + s_ = s.split() + if len(s_) != 2: + raise ValueError("%s is not a recognized coodinate" % s) - x *= dpi/72. - y *= dpi/72. - if x<0: - x = r + x - if y<0: - y = t + y - return x,y - elif s=='figure pixels': - #pixels from the lower left corner of the figure - l,b,w,h = self.figure.bbox.bounds - r = l+w - t = b+h - if x<0: - x = r + x - if y<0: - y = t + y - return x, y - elif s=='figure fraction': - #(0,0) is lower left, (1,1) is upper right of figure - trans = self.figure.transFigure - return trans.transform_point((x,y)) - elif s=='axes points': - #points from the lower left corner of the axes - dpi = self.figure.dpi - l,b,w,h = self.axes.bbox.bounds - r = l+w - t = b+h - if x<0: - x = r + x*dpi/72. - else: - x = l + x*dpi/72. - if y<0: - y = t + y*dpi/72. - else: - y = b + y*dpi/72. - return x, y - elif s=='axes pixels': - #pixels from the lower left corner of the axes + bbox0, xy0 = None, None - l,b,w,h = self.axes.bbox.bounds - r = l+w - t = b+h - if x<0: - x = r + x + bbox_name, unit = s_ + # if unit is offset-like + if bbox_name == "figure": + bbox0 = self.figure.bbox + elif bbox_name == "axes": + bbox0 = self.axes.bbox + # elif bbox_name == "bbox": + # if bbox is None: + # raise RuntimeError("bbox is specified as a coordinate but never set") + # bbox0 = self._get_bbox(renderer, bbox) + + if bbox0 is not None: + xy0 = bbox0.bounds[:2] + elif bbox_name == "offset": + xy0 = self._get_ref_xy(renderer) + + if xy0 is not None: + # reference x, y in display coordinate + ref_x, ref_y = xy0 + from matplotlib.transforms import Affine2D + if unit == "points": + dpi = self.figure.get_dpi() + tr = Affine2D().scale(dpi/72., dpi/72.) + elif unit == "pixels": + tr = Affine2D() + elif unit == "fontsize": + fontsize = self.get_size() + dpi = self.figure.get_dpi() + tr = Affine2D().scale(fontsize*dpi/72., fontsize*dpi/72.) + elif unit == "fraction": + w, h = bbox0.bounds[2:] + tr = Affine2D().scale(w, h) else: - x = l + x - if y<0: - y = t + y - else: - y = b + y - return x, y - elif s=='axes fraction': - #(0,0) is lower left, (1,1) is upper right of axes - trans = self.axes.transAxes - return trans.transform_point((x, y)) + raise ValueError("%s is not a recognized coodinate" % s) + return tr.translate(ref_x, ref_y) + + else: + raise ValueError("%s is not a recognized coodinate" % s) + + + def _get_ref_xy(self, renderer): + """ + return x, y (in display coordinate) that is to be used for a reference + of any offset coordinate + """ + + if isinstance(self.xycoords, tuple): + s1, s2 = self.xycoords + if s1.split()[0] == "offset" or s2.split()[0] == "offset": + raise ValueError("xycoords should not be an offset coordinate") + x, y = self.xy + x1, y1 = self._get_xy(renderer, x, y, s1) + x2, y2 = self._get_xy(renderer, x, y, s2) + return x1, y2 + elif is_string_like(self.xycoords) and self.xycoords.split()[0] == "offset": + raise ValueError("xycoords should not be an offset coordinate") + else: + x, y = self.xy + return self._get_xy(renderer, x, y, self.xycoords) + #raise RuntimeError("must be defined by the derived class") + + + # def _get_bbox(self, renderer): + # if hasattr(bbox, "bounds"): + # return bbox + # elif hasattr(bbox, "get_window_extent"): + # bbox = bbox.get_window_extent() + # return bbox + # else: + # raise ValueError("A bbox instance is expected but got %s" % str(bbox)) + + + + def _get_xy_legacy(self, renderer, x, y, s): + """ + only used when s in ['axes points', 'axes pixel', 'figure points', 'figure pixel']. + """ + s_ = s.split() + bbox0, xy0 = None, None + bbox_name, unit = s_ + + if bbox_name == "figure": + bbox0 = self.figure.bbox + elif bbox_name == "axes": + bbox0 = self.axes.bbox + + if unit == "points": + sc = self.figure.get_dpi()/72. + elif unit == "pixels": + sc = 1 + + l,b,r,t = bbox0.extents + if x<0: + x = r + x*sc + else: + x = l + x*sc + if y<0: + y = t + y*sc + else: + y = b + y*sc + + return x, y + + def set_annotation_clip(self, b): """ set *annotation_clip* attribute. @@ -1524,7 +1631,7 @@ def _get_position_xy(self, renderer): "Return the pixel position of the the annotated point." x, y = self.xy - return self._get_xy(x, y, self.xycoords) + return self._get_xy(renderer, x, y, self.xycoords) def _check_xy(self, renderer, xy_pixel): """ @@ -1533,6 +1640,7 @@ """ b = self.get_annotation_clip() + if b or (b is None and self.xycoords == "data"): # check if self.xy is inside the axes. if not self.axes.contains_point(xy_pixel): @@ -1550,7 +1658,7 @@ * True : turn draggable on * False : turn draggable off - + If draggable is on, you can drag the annotation on the canvas with the mouse. The DraggableAnnotation helper instance is returned if draggable is on. @@ -1561,7 +1669,7 @@ # if state is None we'll toggle if state is None: state = not is_draggable - + if state: if self._draggable is None: self._draggable = DraggableAnnotation(self, use_blit) @@ -1706,7 +1814,7 @@ else: self.arrow_patch = None - + def contains(self,event): t,tinfo = Text.contains(self,event) if self.arrow is not None: @@ -1737,7 +1845,8 @@ "Update the pixel positions of the annotation text and the arrow patch." x, y = self.xytext - self._x, self._y = self._get_xy(x, y, self.textcoords) + self._x, self._y = self._get_xy(renderer, x, y, + self.textcoords) x, y = xy_pixel This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <lee...@us...> - 2010-02-28 03:13:45
|
Revision: 8163 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8163&view=rev Author: leejjoon Date: 2010-02-28 03:13:39 +0000 (Sun, 28 Feb 2010) Log Message: ----------- update annotation guide Modified Paths: -------------- trunk/matplotlib/doc/users/annotations_guide.rst trunk/matplotlib/examples/pylab_examples/annotation_demo3.py trunk/matplotlib/lib/matplotlib/text.py Added Paths: ----------- trunk/matplotlib/doc/users/plotting/examples/annotate_simple_coord01.py trunk/matplotlib/doc/users/plotting/examples/annotate_simple_coord02.py trunk/matplotlib/doc/users/plotting/examples/annotate_simple_coord03.py Modified: trunk/matplotlib/doc/users/annotations_guide.rst =================================================================== --- trunk/matplotlib/doc/users/annotations_guide.rst 2010-02-27 17:00:53 UTC (rev 8162) +++ trunk/matplotlib/doc/users/annotations_guide.rst 2010-02-28 03:13:39 UTC (rev 8163) @@ -4,10 +4,13 @@ Annotating Axes **************** -Do not proceed unless you already have read -:func:`~matplotlib.pyplot.text` and :func:`~matplotlib.pyplot.annotate`! +Do not proceed unless you already have read :ref:`annotations-tutorial`, +:func:`~matplotlib.pyplot.text` and +:func:`~matplotlib.pyplot.annotate`! + + Annotating with Text with Box ============================= @@ -182,31 +185,6 @@ .. plot:: users/plotting/examples/annotate_simple04.py -Using ConnectorPatch -==================== - -The ConnectorPatch is like an annotation without a text. While the -annotate function is recommended in most of situation, the -ConnectorPatch is useful when you want to connect points in different -axes. :: - - from matplotlib.patches import ConnectionPatch - xy = (0.2, 0.2) - con = ConnectionPatch(xyA=xy, xyB=xy, coordsA="data", coordsB="data", - axesA=ax1, axesB=ax2) - ax2.add_artist(con) - -The above code connects point xy in data coordinate of ``ax1`` to -point xy int data coordinate of ``ax2``. Here is a simple example. - -.. plot:: users/plotting/examples/connect_simple01.py - - -While the ConnectorPatch instance can be added to any axes, but you -may want it to be added to the axes in the latter (?) of the axes -drawing order to prevent overlap (?) by other axes. - - Placing Artist at the anchored location of the Axes =================================================== @@ -282,6 +260,111 @@ Note that unlike the legend, the ``bbox_transform`` is set to IdentityTransform by default. +Using Complex Coordinate with Annotation +======================================== + +The Annotation in matplotlib support several types of coordinate as +described in :ref:`annotations-tutorial`. For an advanced user who wants +more control, it supports a few other options. + + 1. :class:`~matplotlib.transforms.Transform` instance. For example, :: + + ax.annotate("Test", xy=(0.5, 0.5), xycoords=ax.transAxes) + + is identical to :: + + ax.annotate("Test", xy=(0.5, 0.5), xycoords="axes fraction") + + With this, you can annotate a point in other axes. :: + + ax1, ax2 = subplot(121), subplot(122) + ax2.annotate("Test", xy=(0.5, 0.5), xycoords=ax1.transData, + xytext=(0.5, 0.5), textcoords=ax2.transData, + arrowprops=dict(arrowstyle="->")) + + 2. :class:`~matplotlib.artist.Artist` instance. The xy value (or + xytext) is interpreted as a fractional coordinate of the bbox + (return value of *get_window_extent*) of the artist. :: + + an1 = ax.annotate("Test 1", xy=(0.5, 0.5), xycoords="data", + va="center", ha="center", + bbox=dict(boxstyle="round", fc="w")) + an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1, # (1,0.5) of the an1's bbox + xytext=(30,0), textcoords="offset points", + va="center", ha="left", + bbox=dict(boxstyle="round", fc="w"), + arrowprops=dict(arrowstyle="->")) + + .. plot:: users/plotting/examples/annotate_simple_coord01.py + + Note that it is your responsibility that the extent of the + coordinate artist (*an1* in above example) is determined before *an2* + gets drawn. In most cases, it means that an2 needs to be drawn + later than *an1*. + + + 3. A callable object that returns an instance of either + :class:`~matplotlib.transforms.BboxBase` or + :class:`~matplotlib.transforms.Transform`. If a transform is + returned, it is same as 1 and if bbox is returned, it is same + as 2. The callable object should take a single argument of + renderer instance. For example, following two commands give + identical results :: + an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1, + xytext=(30,0), textcoords="offset points") + an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1.get_window_extent, + xytext=(30,0), textcoords="offset points") + + + 4. A tuple of two coordinate specification. The first item is for + x-coordinate and the second is for y-coordinate. For example, :: + + annotate("Test", xy=(0.5, 1), xycoords=("data", "axes fraction")) + + 0.5 is in data coordinate, and 1 is in normalized axes coordinate. + You may use an atist or transform as with a tuple. For example, + + .. plot:: users/plotting/examples/annotate_simple_coord02.py + :include-source: + + + 5. Sometimes, you want your annotation with some "offset points", but + not from the annotated point but from other + point. :class:`~matplotlib.text.OffsetFrom` is a helper class for such + case. + + .. plot:: users/plotting/examples/annotate_simple_coord03.py + :include-source: + + You may take a look at this example :ref:`pylab_examples-annotation_demo3`. + +Using ConnectorPatch +==================== + +The ConnectorPatch is like an annotation without a text. While the +annotate function is recommended in most of situation, the +ConnectorPatch is useful when you want to connect points in different +axes. :: + + from matplotlib.patches import ConnectionPatch + xy = (0.2, 0.2) + con = ConnectionPatch(xyA=xy, xyB=xy, coordsA="data", coordsB="data", + axesA=ax1, axesB=ax2) + ax2.add_artist(con) + +The above code connects point xy in data coordinate of ``ax1`` to +point xy int data coordinate of ``ax2``. Here is a simple example. + +.. plot:: users/plotting/examples/connect_simple01.py + + +While the ConnectorPatch instance can be added to any axes, but you +may want it to be added to the axes in the latter (?) of the axes +drawing order to prevent overlap (?) by other axes. + + + + Advanced Topics *************** Added: trunk/matplotlib/doc/users/plotting/examples/annotate_simple_coord01.py =================================================================== --- trunk/matplotlib/doc/users/plotting/examples/annotate_simple_coord01.py (rev 0) +++ trunk/matplotlib/doc/users/plotting/examples/annotate_simple_coord01.py 2010-02-28 03:13:39 UTC (rev 8163) @@ -0,0 +1,15 @@ + +import matplotlib.pyplot as plt + +plt.figure(figsize=(3,2)) +ax=plt.subplot(111) +an1 = ax.annotate("Test 1", xy=(0.5, 0.5), xycoords="data", + va="center", ha="center", + bbox=dict(boxstyle="round", fc="w")) +an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1, + xytext=(30,0), textcoords="offset points", + va="center", ha="left", + bbox=dict(boxstyle="round", fc="w"), + arrowprops=dict(arrowstyle="->")) +plt.show() + Added: trunk/matplotlib/doc/users/plotting/examples/annotate_simple_coord02.py =================================================================== --- trunk/matplotlib/doc/users/plotting/examples/annotate_simple_coord02.py (rev 0) +++ trunk/matplotlib/doc/users/plotting/examples/annotate_simple_coord02.py 2010-02-28 03:13:39 UTC (rev 8163) @@ -0,0 +1,16 @@ + +import matplotlib.pyplot as plt + +plt.figure(figsize=(3,2)) +ax=plt.axes([0.1, 0.1, 0.8, 0.7]) +an1 = ax.annotate("Test 1", xy=(0.5, 0.5), xycoords="data", + va="center", ha="center", + bbox=dict(boxstyle="round", fc="w")) + +an2 = ax.annotate("Test 2", xy=(0.5, 1.), xycoords=an1, + xytext=(0.5,1.1), textcoords=(an1, "axes fraction"), + va="bottom", ha="center", + bbox=dict(boxstyle="round", fc="w"), + arrowprops=dict(arrowstyle="->")) +plt.show() + Added: trunk/matplotlib/doc/users/plotting/examples/annotate_simple_coord03.py =================================================================== --- trunk/matplotlib/doc/users/plotting/examples/annotate_simple_coord03.py (rev 0) +++ trunk/matplotlib/doc/users/plotting/examples/annotate_simple_coord03.py 2010-02-28 03:13:39 UTC (rev 8163) @@ -0,0 +1,19 @@ + +import matplotlib.pyplot as plt + +plt.figure(figsize=(3,2)) +ax=plt.axes([0.1, 0.1, 0.8, 0.7]) +an1 = ax.annotate("Test 1", xy=(0.5, 0.5), xycoords="data", + va="center", ha="center", + bbox=dict(boxstyle="round", fc="w")) + +from matplotlib.text import OffsetFrom +offset_from = OffsetFrom(an1, (0.5, 0)) +an2 = ax.annotate("Test 2", xy=(0.1, 0.1), xycoords="data", + xytext=(0, -10), textcoords=offset_from, + # xytext is offset points from "xy=(0.5, 0), xycoords=an1" + va="top", ha="center", + bbox=dict(boxstyle="round", fc="w"), + arrowprops=dict(arrowstyle="->")) +plt.show() + Modified: trunk/matplotlib/examples/pylab_examples/annotation_demo3.py =================================================================== --- trunk/matplotlib/examples/pylab_examples/annotation_demo3.py 2010-02-27 17:00:53 UTC (rev 8162) +++ trunk/matplotlib/examples/pylab_examples/annotation_demo3.py 2010-02-28 03:13:39 UTC (rev 8163) @@ -76,17 +76,16 @@ from matplotlib.text import OffsetFrom -ax2.annotate('xy=(0.5, 0)\nxycoords="bbox fraction"\nxybbox=artist', - xy=(0.5, 0.), xycoords=t.get_window_extent, +ax2.annotate('xy=(0.5, 0)\nxycoords=artist', + xy=(0.5, 0.), xycoords=t, xytext=(0, -20), textcoords='offset points', ha="center", va="top", bbox=bbox_args, arrowprops=arrow_args ) -ax2.annotate('xy=(0.8, 0.5)\nxycoords="bbox"\nxybbox=ax1.transData', +ax2.annotate('xy=(0.8, 0.5)\nxycoords=ax1.transData', xy=(0.8, 0.5), xycoords=ax1.transData, - #xytext=(0, 0), textcoords='data', xytext=(10, 10), textcoords=OffsetFrom(ax2.bbox, (0, 0), "points"), ha="left", va="bottom", bbox=bbox_args, Modified: trunk/matplotlib/lib/matplotlib/text.py =================================================================== --- trunk/matplotlib/lib/matplotlib/text.py 2010-02-27 17:00:53 UTC (rev 8162) +++ trunk/matplotlib/lib/matplotlib/text.py 2010-02-28 03:13:39 UTC (rev 8163) @@ -1423,7 +1423,9 @@ x, y = l+w*xf, b+h*yf elif isinstance(self._artist, Transform): x, y = self._artist.transform_point(self._ref_coord) - + else: + raise RuntimeError("unknown type") + sc = self._get_scale(renderer) tr = Affine2D().scale(sc, sc).translate(x, y) @@ -1780,7 +1782,12 @@ # 5 points below the top border xy=(10,-5), xycoords='axes points' + You may use an instance of + :class:`~matplotlib.transforms.Transform` or + :class:`~matplotlib.artist.Artist`. See + :ref:`plotting-guide-annotation` for more details. + The *annotation_clip* attribute contols the visibility of the annotation when it goes outside the axes area. If True, the annotation will only be drawn when the *xy* is inside the This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jd...@us...> - 2010-03-03 21:06:19
|
Revision: 8176 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8176&view=rev Author: jdh2358 Date: 2010-03-03 21:06:01 +0000 (Wed, 03 Mar 2010) Log Message: ----------- patch branch updates Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/doc/_templates/indexsidebar.html trunk/matplotlib/doc/_templates/layout.html trunk/matplotlib/doc/devel/coding_guide.rst trunk/matplotlib/doc/users/artists.rst trunk/matplotlib/lib/matplotlib/artist.py trunk/matplotlib/lib/matplotlib/backends/backend_wxagg.py trunk/matplotlib/lib/matplotlib/finance.py trunk/matplotlib/lib/matplotlib/patches.py Added Paths: ----------- trunk/matplotlib/doc/_static/favicon.ico Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2010-03-03 18:03:30 UTC (rev 8175) +++ trunk/matplotlib/CHANGELOG 2010-03-03 21:06:01 UTC (rev 8176) @@ -1,3 +1,26 @@ +2010-03-03 Manually brought in commits from branch via diff/patch (svnmerge is broken) + + ------------------------------------------------------------------------ + r8175 | leejjoon | 2010-03-03 10:03:30 -0800 (Wed, 03 Mar 2010) | 1 line + + fix arguments of allow_rasterization.draw_wrapper + ------------------------------------------------------------------------ + r8174 | jdh2358 | 2010-03-03 09:15:58 -0800 (Wed, 03 Mar 2010) | 1 line + + added support for favicon in docs build + ------------------------------------------------------------------------ + r8173 | jdh2358 | 2010-03-03 08:56:16 -0800 (Wed, 03 Mar 2010) | 1 line + + applied Mattias get_bounds patch + ------------------------------------------------------------------------ + r8172 | jdh2358 | 2010-03-03 08:31:42 -0800 (Wed, 03 Mar 2010) | 1 line + + fix svnmerge download instructions + ------------------------------------------------------------------------ + r8171 | jdh2358 | 2010-03-03 07:47:48 -0800 (Wed, 03 Mar 2010) | 1 line + + + 2010-02-25 add annotation_demo3.py that demonstrates new functionality. -JJL 2010-02-25 refactor Annotation to support arbitrary Transform as xycoords Added: trunk/matplotlib/doc/_static/favicon.ico =================================================================== (Binary files differ) Property changes on: trunk/matplotlib/doc/_static/favicon.ico ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/matplotlib/doc/_templates/indexsidebar.html =================================================================== --- trunk/matplotlib/doc/_templates/indexsidebar.html 2010-03-03 18:03:30 UTC (rev 8175) +++ trunk/matplotlib/doc/_templates/indexsidebar.html 2010-03-03 21:06:01 UTC (rev 8176) @@ -9,11 +9,11 @@ pathto('users/installing') }}">installing</a> </p> -<p>Sandro Tosi has a new book -<a href="http://www.packtpub.com/matplotlib-python-development/book">Matplotlib for python -developers</a> -also -at <a href="http://www.amazon.com/Matplotlib-Python-Developers-Sandro-Tosi/dp/1847197906">amazon</a>.</p> +<p>Sandro Tosi has a new book + <a href="http://www.packtpub.com/matplotlib-python-development/book?utm_source=matplotlib.sourceforge.net&utm_medium=link&utm_content=pod&utm_campaign=mdb_002124">Matplotlib for python + developers</a> + also + at <a href="http://www.amazon.com/Matplotlib-Python-Developers-Sandro-Tosi/dp/1847197906">amazon</a>.</p> <p>Build websites like matplotlib's, with <a href="http://sphinx.pocoo.org/">sphinx</a> and extensions for Modified: trunk/matplotlib/doc/_templates/layout.html =================================================================== --- trunk/matplotlib/doc/_templates/layout.html 2010-03-03 18:03:30 UTC (rev 8175) +++ trunk/matplotlib/doc/_templates/layout.html 2010-03-03 21:06:01 UTC (rev 8176) @@ -23,8 +23,8 @@ </script> <object><noscript><p><img src="http://apps.sourceforge.net/piwik/matplotlib/piwik.php?idsite=1" alt="piwik"/></p></noscript></object> <!-- End Piwik Tag --> +<link rel="shortcut icon" href="_static/favicon.ico"> - <div style="background-color: white; text-align: left; padding: 10px 10px 15px 15px"> <a href="{{ pathto('index') }}"><img src="{{ pathto("_static/logo2.png", 1) }}" border="0" alt="matplotlib"/></a> Modified: trunk/matplotlib/doc/devel/coding_guide.rst =================================================================== --- trunk/matplotlib/doc/devel/coding_guide.rst 2010-03-03 18:03:30 UTC (rev 8175) +++ trunk/matplotlib/doc/devel/coding_guide.rst 2010-03-03 21:06:01 UTC (rev 8176) @@ -82,8 +82,8 @@ * install ``svnmerge.py`` in your PATH:: - > wget http://svn.collab.net/repos/svn/trunk/contrib/client-side/\ - svnmerge/svnmerge.py + > wget http://svn.apache.org/repos/asf/subversion/trunk/contrib/\ + client-side/svnmerge/svnmerge.py * get a svn checkout of the branch you'll be making bugfixes to and the trunk (see above) Modified: trunk/matplotlib/doc/users/artists.rst =================================================================== --- trunk/matplotlib/doc/users/artists.rst 2010-03-03 18:03:30 UTC (rev 8175) +++ trunk/matplotlib/doc/users/artists.rst 2010-03-03 21:06:01 UTC (rev 8176) @@ -419,7 +419,7 @@ # and notice that the ax.add_patch method has set the axes # instance In [267]: print rect.get_axes() - Subplot(49,81.25) + Axes(0.125,0.1;0.775x0.8) # and the transformation has been set too In [268]: print rect.get_transform() @@ -434,7 +434,7 @@ (0.0, 1.0) # but the data limits have been updated to encompass the rectangle - In [271]: print ax.dataLim.get_bounds() + In [271]: print ax.dataLim.bounds (1.0, 1.0, 5.0, 12.0) # we can manually invoke the auto-scaling machinery Modified: trunk/matplotlib/lib/matplotlib/artist.py =================================================================== --- trunk/matplotlib/lib/matplotlib/artist.py 2010-03-03 18:03:30 UTC (rev 8175) +++ trunk/matplotlib/lib/matplotlib/artist.py 2010-03-03 21:06:01 UTC (rev 8176) @@ -50,9 +50,9 @@ renderer.stop_rasterizing() # the axes class has a second argument inframe for its draw method. - def draw_wrapper(artist, renderer, *kl): + def draw_wrapper(artist, renderer, *args, **kwargs): before(artist, renderer) - draw(artist, renderer, *kl) + draw(artist, renderer, *args, **kwargs) after(artist, renderer) # "safe wrapping" to exactly replicate anything we haven't overridden above Modified: trunk/matplotlib/lib/matplotlib/backends/backend_wxagg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_wxagg.py 2010-03-03 18:03:30 UTC (rev 8175) +++ trunk/matplotlib/lib/matplotlib/backends/backend_wxagg.py 2010-03-03 21:06:01 UTC (rev 8176) @@ -171,7 +171,7 @@ """ Convert the region of a wx.Image bounded by bbox to a wx.Bitmap. """ - l, b, width, height = bbox.get_bounds() + l, b, width, height = bbox.bounds r = l + width t = b + height @@ -238,7 +238,7 @@ Note: agg must be a backend_agg.RendererAgg instance. """ - l, b, width, height = bbox.get_bounds() + l, b, width, height = bbox.bounds r = l + width t = b + height Modified: trunk/matplotlib/lib/matplotlib/finance.py =================================================================== --- trunk/matplotlib/lib/matplotlib/finance.py 2010-03-03 18:03:30 UTC (rev 8175) +++ trunk/matplotlib/lib/matplotlib/finance.py 2010-03-03 21:06:01 UTC (rev 8176) @@ -597,8 +597,8 @@ maxy = max([volume for d, open, close, high, low, volume in quotes]) corners = (minpy, miny), (maxx, maxy) ax.update_datalim(corners) - #print 'datalim', ax.dataLim.get_bounds() - #print 'viewlim', ax.viewLim.get_bounds() + #print 'datalim', ax.dataLim.bounds + #print 'viewlim', ax.viewLim.bounds ax.add_collection(barCollection) ax.autoscale_view() Modified: trunk/matplotlib/lib/matplotlib/patches.py =================================================================== --- trunk/matplotlib/lib/matplotlib/patches.py 2010-03-03 18:03:30 UTC (rev 8175) +++ trunk/matplotlib/lib/matplotlib/patches.py 2010-03-03 21:06:01 UTC (rev 8176) @@ -1414,12 +1414,12 @@ pad = props.pop('pad', 4) pad = renderer.points_to_pixels(pad) bbox = artist.get_window_extent(renderer) - l,b,w,h = bbox.bounds - l-=pad/2. - b-=pad/2. - w+=pad - h+=pad - r = Rectangle(xy=(l,b), + l, b, w, h = bbox.bounds + l -= pad/2. + b -= pad/2. + w += pad + h += pad + r = Rectangle(xy=(l, b), width=w, height=h, fill=fill, @@ -1438,8 +1438,8 @@ to test whether the artist is returning the correct bbox. """ - l,b,w,h = bbox.get_bounds() - r = Rectangle(xy=(l,b), + l, b, w, h = bbox.bounds + r = Rectangle(xy=(l, b), width=w, height=h, edgecolor=color, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jd...@us...> - 2010-03-09 14:19:56
|
Revision: 8183 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8183&view=rev Author: jdh2358 Date: 2010-03-09 14:19:49 +0000 (Tue, 09 Mar 2010) Log Message: ----------- update make.osx to build on 10.6 Modified Paths: -------------- trunk/matplotlib/make.osx trunk/matplotlib/release/osx/Makefile Modified: trunk/matplotlib/make.osx =================================================================== --- trunk/matplotlib/make.osx 2010-03-08 18:33:04 UTC (rev 8182) +++ trunk/matplotlib/make.osx 2010-03-09 14:19:49 UTC (rev 8183) @@ -4,17 +4,22 @@ PYVERSION=2.6 PYTHON=python${PYVERSION} ZLIBVERSION=1.2.3 -PNGVERSION=1.2.40 +PNGVERSION=1.2.39 FREETYPEVERSION=2.3.11 -MACOSX_DEPLOYMENT_TARGET=10.4 -OSX_SDK_VER=10.4u -ARCH_FLAGS="-arch i386 -arch ppc -arch x86_64" +MACOSX_DEPLOYMENT_TARGET=10.6 +OSX_SDK_VER=10.6 +ARCH_FLAGS="-arch i386-arch x86_64" ## You shouldn't need to configure past this point +#PKG_CONFIG_PATH="${PREFIX}/lib/pkgconfig" +#CFLAGS="${ARCH_FLAGS} -I${PREFIX}/include -I${PREFIX}/include/freetype2 -isysroot /Developer/SDKs/MacOSX${OSX_SDK_VER}.sdk" +#LDFLAGS="${ARCH_FLAGS} -L${PREFIX}/lib -syslibroot,/Developer/SDKs/MacOSX${OSX_SDK_VER}.sdk" + PKG_CONFIG_PATH="${PREFIX}/lib/pkgconfig" -CFLAGS="${ARCH_FLAGS} -I${PREFIX}/include -I${PREFIX}/include/freetype2 -isysroot /Developer/SDKs/MacOSX${OSX_SDK_VER}.sdk" -LDFLAGS="${ARCH_FLAGS} -L${PREFIX}/lib -syslibroot,/Developer/SDKs/MacOSX${OSX_SDK_VER}.sdk" +CFLAGS="-arch i386 -arch x86_64 -I${PREFIX}/include -I${PREFIX}/include/freetype2 -isysroot /Developer/SDKs/MacOSX${OSX_SDK_VER}.sdk" +LDFLAGS="-arch i386 -arch x86_64 -L${PREFIX}/lib -syslibroot,/Developer/SDKs/MacOSX${OSX_SDK_VER}.sdk" +FFLAGS="-arch i386 -arch x86_64" clean: rm -rf zlib-${ZLIBVERSION}.tar.gz libpng-${PNGVERSION}.tar.bz2 \ @@ -23,9 +28,10 @@ zlib-${ZLIBVERSION} libpng-${PNGVERSION} freetype-${FREETYPEVERSION} \ build + fetch: ${PYTHON} -c 'import urllib; urllib.urlretrieve("http://www.zlib.net/zlib-${ZLIBVERSION}.tar.gz", "zlib-${ZLIBVERSION}.tar.gz")' &&\ - ${PYTHON} -c 'import urllib; urllib.urlretrieve("http://download.sourceforge.net/libpng/libpng-${PNGVERSION}.tar.gz", "libpng-${PNGVERSION}.tar.bz2")' &&\ + ${PYTHON} -c 'import urllib; urllib.urlretrieve("http://downloads.sourceforge.net/project/libpng/libpng-stable/${PNGVERSION}/libpng-${PNGVERSION}.tar.gz", "libpng-${PNGVERSION}.tar.gz")' &&\ ${PYTHON} -c 'import urllib; urllib.urlretrieve("http://download.savannah.gnu.org/releases/freetype/freetype-${FREETYPEVERSION}.tar.bz2", "freetype-${FREETYPEVERSION}.tar.bz2")' @@ -34,7 +40,7 @@ zlib: export PKG_CONFIG_PATH=${PKG_CONFIG_PATH} &&\ rm -rf zlib-${ZLIBVERSION} &&\ - tar xvfz zlib-${ZLIBVERSION}.tar.gz &&\ + tar xvfj zlib-${ZLIBVERSION}.tar.gz &&\ cd zlib-${ZLIBVERSION} &&\ export MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET} &&\ export CFLAGS=${CFLAGS} &&\ @@ -46,7 +52,7 @@ png: zlib export PKG_CONFIG_PATH=${PKG_CONFIG_PATH} &&\ rm -rf libpng-${PNGVERSION} &&\ - tar xvfz libpng-${PNGVERSION}.tar.gz + tar xvfz libpng-${PNGVERSION}.tar.gz && \ cd libpng-${PNGVERSION} &&\ export MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET} &&\ export CFLAGS=${CFLAGS} &&\ Modified: trunk/matplotlib/release/osx/Makefile =================================================================== --- trunk/matplotlib/release/osx/Makefile 2010-03-08 18:33:04 UTC (rev 8182) +++ trunk/matplotlib/release/osx/Makefile 2010-03-09 14:19:49 UTC (rev 8183) @@ -4,7 +4,7 @@ ZLIBVERSION=1.2.3 PNGVERSION=1.2.33 FREETYPEVERSION=2.3.7 -MPLVERSION=0.99.0 +MPLVERSION=1.0 BDISTMPKGVERSION=0.4.4 MPLSRC=matplotlib-${MPLVERSION} MACOSX_DEPLOYMENT_TARGET=10.4 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <lee...@us...> - 2010-03-13 22:31:17
|
Revision: 8192 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8192&view=rev Author: leejjoon Date: 2010-03-13 22:31:11 +0000 (Sat, 13 Mar 2010) Log Message: ----------- fix the bug that handles for scatter are incorrectly set when dpi!=72. Thanks to Ray Speth for the bug report. Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/legend.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2010-03-13 22:27:57 UTC (rev 8191) +++ trunk/matplotlib/CHANGELOG 2010-03-13 22:31:11 UTC (rev 8192) @@ -1,3 +1,11 @@ +2010-03-13 Manually brought in commits from branch + + ------------------------------------------------------------------------ + r8191 | leejjoon | 2010-03-13 17:27:57 -0500 (Sat, 13 Mar 2010) | 1 line + + fix the bug that handles for scatter are incorrectly set when dpi!=72. Thanks to Ray Speth for the bug report. + + 2010-03-03 Manually brought in commits from branch via diff/patch (svnmerge is broken) ------------------------------------------------------------------------ Modified: trunk/matplotlib/lib/matplotlib/legend.py =================================================================== --- trunk/matplotlib/lib/matplotlib/legend.py 2010-03-13 22:27:57 UTC (rev 8191) +++ trunk/matplotlib/lib/matplotlib/legend.py 2010-03-13 22:31:11 UTC (rev 8192) @@ -623,6 +623,14 @@ xdescent=0., ydescent=descent) handlebox.add_artist(handle) + + # special case for collection instances + if isinstance(handle, RegularPolyCollection) or \ + isinstance(handle, CircleCollection): + handle._transOffset = handlebox.get_transform() + handle.set_transform(None) + + if hasattr(handle, "_legmarker"): handlebox.add_artist(handle._legmarker) handleboxes.append(handlebox) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <he...@us...> - 2010-03-19 17:12:49
|
Revision: 8199 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8199&view=rev Author: heeres Date: 2010-03-19 17:12:41 +0000 (Fri, 19 Mar 2010) Log Message: ----------- Some fixes Modified Paths: -------------- trunk/matplotlib/examples/mplot3d/hist3d_demo.py trunk/matplotlib/examples/mplot3d/text3d_demo.py trunk/matplotlib/lib/mpl_toolkits/mplot3d/art3d.py trunk/matplotlib/lib/mpl_toolkits/mplot3d/axes3d.py Modified: trunk/matplotlib/examples/mplot3d/hist3d_demo.py =================================================================== --- trunk/matplotlib/examples/mplot3d/hist3d_demo.py 2010-03-19 16:50:37 UTC (rev 8198) +++ trunk/matplotlib/examples/mplot3d/hist3d_demo.py 2010-03-19 17:12:41 UTC (rev 8199) @@ -17,7 +17,7 @@ dy = dx.copy() dz = hist.flatten() -ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color='b') +ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color='b', zsort='average') plt.show() Modified: trunk/matplotlib/examples/mplot3d/text3d_demo.py =================================================================== --- trunk/matplotlib/examples/mplot3d/text3d_demo.py 2010-03-19 16:50:37 UTC (rev 8198) +++ trunk/matplotlib/examples/mplot3d/text3d_demo.py 2010-03-19 17:12:41 UTC (rev 8199) @@ -13,6 +13,9 @@ label = '(%d, %d, %d), dir=%s' % (x, y, z, zdir) ax.text(x, y, z, label, zdir) +ax.text(1, 1, 1, "red", color='red') +ax.text2D(0.05, 0.95, "2D Text", transform=ax.transAxes) + ax.set_xlim3d(0, 10) ax.set_ylim3d(0, 10) ax.set_zlim3d(0, 10) Modified: trunk/matplotlib/lib/mpl_toolkits/mplot3d/art3d.py =================================================================== --- trunk/matplotlib/lib/mpl_toolkits/mplot3d/art3d.py 2010-03-19 16:50:37 UTC (rev 8198) +++ trunk/matplotlib/lib/mpl_toolkits/mplot3d/art3d.py 2010-03-19 17:12:41 UTC (rev 8199) @@ -1,6 +1,7 @@ #!/usr/bin/python # art3d.py, original mplot3d version by John Porter # Parts rewritten by Reinier Heeres <re...@he...> +# Minor additions by Ben Axelrod <bax...@co...> ''' Module containing 3D artist code and functions to convert 2D @@ -15,6 +16,7 @@ from matplotlib.colors import Normalize from matplotlib.cbook import iterable +import warnings import numpy as np import math import proj3d @@ -52,8 +54,15 @@ Text object with 3D position and (in the future) direction. ''' - def __init__(self, x=0, y=0, z=0, text='', zdir='z'): - mtext.Text.__init__(self, x, y, text) + def __init__(self, x=0, y=0, z=0, text='', zdir='z', **kwargs): + ''' + *x*, *y*, *z* Position of text + *text* Text string to display + *zdir* Direction of text + + Keyword arguments are passed onto :func:`~matplotlib.text.Text`. + ''' + mtext.Text.__init__(self, x, y, text, **kwargs) self.set_3d_properties(z, zdir) def set_3d_properties(self, z=0, zdir='z'): @@ -86,6 +95,9 @@ ''' def __init__(self, xs, ys, zs, *args, **kwargs): + ''' + Keyword arguments are passed onto :func:`~matplotlib.lines.Line2D`. + ''' lines.Line2D.__init__(self, [], [], *args, **kwargs) self._verts3d = xs, ys, zs @@ -145,6 +157,9 @@ ''' def __init__(self, segments, *args, **kwargs): + ''' + Keyword arguments are passed onto :func:`~matplotlib.collections.LineCollection`. + ''' LineCollection.__init__(self, segments, *args, **kwargs) def set_segments(self, segments): @@ -317,13 +332,44 @@ *verts* should contain 3D coordinates. + Keyword arguments: + zsort, see set_zsort for options. + Note that this class does a bit of magic with the _facecolors and _edgecolors properties. ''' + self.set_zsort(kwargs.pop('zsort', True)) + PolyCollection.__init__(self, verts, *args, **kwargs) - self._zsort = 1 + + _zsort_functions = { + 'average': np.average, + 'min': np.min, + 'max': np.max, + } + + def set_zsort(self, zsort): + ''' + Set z-sorting behaviour: + boolean: if True use default 'average' + string: 'average', 'min' or 'max' + ''' + + if zsort is True: + zsort = 'average' + + if zsort is not False: + if zsort in self._zsort_functions: + zsortfunc = self._zsort_functions[zsort] + else: + return False + else: + zsortfunc = None + + self._zsort = zsort self._sort_zpos = None + self._zsortfunc = zsortfunc def get_vector(self, segments3d): """Optimize points for projection""" @@ -348,12 +394,13 @@ PolyCollection.set_verts(self, [], closed) def set_3d_properties(self): - self._zsort = 1 self._sort_zpos = None + self.set_zsort(True) self._facecolors3d = PolyCollection.get_facecolors(self) self._edgecolors3d = PolyCollection.get_edgecolors(self) - def set_sort_zpos(self, val): + def set_sort_zpos(self,val): + '''Set the position to use for z-sorting.''' self._sort_zpos = val def do_3d_projection(self, renderer): @@ -381,7 +428,7 @@ # if required sort by depth (furthest drawn first) if self._zsort: - z_segments_2d = [(np.average(zs), zip(xs, ys), fc, ec) for + z_segments_2d = [(self._zsortfunc(zs), zip(xs, ys), fc, ec) for (xs, ys, zs), fc, ec in zip(xyzlist, cface, cedge)] z_segments_2d.sort(cmp=lambda x, y: cmp(y[0], x[0])) else: @@ -468,9 +515,14 @@ def iscolor(c): try: - return (len(c) == 4 or len(c) == 3) and hasattr(c[0], '__float__') - except (IndexError): + if len(c) == 4 or len(c) == 3: + if iterable(c[0]): + return False + if hasattr(c[0], '__float__'): + return True + except: return False + return False def get_colors(c, num): """Stretch the color argument to provide the required number num""" @@ -484,6 +536,8 @@ return c elif iscolor(c): return [c] * num + elif len(c) == 0: #if edgecolor or facecolor is specified as 'none' + return [[0,0,0,0]] * num elif iscolor(c[0]): return [c[0]] * num else: Modified: trunk/matplotlib/lib/mpl_toolkits/mplot3d/axes3d.py =================================================================== --- trunk/matplotlib/lib/mpl_toolkits/mplot3d/axes3d.py 2010-03-19 16:50:37 UTC (rev 8198) +++ trunk/matplotlib/lib/mpl_toolkits/mplot3d/axes3d.py 2010-03-19 17:12:41 UTC (rev 8199) @@ -2,12 +2,14 @@ # axes3d.py, original mplot3d version by John Porter # Created: 23 Sep 2005 # Parts fixed by Reinier Heeres <re...@he...> +# Minor additions by Ben Axelrod <bax...@co...> """ Module containing Axes3D, an object which can plot 3D objects on a 2D matplotlib figure. """ +import warnings from matplotlib.axes import Axes, rcParams from matplotlib import cbook from matplotlib.transforms import Bbox @@ -55,7 +57,7 @@ if rect is None: rect = [0.0, 0.0, 1.0, 1.0] self.fig = fig - self.cids = [] + self._cids = [] azim = kwargs.pop('azim', -60) elev = kwargs.pop('elev', 30) @@ -147,7 +149,7 @@ # Calculate projection of collections and zorder them zlist = [(col.do_3d_projection(renderer), col) \ - for col in self.collections] + for col in self.collections] zlist.sort() zlist.reverse() for i, (z, col) in enumerate(zlist): @@ -322,23 +324,52 @@ M = np.dot(perspM, M0) return M - def mouse_init(self): + def mouse_init(self, rotate_btn=1, zoom_btn=3): + """Initializes mouse button callbacks to enable 3D rotation of + the axes. Also optionally sets the mouse buttons for 3D rotation + and zooming. + + ============ ================================================ + Argument Description + ============ ================================================ + *rotate_btn* The integer or list of integers specifying which mouse + button or buttons to use for 3D rotation of the axes. + Default = 1. + + *zoom_btn* The integer or list of integers specifying which mouse + button or buttons to use to zoom the 3D axes. + Default = 3. + ============ ================================================ + """ self.button_pressed = None canv = self.figure.canvas if canv != None: c1 = canv.mpl_connect('motion_notify_event', self._on_move) c2 = canv.mpl_connect('button_press_event', self._button_press) c3 = canv.mpl_connect('button_release_event', self._button_release) - self.cids = [c1, c2, c3] + self._cids = [c1, c2, c3] + else: + warnings.warn('Axes3D.figure.canvas is \'None\', mouse rotation disabled. Set canvas then call Axes3D.mouse_init().') + self._rotate_btn = np.atleast_1d(rotate_btn) + self._zoom_btn = np.atleast_1d(zoom_btn) + def cla(self): - # Disconnect the various events we set. - for cid in self.cids: - self.figure.canvas.mpl_disconnect(cid) - self.cids = [] + """Clear axes and disable mouse button callbacks. + """ + self.disable_mouse_rotation() Axes.cla(self) self.grid(rcParams['axes3d.grid']) + def disable_mouse_rotation(self): + """Disable mouse button callbacks. + """ + # Disconnect the various events we set. + for cid in self._cids: + self.figure.canvas.mpl_disconnect(cid) + + self._cids = [] + def _button_press(self, event): if event.inaxes == self: self.button_pressed = event.button @@ -426,9 +457,10 @@ def _on_move(self, event): """Mouse moving - button-1 rotates - button-3 zooms + button-1 rotates by default. Can be set explicitly in mouse_init(). + button-3 zooms by default. Can be set explicitly in mouse_init(). """ + if not self.button_pressed: return @@ -447,7 +479,8 @@ h = (y1-y0) self.sx, self.sy = x, y - if self.button_pressed == 1: + # Rotation + if self.button_pressed in self._rotate_btn: # rotate viewing point # get the x and y pixel coords if dx == 0 and dy == 0: @@ -456,12 +489,15 @@ self.azim = art3d.norm_angle(self.azim - (dx/w)*180) self.get_proj() self.figure.canvas.draw() - elif self.button_pressed == 2: + +# elif self.button_pressed == 2: # pan view # project xv,yv,zv -> xw,yw,zw # pan - pass - elif self.button_pressed == 3: +# pass + + # Zoom + elif self.button_pressed in self._zoom_btn: # zoom view # hmmm..this needs some help from clipping.... minx, maxx, miny, maxy, minz, maxz = self.get_w_lims() @@ -476,7 +512,7 @@ self.figure.canvas.draw() def set_xlabel(self, xlabel, fontdict=None, **kwargs): - '''Set xlabel. ''' + '''Set xlabel.''' label = self.w_xaxis.get_label() label.set_text(xlabel) @@ -511,13 +547,18 @@ ''' self._draw_grid = on - def text(self, x, y, z, s, zdir=None): - '''Add text to the plot.''' - text = Axes.text(self, x, y, s) + def text(self, x, y, z, s, zdir=None, **kwargs): + ''' + Add text to the plot. kwargs will be passed on to Axes.text, + except for the `zdir` keyword, which sets the direction to be + used as the z direction. + ''' + text = Axes.text(self, x, y, s, **kwargs) art3d.text_2d_to_3d(text, z, zdir) return text text3D = text + text2D = Axes.text def plot(self, xs, ys, *args, **kwargs): ''' @@ -591,6 +632,9 @@ *shade* Whether to shade the facecolors, default: false when cmap specified, true otherwise ========== ================================================ + + Other arguments are passed on to + :func:`~mpl_toolkits.mplot3d.art3d.Poly3DCollection.__init__` ''' had_data = self.has_data() @@ -822,8 +866,9 @@ colors = self._shade_colors(color, normals) colors2 = self._shade_colors(color, normals) - polycol = art3d.Poly3DCollection(polyverts, facecolors=colors, - edgecolors=colors2) + polycol = art3d.Poly3DCollection(polyverts, + facecolors=colors, + edgecolors=colors2) polycol.set_sort_zpos(z) self.add_collection3d(polycol) @@ -848,6 +893,8 @@ Other keyword arguments are passed on to :func:`~matplotlib.axes.Axes.contour` + + Returns a :class:`~matplotlib.axes.Axes.contour` ''' extend3d = kwargs.pop('extend3d', False) @@ -881,7 +928,9 @@ *X*, *Y*, *Z*: data points. Keyword arguments are passed on to - :func:`~matplotlib.axes.Axes.contour` + :func:`~matplotlib.axes.Axes.contourf` + + Returns a :class:`~matplotlib.axes.Axes.contourf` ''' had_data = self.has_data() @@ -1005,25 +1054,61 @@ return patches - def bar3d(self, x, y, z, dx, dy, dz, color='b'): + def bar3d(self, x, y, z, dx, dy, dz, color='b', + zsort='average', *args, **kwargs): ''' Generate a 3D bar, or multiple bars. When generating multiple bars, x, y, z have to be arrays. - dx, dy, dz can still be scalars. + dx, dy, dz can be arrays or scalars. + + *color* can be: + - A single color value, to color all bars the same color. + - An array of colors of length N bars, to color each bar + independently. + - An array of colors of length 6, to color the faces of the bars + similarly. + - An array of colors of length 6 * N bars, to color each face + independently. + + When coloring the faces of the boxes specifically, this is the order + of the coloring: + 1. -Z (bottom of box) + 2. +Z (top of box) + 3. -Y + 4. +Y + 5. -X + 6. +X + + Keyword arguments are passed onto + :func:`~mpl_toolkits.mplot3d.art3d.Poly3DCollection` ''' - had_data = self.has_data() if not cbook.iterable(x): - x, y, z = [x], [y], [z] + x = [x] + if not cbook.iterable(y): + y = [y] + if not cbook.iterable(z): + z = [z] + if not cbook.iterable(dx): - dx, dy, dz = [dx], [dy], [dz] + dx = [dx] + if not cbook.iterable(dy): + dy = [dy] + if not cbook.iterable(dz): + dz = [dz] + if len(dx) == 1: dx = dx * len(x) - dy = dy * len(x) - dz = dz * len(x) + if len(dy) == 1: + dy = dy * len(y) + if len(dz) == 1: + dz = dz * len(z) + if len(x) != len(y) or len(x) != len(z): + warnings.warn('x, y, and z must be the same length.') + minx, miny, minz = 1e20, 1e20, 1e20 maxx, maxy, maxz = -1e20, -1e20, -1e20 @@ -1053,15 +1138,35 @@ (xi + dxi, yi + dyi, zi + dzi), (xi + dxi, yi, zi + dzi)), ]) - color = np.array(colorConverter.to_rgba(color)) + facecolors = [] + if color is None: + # no color specified + facecolors = [None] * len(x) + elif len(color) == len(x): + # bar colors specified, need to expand to number of faces + for c in color: + facecolors.extend([c] * 6) + else: + # a single color specified, or face colors specified explicitly + facecolors = list(colorConverter.to_rgba_array(color)) + if len(facecolors) < len(x): + facecolors *= (6 * len(x)) + normals = self._generate_normals(polys) - colors = self._shade_colors(color, normals) - - col = art3d.Poly3DCollection(polys, facecolor=colors) + sfacecolors = self._shade_colors(facecolors, normals) + col = art3d.Poly3DCollection(polys, + zsort=zsort, + facecolor=sfacecolors, + *args, **kwargs) self.add_collection(col) self.auto_scale_xyz((minx, maxx), (miny, maxy), (minz, maxz), had_data) + def set_title(self, label, fontdict=None, **kwargs): + Axes.set_title(self, label, fontdict, **kwargs) + (x, y) = self.title.get_position() + self.title.set_y(0.92 * y) + def get_test_data(delta=0.05): ''' Return a tuple X, Y, Z with a test data set. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fer...@us...> - 2010-03-20 08:57:45
|
Revision: 8201 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8201&view=rev Author: fer_perez Date: 2010-03-20 08:57:37 +0000 (Sat, 20 Mar 2010) Log Message: ----------- Renamed fig_subplot to suplots(), now returns numpy array with axes. Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/examples/pylab_examples/fig_subplot_demo.py trunk/matplotlib/lib/matplotlib/pyplot.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2010-03-20 00:29:19 UTC (rev 8200) +++ trunk/matplotlib/CHANGELOG 2010-03-20 08:57:37 UTC (rev 8201) @@ -1,3 +1,7 @@ +2010-03-20 Changed plt.fig_subplot() to plt.subplots() after discussion on + list, and changed its API to return axes as a numpy object array + (with control of dimensions via squeeze keyword). FP. + 2010-03-13 Manually brought in commits from branch ------------------------------------------------------------------------ Modified: trunk/matplotlib/examples/pylab_examples/fig_subplot_demo.py =================================================================== --- trunk/matplotlib/examples/pylab_examples/fig_subplot_demo.py 2010-03-20 00:29:19 UTC (rev 8200) +++ trunk/matplotlib/examples/pylab_examples/fig_subplot_demo.py 2010-03-20 08:57:37 UTC (rev 8201) @@ -1,32 +1,39 @@ +"""Examples illustrating the use of plt.subplots(). + +This function creates a figure and a grid of subplots with a single call, while +providing reasonable control over how the individual plots are created. For +very refined tuning of subplot creation, you can still use add_subplot() +directly on a new figure. """ -""" + import matplotlib.pyplot as plt import numpy as np +# Simple data to display in various forms x = np.linspace(0, 2*np.pi, 400) y = np.sin(x**2) plt.close('all') # Just a figure and one subplot -f, ax = plt.fig_subplot() +f, ax = plt.subplots() ax.plot(x, y) ax.set_title('Simple plot') -# Two subplots, grab the whole fig_axes list -fax = plt.fig_subplot(2, sharex=True) -fax[1].plot(x, y) -fax[1].set_title('Sharing X axis') -fax[2].scatter(x, y) +# Two subplots, the axes array is 1-d +f, axarr = plt.subplots(2, sharex=True) +axarr[0].plot(x, y) +axarr[0].set_title('Sharing X axis') +axarr[1].scatter(x, y) -# Two subplots, unpack the output immediately -f, ax1, ax2 = plt.fig_subplot(1, 2, sharey=True) +# Two subplots, unpack the axes array immediately +f, (ax1, ax2) = plt.subplots(1, 2, sharey=True) ax1.plot(x, y) ax1.set_title('Sharing Y axis') ax2.scatter(x, y) # Three subplots sharing both x/y axes -f, ax1, ax2, ax3 = plt.fig_subplot(3, sharex=True, sharey=True) +f, (ax1, ax2, ax3) = plt.subplots(3, sharex=True, sharey=True) ax1.plot(x, y) ax1.set_title('Sharing both axes') ax2.scatter(x, y) @@ -36,7 +43,21 @@ f.subplots_adjust(hspace=0) plt.setp([a.get_xticklabels() for a in f.axes[:-1]], visible=False) +# Four axes, returned as a 2-d array +f, axarr = plt.subplots(2, 2) +axarr[0,0].plot(x, y) +axarr[0,0].set_title('Axis [0,0]') +axarr[0,1].scatter(x, y) +axarr[0,1].set_title('Axis [0,1]') +axarr[1,0].plot(x, y**2) +axarr[1,0].set_title('Axis [1,0]') +axarr[1,1].scatter(x, y**2) +axarr[1,1].set_title('Axis [1,1]') +# Fine-tune figure; hide x ticks for top plots and y ticks for right plots +plt.setp([a.get_xticklabels() for a in axarr[0,:]], visible=False) +plt.setp([a.get_yticklabels() for a in axarr[:,1]], visible=False) + # Four polar axes -plt.fig_subplot(2, 2, subplot_kw=dict(polar=True)) +plt.subplots(2, 2, subplot_kw=dict(polar=True)) plt.show() Modified: trunk/matplotlib/lib/matplotlib/pyplot.py =================================================================== --- trunk/matplotlib/lib/matplotlib/pyplot.py 2010-03-20 00:29:19 UTC (rev 8200) +++ trunk/matplotlib/lib/matplotlib/pyplot.py 2010-03-20 08:57:37 UTC (rev 8201) @@ -79,7 +79,6 @@ new_figure_manager, draw_if_interactive, show = pylab_setup() - def findobj(o=None, match=None): if o is None: o = gcf() @@ -649,7 +648,7 @@ return a -def fig_subplot(nrows=1, ncols=1, sharex=False, sharey=False, +def subplots(nrows=1, ncols=1, sharex=False, sharey=False, squeeze=True, subplot_kw=None, **fig_kw): """Create a figure with a set of subplots already made. @@ -661,7 +660,7 @@ nrows : int Number of rows of the subplot grid. Defaults to 1. - nrows : int + ncols : int Number of columns of the subplot grid. Defaults to 1. sharex : bool @@ -670,6 +669,18 @@ sharex : bool If True, the Y axis will be shared amongst all subplots. + squeeze : bool + + If True, extra dimensions are squeezed out from the returned axis object: + - if only one subplot is constructed (nrows=ncols=1), the resulting + single Axis object is returned as a scalar. + - for Nx1 or 1xN subplots, the returned object is a 1-d numpy object + array of Axis objects are returned as numpy 1-d arrays. + - for NxM subplots with N>1 and M>1 are returned as a 2d array. + + If False, no squeezing at all is done: the returned axis object is always + a 2-d array contaning Axis instances, even if it ends up being 1x1. + subplot_kw : dict Dict with keywords passed to the add_subplot() call used to create each subplots. @@ -680,28 +691,30 @@ Returns: - fig_axes : list - A list containing [fig, ax1, ax2, ...], where fig is the Matplotlib - Figure object and the rest are the axes. - + fig, ax : tuple + - fig is the Matplotlib Figure object + - ax can be either a single axis object or an array of axis objects if + more than one supblot was created. The dimensions of the resulting array + can be controlled with the squeeze keyword, see above. + **Examples:** x = np.linspace(0, 2*np.pi, 400) y = np.sin(x**2) # Just a figure and one subplot - f, ax = plt.fig_subplot() + f, ax = plt.subplots() ax.plot(x, y) ax.set_title('Simple plot') - # Two subplots, unpack the output immediately - f, ax1, ax2 = plt.fig_subplot(1, 2, sharey=True) + # Two subplots, unpack the output array immediately + f, (ax1, ax2) = plt.subplots(1, 2, sharey=True) ax1.plot(x, y) ax1.set_title('Sharing Y axis') ax2.scatter(x, y) # Four polar axes - plt.fig_subplot(2, 2, subplot_kw=dict(polar=True)) + plt.subplots(2, 2, subplot_kw=dict(polar=True)) """ if subplot_kw is None: @@ -709,20 +722,37 @@ fig = figure(**fig_kw) + # Create empty object array to hold all axes. It's easiest to make it 1-d + # so we can just append subplots upon creation, and then + nplots = nrows*ncols + axarr = np.empty(nplots, dtype=object) + # Create first subplot separately, so we can share it if requested - ax1 = fig.add_subplot(nrows, ncols, 1, **subplot_kw) + ax0 = fig.add_subplot(nrows, ncols, 1, **subplot_kw) if sharex: - subplot_kw['sharex'] = ax1 + subplot_kw['sharex'] = ax0 if sharey: - subplot_kw['sharey'] = ax1 + subplot_kw['sharey'] = ax0 + axarr[0] = ax0 + + # Note off-by-one counting because add_subplot uses the matlab 1-based + # convention. + for i in range(1, nplots): + axarr[i] = fig.add_subplot(nrows, ncols, i+1, **subplot_kw) - # Valid indices for axes start at 1, since fig is at 0: - axes = [ fig.add_subplot(nrows, ncols, i, **subplot_kw) - for i in range(2, nrows*ncols+1)] + if squeeze: + # Reshape the array to have the final desired dimension (nrow,ncol), + # though discarding unneeded dimensions that equal 1. If we only have + # one subplot, just return it instead of a 1-element array. + if nplots==1: + return fig, axarr[0] + else: + return fig, axarr.reshape(nrows, ncols).squeeze() + else: + # returned axis array will be always 2-d, even if nrows=ncols=1 + return fig, axarr.reshape(nrows, ncols) - return [fig, ax1] + axes - def twinx(ax=None): """ Make a second axes overlay *ax* (or the current axes if *ax* is This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ef...@us...> - 2010-03-20 23:24:37
|
Revision: 8204 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8204&view=rev Author: efiring Date: 2010-03-20 23:24:29 +0000 (Sat, 20 Mar 2010) Log Message: ----------- CHANGELOG update and format fixups; fix python version info in INSTALL Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/INSTALL Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2010-03-20 22:49:25 UTC (rev 8203) +++ trunk/matplotlib/CHANGELOG 2010-03-20 23:24:29 UTC (rev 8204) @@ -1,16 +1,20 @@ +2010-03-20 Added conditional support for new Tooltip API in gtk backend. - EF + 2010-03-20 Changed plt.fig_subplot() to plt.subplots() after discussion on - list, and changed its API to return axes as a numpy object array - (with control of dimensions via squeeze keyword). FP. + list, and changed its API to return axes as a numpy object array + (with control of dimensions via squeeze keyword). FP. 2010-03-13 Manually brought in commits from branch ------------------------------------------------------------------------ r8191 | leejjoon | 2010-03-13 17:27:57 -0500 (Sat, 13 Mar 2010) | 1 line - fix the bug that handles for scatter are incorrectly set when dpi!=72. Thanks to Ray Speth for the bug report. + fix the bug that handles for scatter are incorrectly set when dpi!=72. + Thanks to Ray Speth for the bug report. -2010-03-03 Manually brought in commits from branch via diff/patch (svnmerge is broken) +2010-03-03 Manually brought in commits from branch via diff/patch + (svnmerge is broken) ------------------------------------------------------------------------ r8175 | leejjoon | 2010-03-03 10:03:30 -0800 (Wed, 03 Mar 2010) | 1 line @@ -35,15 +39,15 @@ 2010-02-25 add annotation_demo3.py that demonstrates new functionality. -JJL -2010-02-25 refactor Annotation to support arbitrary Transform as xycoords - or textcoords. Also, if a tuple of two coordinates is provided, - they are interpreted as coordinates for each x and y position. +2010-02-25 refactor Annotation to support arbitrary Transform as xycoords + or textcoords. Also, if a tuple of two coordinates is provided, + they are interpreted as coordinates for each x and y position. -JJL 2010-02-24 Added pyplot.fig_subplot(), to create a figure and a group of - subplots in a single call. This offers an easier pattern than - manually making figures and calling add_subplot() multiple times. FP - + subplots in a single call. This offers an easier pattern than + manually making figures and calling add_subplot() multiple times. FP + 2010-02-17 Added Gokhan's and Mattias' customizable keybindings patch for the toolbar. You can now set the keymap.* properties in the matplotlibrc file. Newbindings were added for @@ -67,7 +71,7 @@ warnings can be turned into fatal errors easily if desired. - FP 2010-01-29 Added draggable method to Legend to allow mouse drag -placement. Thanks Adam Fraser. JDH + placement. Thanks Adam Fraser. JDH 2010-01-25 Fixed a bug reported by Olle Engdegard, when using histograms with stepfilled and log=True - MM Modified: trunk/matplotlib/INSTALL =================================================================== --- trunk/matplotlib/INSTALL 2010-03-20 22:49:25 UTC (rev 8203) +++ trunk/matplotlib/INSTALL 2010-03-20 23:24:29 UTC (rev 8204) @@ -1,7 +1,7 @@ INTRODUCTION - matplotlib requires at a minimum python 2.3, numpy, libpng and + matplotlib requires at a minimum python 2.4, numpy, libpng and freetype. To get the most out of matplotlib, you will want to build some of the optional GUI and image extensions, discussed below. Matplotlib is known to work on linux, unix, win32 and OS X This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ef...@us...> - 2010-03-21 00:39:12
|
Revision: 8205 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8205&view=rev Author: efiring Date: 2010-03-21 00:39:04 +0000 (Sun, 21 Mar 2010) Log Message: ----------- pyplot: new sca() function suggested by LJJ Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/pyplot.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2010-03-20 23:24:29 UTC (rev 8204) +++ trunk/matplotlib/CHANGELOG 2010-03-21 00:39:04 UTC (rev 8205) @@ -1,3 +1,5 @@ +2010-03-20 Added pyplot.sca() function suggested by JJL. - EF + 2010-03-20 Added conditional support for new Tooltip API in gtk backend. - EF 2010-03-20 Changed plt.fig_subplot() to plt.subplots() after discussion on Modified: trunk/matplotlib/lib/matplotlib/pyplot.py =================================================================== --- trunk/matplotlib/lib/matplotlib/pyplot.py 2010-03-20 23:24:29 UTC (rev 8204) +++ trunk/matplotlib/lib/matplotlib/pyplot.py 2010-03-21 00:39:04 UTC (rev 8205) @@ -549,9 +549,20 @@ draw_if_interactive() return ret +def sca(ax): + """ + Set the current Axes instance to *ax*. The current Figure + is updated to the parent of *ax*. + """ + managers = _pylab_helpers.Gcf.get_all_fig_managers() + for m in managers: + if ax in m.canvas.figure.axes: + _pylab_helpers.Gcf.set_active(m) + m.canvas.figure.sca(ax) + return + raise ValueError("Axes instance argument was not found in a figure.") - def gca(**kwargs): """ Return the current axis instance. This can be used to control @@ -656,7 +667,7 @@ subplots, including the enclosing figure object, in a single call. Keyword arguments: - + nrows : int Number of rows of the subplot grid. Defaults to 1. @@ -670,7 +681,7 @@ If True, the Y axis will be shared amongst all subplots. squeeze : bool - + If True, extra dimensions are squeezed out from the returned axis object: - if only one subplot is constructed (nrows=ncols=1), the resulting single Axis object is returned as a scalar. @@ -696,7 +707,7 @@ - ax can be either a single axis object or an array of axis objects if more than one supblot was created. The dimensions of the resulting array can be controlled with the squeeze keyword, see above. - + **Examples:** x = np.linspace(0, 2*np.pi, 400) @@ -706,7 +717,7 @@ f, ax = plt.subplots() ax.plot(x, y) ax.set_title('Simple plot') - + # Two subplots, unpack the output array immediately f, (ax1, ax2) = plt.subplots(1, 2, sharey=True) ax1.plot(x, y) @@ -719,11 +730,11 @@ if subplot_kw is None: subplot_kw = {} - + fig = figure(**fig_kw) # Create empty object array to hold all axes. It's easiest to make it 1-d - # so we can just append subplots upon creation, and then + # so we can just append subplots upon creation, and then nplots = nrows*ncols axarr = np.empty(nplots, dtype=object) @@ -734,9 +745,9 @@ if sharey: subplot_kw['sharey'] = ax0 axarr[0] = ax0 - + # Note off-by-one counting because add_subplot uses the matlab 1-based - # convention. + # convention. for i in range(1, nplots): axarr[i] = fig.add_subplot(nrows, ncols, i+1, **subplot_kw) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <lee...@us...> - 2010-03-21 22:02:38
|
Revision: 8209 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8209&view=rev Author: leejjoon Date: 2010-03-21 22:02:31 +0000 (Sun, 21 Mar 2010) Log Message: ----------- x or y key during the zoom mode only change the x or y limits Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/backend_bases.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2010-03-21 19:27:52 UTC (rev 8208) +++ trunk/matplotlib/CHANGELOG 2010-03-21 22:02:31 UTC (rev 8209) @@ -1,3 +1,5 @@ +2010-03-21 x/y key during the zoom mode only changes the x/y limits. -JJL + 2010-03-20 Added pyplot.sca() function suggested by JJL. - EF 2010-03-20 Added conditional support for new Tooltip API in gtk backend. - EF Modified: trunk/matplotlib/lib/matplotlib/backend_bases.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backend_bases.py 2010-03-21 19:27:52 UTC (rev 8208) +++ trunk/matplotlib/lib/matplotlib/backend_bases.py 2010-03-21 22:02:31 UTC (rev 8209) @@ -2049,6 +2049,10 @@ self._lastCursor = None self._init_toolbar() self._idDrag=self.canvas.mpl_connect('motion_notify_event', self.mouse_move) + + self._ids_zoom = None + self._zoom_mode = None + self._button_pressed = None # determined by the button pressed at start self.mode = '' # a mode string for the status bar @@ -2123,6 +2127,14 @@ if self._xypress: x, y = event.x, event.y lastx, lasty, a, ind, lim, trans = self._xypress[0] + + if self._zoom_mode == "x": + x1, y1, x2, y2 = event.inaxes.bbox.extents + y, lasty = y1, y2 + elif self._zoom_mode == "y": + x1, y1, x2, y2 = event.inaxes.bbox.extents + x, lastx = x1, x2 + self.draw_rubberband(event, x, y, lastx, lasty) elif (self._active=='PAN' and self._lastCursor != cursors.MOVE): @@ -2225,8 +2237,26 @@ and a.get_navigate() and a.can_zoom(): self._xypress.append(( x, y, a, i, a.viewLim.frozen(), a.transData.frozen())) + id1 = self.canvas.mpl_connect('key_press_event', + self._switch_on_zoom_mode) + id2 = self.canvas.mpl_connect('key_release_event', + self._switch_off_zoom_mode) + + self._ids_zoom = id1, id2 + + self._zoom_mode = event.key + + self.press(event) + def _switch_on_zoom_mode(self, event): + self._zoom_mode = event.key + self.mouse_move(event) + + def _switch_off_zoom_mode(self, event): + self._zoom_mode = None + self.mouse_move(event) + def push_current(self): 'push the current view limits and position onto the stack' lims = []; pos = [] @@ -2275,6 +2305,9 @@ 'the release mouse button callback in zoom to rect mode' if not self._xypress: return + for zoom_id in self._ids_zoom: + self.canvas.mpl_disconnect(zoom_id) + last_a = [] for cur_xypress in self._xypress: @@ -2334,8 +2367,13 @@ if y1 < Ymax: y1=Ymax if self._button_pressed == 1: - a.set_xlim((x0, x1)) - a.set_ylim((y0, y1)) + if self._zoom_mode == "x": + a.set_xlim((x0, x1)) + elif self._zoom_mode == "y": + a.set_ylim((y0, y1)) + else: + a.set_xlim((x0, x1)) + a.set_ylim((y0, y1)) elif self._button_pressed == 3: if a.get_xscale()=='log': alpha=np.log(Xmax/Xmin)/np.log(x1/x0) @@ -2353,13 +2391,21 @@ alpha=(Ymax-Ymin)/(y1-y0) ry1=alpha*(Ymin-y0)+Ymin ry2=alpha*(Ymax-y0)+Ymin - a.set_xlim((rx1, rx2)) - a.set_ylim((ry1, ry2)) + if self._zoom_mode == "x": + a.set_xlim((rx1, rx2)) + elif self._zoom_mode == "y": + a.set_ylim((ry1, ry2)) + else: + a.set_xlim((rx1, rx2)) + a.set_ylim((ry1, ry2)) + self.draw() self._xypress = None self._button_pressed = None + self._zoom_mode = None + self.push_current() self.release(event) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <lee...@us...> - 2010-03-22 16:47:33
|
Revision: 8210 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8210&view=rev Author: leejjoon Date: 2010-03-22 16:47:27 +0000 (Mon, 22 Mar 2010) Log Message: ----------- fix incorrect rubber band during the zoom mode when mouse the axes Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/backend_bases.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2010-03-21 22:02:31 UTC (rev 8209) +++ trunk/matplotlib/CHANGELOG 2010-03-22 16:47:27 UTC (rev 8210) @@ -1,3 +1,6 @@ +2010-03-22 fix incorrect rubber band during the zoom mode when mouse + leaves the axes. -JJL + 2010-03-21 x/y key during the zoom mode only changes the x/y limits. -JJL 2010-03-20 Added pyplot.sca() function suggested by JJL. - EF Modified: trunk/matplotlib/lib/matplotlib/backend_bases.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backend_bases.py 2010-03-21 22:02:31 UTC (rev 8209) +++ trunk/matplotlib/lib/matplotlib/backend_bases.py 2010-03-22 16:47:27 UTC (rev 8210) @@ -2124,18 +2124,6 @@ if self._lastCursor != cursors.SELECT_REGION: self.set_cursor(cursors.SELECT_REGION) self._lastCursor = cursors.SELECT_REGION - if self._xypress: - x, y = event.x, event.y - lastx, lasty, a, ind, lim, trans = self._xypress[0] - - if self._zoom_mode == "x": - x1, y1, x2, y2 = event.inaxes.bbox.extents - y, lasty = y1, y2 - elif self._zoom_mode == "y": - x1, y1, x2, y2 = event.inaxes.bbox.extents - x, lastx = x1, x2 - - self.draw_rubberband(event, x, y, lastx, lasty) elif (self._active=='PAN' and self._lastCursor != cursors.MOVE): self.set_cursor(cursors.MOVE) @@ -2237,12 +2225,14 @@ and a.get_navigate() and a.can_zoom(): self._xypress.append(( x, y, a, i, a.viewLim.frozen(), a.transData.frozen())) - id1 = self.canvas.mpl_connect('key_press_event', + id1 = self.canvas.mpl_connect('motion_notify_event', self.drag_zoom) + + id2 = self.canvas.mpl_connect('key_press_event', self._switch_on_zoom_mode) - id2 = self.canvas.mpl_connect('key_release_event', + id3 = self.canvas.mpl_connect('key_release_event', self._switch_off_zoom_mode) - self._ids_zoom = id1, id2 + self._ids_zoom = id1, id2, id3 self._zoom_mode = event.key @@ -2301,6 +2291,29 @@ a.drag_pan(self._button_pressed, event.key, event.x, event.y) self.dynamic_update() + def drag_zoom(self, event): + 'the drag callback in zoom mode' + + if self._xypress: + x, y = event.x, event.y + lastx, lasty, a, ind, lim, trans = self._xypress[0] + + # adjust x, last, y, last + x1, y1, x2, y2 = a.bbox.extents + x, lastx = max(min(x, lastx), x1), min(max(x, lastx), x2) + y, lasty = max(min(y, lasty), y1), min(max(y, lasty), y2) + + if self._zoom_mode == "x": + x1, y1, x2, y2 = a.bbox.extents + y, lasty = y1, y2 + elif self._zoom_mode == "y": + x1, y1, x2, y2 = a.bbox.extents + x, lastx = x1, x2 + + self.draw_rubberband(event, x, y, lastx, lasty) + + + def release_zoom(self, event): 'the release mouse button callback in zoom to rect mode' if not self._xypress: return @@ -2313,7 +2326,6 @@ for cur_xypress in self._xypress: x, y = event.x, event.y lastx, lasty, a, ind, lim, trans = cur_xypress - # 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...> - 2010-03-24 04:45:26
|
Revision: 8213 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8213&view=rev Author: leejjoon Date: 2010-03-24 04:45:19 +0000 (Wed, 24 Mar 2010) Log Message: ----------- refactor colorbar code so that no cla() is necessary when mappable is changed Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/colorbar.py trunk/matplotlib/lib/matplotlib/figure.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2010-03-23 17:37:51 UTC (rev 8212) +++ trunk/matplotlib/CHANGELOG 2010-03-24 04:45:19 UTC (rev 8213) @@ -1,3 +1,6 @@ +2010-03-24 refactor colorbar code so that no cla() is necessary when + mappable is changed. -JJL + 2010-03-22 fix incorrect rubber band during the zoom mode when mouse leaves the axes. -JJL Modified: trunk/matplotlib/lib/matplotlib/colorbar.py =================================================================== --- trunk/matplotlib/lib/matplotlib/colorbar.py 2010-03-23 17:37:51 UTC (rev 8212) +++ trunk/matplotlib/lib/matplotlib/colorbar.py 2010-03-24 04:45:19 UTC (rev 8213) @@ -223,6 +223,8 @@ self.filled = filled self.solids = None self.lines = None + self.outline = None + self.patch = None self.dividers = None self.set_label('') if cbook.iterable(ticks): @@ -239,6 +241,7 @@ else: self.formatter = format # Assume it is a Formatter # The rest is in a method so we can recalculate when clim changes. + self.config_axis() self.draw_all() def _patch_ax(self): @@ -260,6 +263,17 @@ self._config_axes(X, Y) if self.filled: self._add_solids(X, Y, C) + + def config_axis(self): + ax = self.ax + if self.orientation == 'vertical': + ax.xaxis.set_ticks([]) + ax.yaxis.set_label_position('right') + ax.yaxis.set_ticks_position('right') + else: + ax.yaxis.set_ticks([]) + ax.xaxis.set_label_position('bottom') + self._set_label() def update_ticks(self): @@ -270,16 +284,11 @@ ax = self.ax ticks, ticklabels, offset_string = self._ticker() if self.orientation == 'vertical': - ax.xaxis.set_ticks([]) - ax.yaxis.set_label_position('right') - ax.yaxis.set_ticks_position('right') ax.yaxis.set_ticks(ticks) ax.set_yticklabels(ticklabels) ax.yaxis.get_major_formatter().set_offset_string(offset_string) else: - ax.yaxis.set_ticks([]) - ax.xaxis.set_label_position('bottom') ax.xaxis.set_ticks(ticks) ax.set_xticklabels(ticklabels) ax.xaxis.get_major_formatter().set_offset_string(offset_string) @@ -317,12 +326,16 @@ ax.update_datalim(xy) ax.set_xlim(*ax.dataLim.intervalx) ax.set_ylim(*ax.dataLim.intervaly) + if self.outline is not None: + self.outline.remove() self.outline = lines.Line2D(xy[:, 0], xy[:, 1], color=mpl.rcParams['axes.edgecolor'], linewidth=mpl.rcParams['axes.linewidth']) ax.add_artist(self.outline) self.outline.set_clip_box(None) self.outline.set_clip_path(None) c = mpl.rcParams['axes.facecolor'] + if self.patch is not None: + self.patch.remove() self.patch = patches.Polygon(xy, edgecolor=c, facecolor=c, linewidth=0.01, @@ -394,6 +407,9 @@ col = self.ax.pcolor(*args, **kw) self.ax.hold(_hold) #self.add_observer(col) # We should observe, not be observed... + + if self.solids is not None: + self.solids.remove() self.solids = col if self.drawedges: self.dividers = collections.LineCollection(self._edges(X,Y), @@ -417,6 +433,9 @@ else: xy = [zip(Y[i], X[i]) for i in range(N)] col = collections.LineCollection(xy, linewidths=linewidths) + + if self.lines: + self.lines.remove() self.lines = col col.set_color(colors) self.ax.add_collection(col) @@ -713,6 +732,19 @@ #print 'tlinewidths:', tlinewidths ColorbarBase.add_lines(self, CS.levels, tcolors, tlinewidths) + def update_normal(self, mappable): + ''' + update solid, lines, etc. Unlike update_bruteforce, it does + not clear the axes. This is meant to be called when the image + or contour plot to which this colorbar belongs is changed. + ''' + self.draw_all() + if isinstance(self.mappable, contour.ContourSet): + CS = self.mappable + if not CS.filled: + self.add_lines(CS) + + def update_bruteforce(self, mappable): ''' Manually change any contour line colors. This is called @@ -724,6 +756,7 @@ # properties have been changed by methods other than the # colorbar methods, those changes will be lost. self.ax.cla() + self.config_axis() self.draw_all() #if self.vmin != self.norm.vmin or self.vmax != self.norm.vmax: # self.ax.cla() Modified: trunk/matplotlib/lib/matplotlib/figure.py =================================================================== --- trunk/matplotlib/lib/matplotlib/figure.py 2010-03-23 17:37:51 UTC (rev 8212) +++ trunk/matplotlib/lib/matplotlib/figure.py 2010-03-24 04:45:19 UTC (rev 8213) @@ -1106,7 +1106,7 @@ #print 'calling on changed', m.get_cmap().name cb.set_cmap(m.get_cmap()) cb.set_clim(m.get_clim()) - cb.update_bruteforce(m) + cb.update_normal(m) self.cbid = mappable.callbacksSM.connect('changed', on_changed) mappable.set_colorbar(cb, cax) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ef...@us...> - 2010-04-03 23:22:55
|
Revision: 8220 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8220&view=rev Author: efiring Date: 2010-04-03 23:22:48 +0000 (Sat, 03 Apr 2010) Log Message: ----------- Update docs, examples, for new color kwarg in hist. Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/doc/api/api_changes.rst trunk/matplotlib/examples/pylab_examples/histogram_demo_extended.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2010-04-03 07:18:18 UTC (rev 8219) +++ trunk/matplotlib/CHANGELOG 2010-04-03 23:22:48 UTC (rev 8220) @@ -1,7 +1,10 @@ -2010-03-24 refactor colorbar code so that no cla() is necessary when +2010-04-03 Added color kwarg to Axes.hist(), based on work by + Jeff Klukas. - EF + +2010-03-24 refactor colorbar code so that no cla() is necessary when mappable is changed. -JJL -2010-03-22 fix incorrect rubber band during the zoom mode when mouse +2010-03-22 fix incorrect rubber band during the zoom mode when mouse leaves the axes. -JJL 2010-03-21 x/y key during the zoom mode only changes the x/y limits. -JJL Modified: trunk/matplotlib/doc/api/api_changes.rst =================================================================== --- trunk/matplotlib/doc/api/api_changes.rst 2010-04-03 07:18:18 UTC (rev 8219) +++ trunk/matplotlib/doc/api/api_changes.rst 2010-04-03 23:22:48 UTC (rev 8220) @@ -10,6 +10,9 @@ Changes beyond 0.99.x ===================== +* The :meth:`matplotlib.axes.Axes.hist` *color* kwarg now accepts + a sequence of color specs to match a sequence of datasets. + * The :class:'~matplotlib.collections.EllipseCollection' has been changed in two ways: @@ -19,7 +22,7 @@ + The *height* and *width* kwargs have been changed to specify the height and width, again for consistency with - :class:'~matplotlib.patches.Ellipse`, and to better match + :class:`~matplotlib.patches.Ellipse`, and to better match their names; previously they specified the half-height and half-width. Modified: trunk/matplotlib/examples/pylab_examples/histogram_demo_extended.py =================================================================== --- trunk/matplotlib/examples/pylab_examples/histogram_demo_extended.py 2010-04-03 07:18:18 UTC (rev 8219) +++ trunk/matplotlib/examples/pylab_examples/histogram_demo_extended.py 2010-04-03 23:22:48 UTC (rev 8220) @@ -63,13 +63,18 @@ # # histogram has the ability to plot multiple data in parallel ... +# Note the new color kwarg, used to override the default, which +# uses the line color cycle. # P.figure() # create a new data-set x = mu + sigma*P.randn(1000,3) -n, bins, patches = P.hist(x, 10, normed=1, histtype='bar') +n, bins, patches = P.hist(x, 10, normed=1, histtype='bar', + color=['crimson', 'burlywood', 'chartreuse'], + label=['Crimson', 'Burlywood', 'Chartreuse']) +P.legend() # # ... or we can stack the data This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ef...@us...> - 2010-04-05 18:46:24
|
Revision: 8222 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8222&view=rev Author: efiring Date: 2010-04-05 18:46:18 +0000 (Mon, 05 Apr 2010) Log Message: ----------- Don't import pytz unless and until it is needed Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/examples/pylab_examples/finance_demo.py trunk/matplotlib/lib/matplotlib/config/cutils.py trunk/matplotlib/lib/matplotlib/dates.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2010-04-05 01:06:57 UTC (rev 8221) +++ trunk/matplotlib/CHANGELOG 2010-04-05 18:46:18 UTC (rev 8222) @@ -1,3 +1,6 @@ +2010-04-05 Speed up import: import pytz only if and when it is + needed. It is not needed if the rc timezone is UTC. - EF + 2010-04-03 Added color kwarg to Axes.hist(), based on work by Jeff Klukas. - EF Modified: trunk/matplotlib/examples/pylab_examples/finance_demo.py =================================================================== --- trunk/matplotlib/examples/pylab_examples/finance_demo.py 2010-04-05 01:06:57 UTC (rev 8221) +++ trunk/matplotlib/examples/pylab_examples/finance_demo.py 2010-04-05 18:46:18 UTC (rev 8222) @@ -1,7 +1,7 @@ #!/usr/bin/env python from pylab import * from matplotlib.dates import DateFormatter, WeekdayLocator, HourLocator, \ - DayLocator, MONDAY, timezone + DayLocator, MONDAY from matplotlib.finance import quotes_historical_yahoo, candlestick,\ plot_day_summary, candlestick2 Modified: trunk/matplotlib/lib/matplotlib/config/cutils.py =================================================================== --- trunk/matplotlib/lib/matplotlib/config/cutils.py 2010-04-05 01:06:57 UTC (rev 8221) +++ trunk/matplotlib/lib/matplotlib/config/cutils.py 2010-04-05 18:46:18 UTC (rev 8222) @@ -4,7 +4,6 @@ # Stdlib imports import os -import pytz import sys import tempfile import warnings Modified: trunk/matplotlib/lib/matplotlib/dates.py =================================================================== --- trunk/matplotlib/lib/matplotlib/dates.py 2010-04-05 01:06:57 UTC (rev 8221) +++ trunk/matplotlib/lib/matplotlib/dates.py 2010-04-05 18:46:18 UTC (rev 8222) @@ -92,15 +92,6 @@ """ import re, time, math, datetime -import pytz - -# compatability for 2008c and older versions -try: - import pytz.zoneinfo -except ImportError: - pytz.zoneinfo = pytz.tzinfo - pytz.zoneinfo.UTC = pytz.UTC - import matplotlib import numpy as np @@ -108,7 +99,6 @@ import matplotlib.cbook as cbook import matplotlib.ticker as ticker -from pytz import timezone from dateutil.rrule import rrule, MO, TU, WE, TH, FR, SA, SU, YEARLY, \ MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, SECONDLY from dateutil.relativedelta import relativedelta @@ -127,11 +117,28 @@ 'seconds', 'minutes', 'hours', 'weeks') +# Make a simple UTC instance so we don't always have to import +# pytz. From the python datetime library docs: -UTC = pytz.timezone('UTC') +class _UTC(datetime.tzinfo): + """UTC""" + def utcoffset(self, dt): + return datetime.timedelta(0) + + def tzname(self, dt): + return "UTC" + + def dst(self, dt): + return datetime.timedelta(0) + +UTC = _UTC() + def _get_rc_timezone(): s = matplotlib.rcParams['timezone'] + if s == 'UTC': + return UTC + import pytz return pytz.timezone(s) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <lee...@us...> - 2010-04-06 17:05:58
|
Revision: 8223 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8223&view=rev Author: leejjoon Date: 2010-04-06 17:05:51 +0000 (Tue, 06 Apr 2010) Log Message: ----------- axes_grid toolkit is splitted into two separate modules, axes_grid1 and axisartist. Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/setup.py Added Paths: ----------- trunk/matplotlib/lib/mpl_toolkits/axes_grid1/ trunk/matplotlib/lib/mpl_toolkits/axes_grid1/__init__.py trunk/matplotlib/lib/mpl_toolkits/axes_grid1/anchored_artists.py trunk/matplotlib/lib/mpl_toolkits/axes_grid1/axes_divider.py trunk/matplotlib/lib/mpl_toolkits/axes_grid1/axes_grid.py trunk/matplotlib/lib/mpl_toolkits/axes_grid1/axes_rgb.py trunk/matplotlib/lib/mpl_toolkits/axes_grid1/axes_size.py trunk/matplotlib/lib/mpl_toolkits/axes_grid1/colorbar.py trunk/matplotlib/lib/mpl_toolkits/axes_grid1/inset_locator.py trunk/matplotlib/lib/mpl_toolkits/axes_grid1/mpl_axes.py trunk/matplotlib/lib/mpl_toolkits/axes_grid1/parasite_axes.py trunk/matplotlib/lib/mpl_toolkits/axisartist/ trunk/matplotlib/lib/mpl_toolkits/axisartist/__init__.py trunk/matplotlib/lib/mpl_toolkits/axisartist/angle_helper.py trunk/matplotlib/lib/mpl_toolkits/axisartist/axis_artist.py trunk/matplotlib/lib/mpl_toolkits/axisartist/axisline_style.py trunk/matplotlib/lib/mpl_toolkits/axisartist/axislines.py trunk/matplotlib/lib/mpl_toolkits/axisartist/clip_path.py trunk/matplotlib/lib/mpl_toolkits/axisartist/floating_axes.py trunk/matplotlib/lib/mpl_toolkits/axisartist/grid_finder.py trunk/matplotlib/lib/mpl_toolkits/axisartist/grid_helper_curvelinear.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2010-04-05 18:46:18 UTC (rev 8222) +++ trunk/matplotlib/CHANGELOG 2010-04-06 17:05:51 UTC (rev 8223) @@ -1,3 +1,6 @@ +2010-04-06 axes_grid toolkit is splitted into two separate modules, + axes_grid1 and axisartist. -JJL + 2010-04-05 Speed up import: import pytz only if and when it is needed. It is not needed if the rc timezone is UTC. - EF Added: trunk/matplotlib/lib/mpl_toolkits/axes_grid1/__init__.py =================================================================== --- trunk/matplotlib/lib/mpl_toolkits/axes_grid1/__init__.py (rev 0) +++ trunk/matplotlib/lib/mpl_toolkits/axes_grid1/__init__.py 2010-04-06 17:05:51 UTC (rev 8223) @@ -0,0 +1,5 @@ +import axes_size as Size +from axes_divider import Divider, SubplotDivider, LocatableAxes, \ + make_axes_locatable +from axes_grid import Grid, ImageGrid, AxesGrid +#from axes_divider import make_axes_locatable Added: trunk/matplotlib/lib/mpl_toolkits/axes_grid1/anchored_artists.py =================================================================== --- trunk/matplotlib/lib/mpl_toolkits/axes_grid1/anchored_artists.py (rev 0) +++ trunk/matplotlib/lib/mpl_toolkits/axes_grid1/anchored_artists.py 2010-04-06 17:05:51 UTC (rev 8223) @@ -0,0 +1,160 @@ + +from matplotlib.patches import Rectangle, Ellipse + +import numpy as np + +from matplotlib.offsetbox import AnchoredOffsetbox, AuxTransformBox, VPacker,\ + TextArea, AnchoredText, DrawingArea, AnnotationBbox + + +class AnchoredDrawingArea(AnchoredOffsetbox): + """ + AnchoredOffsetbox with DrawingArea + """ + + def __init__(self, width, height, xdescent, ydescent, + loc, pad=0.4, borderpad=0.5, prop=None, frameon=True, + **kwargs): + """ + *width*, *height*, *xdescent*, *ydescent* : the dimensions of the DrawingArea. + *prop* : font property. this is only used for scaling the paddings. + """ + + self.da = DrawingArea(width, height, xdescent, ydescent, clip=True) + self.drawing_area = self.da + + super(AnchoredDrawingArea, self).__init__(loc, pad=pad, borderpad=borderpad, + child=self.da, + prop=None, + frameon=frameon, + **kwargs) + + +class AnchoredAuxTransformBox(AnchoredOffsetbox): + def __init__(self, transform, loc, + pad=0.4, borderpad=0.5, prop=None, frameon=True, **kwargs): + + self.drawing_area = AuxTransformBox(transform) + + AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, + child=self.drawing_area, + prop=prop, + frameon=frameon, + **kwargs) + + + +class AnchoredEllipse(AnchoredOffsetbox): + def __init__(self, transform, width, height, angle, loc, + pad=0.1, borderpad=0.1, prop=None, frameon=True, **kwargs): + """ + Draw an ellipse the size in data coordinate of the give axes. + + pad, borderpad in fraction of the legend font size (or prop) + """ + self._box = AuxTransformBox(transform) + self.ellipse = Ellipse((0,0), width, height, angle) + self._box.add_artist(self.ellipse) + + AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, + child=self._box, + prop=prop, + frameon=frameon, **kwargs) + + + +class AnchoredSizeBar(AnchoredOffsetbox): + def __init__(self, transform, size, label, loc, + pad=0.1, borderpad=0.1, sep=2, prop=None, frameon=True, + **kwargs): + """ + Draw a horizontal bar with the size in data coordinate of the give axes. + A label will be drawn underneath (center-alinged). + + pad, borderpad in fraction of the legend font size (or prop) + sep in points. + """ + self.size_bar = AuxTransformBox(transform) + self.size_bar.add_artist(Rectangle((0,0), size, 0, fc="none")) + + self.txt_label = TextArea(label, minimumdescent=False) + + self._box = VPacker(children=[self.size_bar, self.txt_label], + align="center", + pad=0, sep=sep) + + AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, + child=self._box, + prop=prop, + frameon=frameon, **kwargs) + + +if __name__ == "__main__": + + import matplotlib.pyplot as plt + + fig = plt.gcf() + fig.clf() + ax = plt.subplot(111) + + offsetbox = AnchoredText("Test", loc=6, pad=0.3, + borderpad=0.3, prop=None) + xy = (0.5, 0.5) + ax.plot([0.5], [0.5], "xk") + ab = AnnotationBbox(offsetbox, xy, + xybox=(1., .5), + xycoords='data', + boxcoords=("axes fraction", "data"), + arrowprops=dict(arrowstyle="->")) + #arrowprops=None) + + ax.add_artist(ab) + + + from matplotlib.patches import Circle + ada = AnchoredDrawingArea(20, 20, 0, 0, + loc=6, pad=0.1, borderpad=0.3, frameon=True) + p = Circle((10, 10), 10) + ada.da.add_artist(p) + + ab = AnnotationBbox(ada, (0.3, 0.4), + xybox=(1., 0.4), + xycoords='data', + boxcoords=("axes fraction", "data"), + arrowprops=dict(arrowstyle="->")) + #arrowprops=None) + + ax.add_artist(ab) + + + arr = np.arange(100).reshape((10,10)) + im = AnchoredImage(arr, + loc=4, + pad=0.5, borderpad=0.2, prop=None, frameon=True, + zoom=1, + cmap = None, + norm = None, + interpolation=None, + origin=None, + extent=None, + filternorm=1, + filterrad=4.0, + resample = False, + ) + + ab = AnnotationBbox(im, (0.5, 0.5), + xybox=(-10., 10.), + xycoords='data', + boxcoords="offset points", + arrowprops=dict(arrowstyle="->")) + #arrowprops=None) + + ax.add_artist(ab) + + ax.set_xlim(0, 1) + ax.set_ylim(0, 1) + + + plt.draw() + plt.show() + Added: trunk/matplotlib/lib/mpl_toolkits/axes_grid1/axes_divider.py =================================================================== --- trunk/matplotlib/lib/mpl_toolkits/axes_grid1/axes_divider.py (rev 0) +++ trunk/matplotlib/lib/mpl_toolkits/axes_grid1/axes_divider.py 2010-04-06 17:05:51 UTC (rev 8223) @@ -0,0 +1,753 @@ +""" +The axes_divider module provide helper classes to adjust the positions of +multiple axes at the drawing time. + + Divider: this is the class that is used calculates the axes + position. It divides the given renctangular area into several sub + rectangles. You intialize the divider by setting the horizontal + and vertical list of sizes that the division will be based on. You + then use the new_locator method, whose return value is a callable + object that can be used to set the axes_locator of the axes. + +""" + +import matplotlib.transforms as mtransforms + +from matplotlib.axes import SubplotBase + +import new + +import axes_size as Size + + +class Divider(object): + """ + This is the class that is used calculates the axes position. It + divides the given renctangular area into several + sub-rectangles. You intialize the divider by setting the + horizontal and vertical lists of sizes + (:mod:`mpl_toolkits.axes_grid.axes_size`) that the division will + be based on. You then use the new_locator method to create a + callable object that can be used to as the axes_locator of the + axes. + """ + + + def __init__(self, fig, pos, horizontal, vertical, aspect=None, anchor="C"): + """ + :param fig: matplotlib figure + :param pos: position (tuple of 4 floats) of the rectangle that + will be divided. + :param horizontal: list of sizes + (:mod:`~mpl_toolkits.axes_grid.axes_size`) + for horizontal division + :param vertical: list of sizes + (:mod:`~mpl_toolkits.axes_grid.axes_size`) + for vertical division + :param aspect: if True, the overall rectalngular area is reduced + so that the relative part of the horizontal and + vertical scales have same scale. + :param anchor: Detrmine how the reduced rectangle is placed + when aspect is True, + """ + + self._fig = fig + self._pos = pos + self._horizontal = horizontal + self._vertical = vertical + self._anchor = anchor + self._aspect = aspect + self._xrefindex = 0 + self._yrefindex = 0 + + + @staticmethod + def _calc_k(l, total_size, renderer): + + rs_sum, as_sum = 0., 0. + + for s in l: + _rs, _as = s.get_size(renderer) + rs_sum += _rs + as_sum += _as + + if rs_sum != 0.: + k = (total_size - as_sum) / rs_sum + return k + else: + return 0. + + + @staticmethod + def _calc_offsets(l, k, renderer): + + offsets = [0.] + + for s in l: + _rs, _as = s.get_size(renderer) + offsets.append(offsets[-1] + _rs*k + _as) + + return offsets + + + def set_position(self, pos): + """ + set the position of the rectangle. + + :param pos: position (tuple of 4 floats) of the rectangle that + will be divided. + """ + self._pos = pos + + def get_position(self): + "return the position of the rectangle." + return self._pos + + def set_anchor(self, anchor): + """ + :param anchor: anchor position + + ===== ============ + value description + ===== ============ + 'C' Center + 'SW' bottom left + 'S' bottom + 'SE' bottom right + 'E' right + 'NE' top right + 'N' top + 'NW' top left + 'W' left + ===== ============ + + """ + if anchor in mtransforms.Bbox.coefs.keys() or len(anchor) == 2: + self._anchor = anchor + else: + raise ValueError('argument must be among %s' % + ', '.join(mtransforms.BBox.coefs.keys())) + + def get_anchor(self): + "return the anchor" + return self._anchor + + def set_horizontal(self, h): + """ + :param horizontal: list of sizes + (:mod:`~mpl_toolkits.axes_grid.axes_size`) + for horizontal division + """ + self._horizontal = h + + + def get_horizontal(self): + "return horizontal sizes" + return self._horizontal + + def set_vertical(self, v): + """ + :param horizontal: list of sizes + (:mod:`~mpl_toolkits.axes_grid.axes_size`) + for horizontal division + """ + self._vertical = v + + def get_vertical(self): + "return vertical sizes" + return self._vertical + + + def set_aspect(self, aspect=False): + """ + :param anchor: True or False + """ + self._aspect = aspect + + def get_aspect(self): + "return aspect" + return self._aspect + + + def locate(self, nx, ny, nx1=None, ny1=None, renderer=None): + """ + + :param nx, nx1: Integers specifying the column-position of the + cell. When nx1 is None, a single nx-th column is + specified. Otherwise location of columns spanning between nx + to nx1 (but excluding nx1-th column) is specified. + + :param ny, ny1: same as nx and nx1, but for row positions. + """ + + + figW,figH = self._fig.get_size_inches() + x, y, w, h = self.get_position() + + k_h = self._calc_k(self._horizontal, figW*w, renderer) + k_v = self._calc_k(self._vertical, figH*h, renderer) + + if self.get_aspect(): + k = min(k_h, k_v) + ox = self._calc_offsets(self._horizontal, k, renderer) + oy = self._calc_offsets(self._vertical, k, renderer) + + ww = (ox[-1] - ox[0])/figW + hh = (oy[-1] - oy[0])/figH + pb = mtransforms.Bbox.from_bounds(x, y, w, h) + pb1 = mtransforms.Bbox.from_bounds(x, y, ww, hh) + pb1_anchored = pb1.anchored(self.get_anchor(), pb) + x0, y0 = pb1_anchored.x0, pb1_anchored.y0 + + else: + ox = self._calc_offsets(self._horizontal, k_h, renderer) + oy = self._calc_offsets(self._vertical, k_v, renderer) + x0, y0 = x, y + + + if nx1 is None: + nx1=nx+1 + if ny1 is None: + ny1=ny+1 + + x1, w1 = x0 + ox[nx]/figW, (ox[nx1] - ox[nx])/figW + y1, h1 = y0 + oy[ny]/figH, (oy[ny1] - oy[ny])/figH + + return mtransforms.Bbox.from_bounds(x1, y1, w1, h1) + + + def new_locator(self, nx, ny, nx1=None, ny1=None): + """ + returns a new locator + (:class:`mpl_toolkits.axes_grid.axes_divider.AxesLocator`) for + specified cell. + + :param nx, nx1: Integers specifying the column-position of the + cell. When nx1 is None, a single nx-th column is + specified. Otherwise location of columns spanning between nx + to nx1 (but excluding nx1-th column) is specified. + + :param ny, ny1: same as nx and nx1, but for row positions. + """ + return AxesLocator(self, nx, ny, nx1, ny1) + + + +class AxesLocator(object): + """ + A simple callable object, initiallized with AxesDivider class, + returns the position and size of the given cell. + """ + def __init__(self, axes_divider, nx, ny, nx1=None, ny1=None): + """ + :param axes_divider: An instance of AxesDivider class. + + :param nx, nx1: Integers specifying the column-position of the + cell. When nx1 is None, a single nx-th column is + specified. Otherwise location of columns spanning between nx + to nx1 (but excluding nx1-th column) is is specified. + + :param ny, ny1: same as nx and nx1, but for row positions. + """ + self._axes_divider = axes_divider + + _xrefindex = axes_divider._xrefindex + _yrefindex = axes_divider._yrefindex + + self._nx, self._ny = nx - _xrefindex, ny - _yrefindex + + if nx1 is None: + nx1 = nx+1 + if ny1 is None: + ny1 = ny+1 + + self._nx1 = nx1 - _xrefindex + self._ny1 = ny1 - _yrefindex + + + def __call__(self, axes, renderer): + + _xrefindex = self._axes_divider._xrefindex + _yrefindex = self._axes_divider._yrefindex + + return self._axes_divider.locate(self._nx + _xrefindex, + self._ny + _yrefindex, + self._nx1 + _xrefindex, + self._ny1 + _yrefindex, + renderer) + + + +class SubplotDivider(Divider): + """ + The Divider class whose rectangle area is specified as a subplot grometry. + """ + + + def __init__(self, fig, *args, **kwargs): + """ + *fig* is a :class:`matplotlib.figure.Figure` instance. + + *args* is the tuple (*numRows*, *numCols*, *plotNum*), where + the array of subplots in the figure has dimensions *numRows*, + *numCols*, and where *plotNum* is the number of the subplot + being created. *plotNum* starts at 1 in the upper left + corner and increases to the right. + + If *numRows* <= *numCols* <= *plotNum* < 10, *args* can be the + decimal integer *numRows* * 100 + *numCols* * 10 + *plotNum*. + """ + + self.figure = fig + + if len(args)==1: + s = str(args[0]) + if len(s) != 3: + raise ValueError('Argument to subplot must be a 3 digits long') + rows, cols, num = map(int, s) + elif len(args)==3: + rows, cols, num = args + else: + raise ValueError( 'Illegal argument to subplot') + + + total = rows*cols + 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 + self._cols = cols + self._num = num + + self.update_params() + + pos = self.figbox.bounds + horizontal = kwargs.pop("horizontal", []) + vertical = kwargs.pop("vertical", []) + aspect = kwargs.pop("aspect", None) + anchor = kwargs.pop("anchor", "C") + + if kwargs: + raise Exception("") + + Divider.__init__(self, fig, pos, horizontal, vertical, + aspect=aspect, anchor=anchor) + + + def get_position(self): + "return the bounds of the subplot box" + self.update_params() + return self.figbox.bounds + + + def update_params(self): + 'update the subplot position from fig.subplotpars' + + rows = self._rows + cols = self._cols + num = self._num + + pars = self.figure.subplotpars + left = pars.left + right = pars.right + bottom = pars.bottom + top = pars.top + wspace = pars.wspace + hspace = pars.hspace + totWidth = right-left + totHeight = top-bottom + + figH = totHeight/(rows + hspace*(rows-1)) + sepH = hspace*figH + + figW = totWidth/(cols + wspace*(cols-1)) + sepW = wspace*figW + + rowNum, colNum = divmod(num, cols) + + figBottom = top - (rowNum+1)*figH - rowNum*sepH + figLeft = left + colNum*(figW + sepW) + + self.figbox = mtransforms.Bbox.from_bounds(figLeft, figBottom, + figW, figH) + + +class AxesDivider(Divider): + """ + Divider based on the pre-existing axes. + """ + + def __init__(self, axes): + """ + :param axes: axes + """ + self._axes = axes + self._xref = Size.AxesX(axes) + self._yref = Size.AxesY(axes) + Divider.__init__(self, fig=axes.get_figure(), pos=None, + horizontal=[self._xref], vertical=[self._yref], + aspect=None, anchor="C") + + def _get_new_axes(self, **kwargs): + axes = self._axes + + axes_class = kwargs.pop("axes_class", None) + + if axes_class is None: + if isinstance(axes, SubplotBase): + axes_class = axes._axes_class + else: + axes_class = type(axes) + + ax = axes_class(axes.get_figure(), + axes.get_position(original=True), **kwargs) + + return ax + + + def new_horizontal(self, size, pad=None, pack_start=False, **kwargs): + """ + Add a new axes on the right (or left) side of the main axes. + + :param size: A width of the axes. A :mod:`~mpl_toolkits.axes_grid.axes_size` + instance or if float or string is given, *from_any* + fucntion is used to create one, with *ref_size* set to AxesX instance + of the current axes. + :param pad: pad between the axes. It takes same argument as *size*. + :param pack_start: If False, the new axes is appended at the end + of the list, i.e., it became the right-most axes. If True, it is + inseted at the start of the list, and becomes the left-most axes. + + All extra keywords argument is passed to when creating a axes. + if *axes_class* is given, the new axes will be created as an + instance of the given class. Otherwise, the same class of the + main axes will be used. if Not provided + + """ + + if pad: + if not isinstance(pad, Size._Base): + pad = Size.from_any(pad, + fraction_ref=self._xref) + if pack_start: + self._horizontal.insert(0, pad) + self._xrefindex += 1 + else: + self._horizontal.append(pad) + + if not isinstance(size, Size._Base): + size = Size.from_any(size, + fraction_ref=self._xref) + + if pack_start: + self._horizontal.insert(0, size) + self._xrefindex += 1 + locator = self.new_locator(nx=0, ny=0) + else: + self._horizontal.append(size) + locator = self.new_locator(nx=len(self._horizontal)-1, ny=0) + + ax = self._get_new_axes(**kwargs) + ax.set_axes_locator(locator) + + return ax + + def new_vertical(self, size, pad=None, pack_start=False, **kwargs): + """ + Add a new axes on the top (or bottom) side of the main axes. + + :param size: A height of the axes. A :mod:`~mpl_toolkits.axes_grid.axes_size` + instance or if float or string is given, *from_any* + fucntion is used to create one, with *ref_size* set to AxesX instance + of the current axes. + :param pad: pad between the axes. It takes same argument as *size*. + :param pack_start: If False, the new axes is appended at the end + of the list, i.e., it became the top-most axes. If True, it is + inseted at the start of the list, and becomes the bottom-most axes. + + All extra keywords argument is passed to when creating a axes. + if *axes_class* is given, the new axes will be created as an + instance of the given class. Otherwise, the same class of the + main axes will be used. if Not provided + + """ + + if pad: + if not isinstance(pad, Size._Base): + pad = Size.from_any(pad, + fraction_ref=self._yref) + if pack_start: + self._vertical.insert(0, pad) + self._yrefindex += 1 + else: + self._vertical.append(pad) + + if not isinstance(size, Size._Base): + size = Size.from_any(size, + fraction_ref=self._yref) + + if pack_start: + self._vertical.insert(0, size) + self._yrefindex += 1 + locator = self.new_locator(nx=0, ny=0) + else: + self._vertical.append(size) + locator = self.new_locator(nx=0, ny=len(self._vertical)-1) + + ax = self._get_new_axes(**kwargs) + ax.set_axes_locator(locator) + + return ax + + + def append_axes(self, position, size, pad=None, **kwargs): + """ + create an axes at the given *position* with the same height + (or width) of the main axes. + + *position* + ["left"|"right"|"bottom"|"top"] + + *size* and *pad* should be axes_grid.axes_size compatible. + """ + + if position == "left": + ax = self.new_horizontal(size, pad, pack_start=True, **kwargs) + elif position == "right": + ax = self.new_horizontal(size, pad, pack_start=False, **kwargs) + elif position == "bottom": + ax = self.new_vertical(size, pad, pack_start=True, **kwargs) + elif position == "top": + ax = self.new_vertical(size, pad, pack_start=False, **kwargs) + else: + raise ValueError("the position must be one of left, right, bottom, or top") + + self._fig.add_axes(ax) + return ax + + def get_aspect(self): + if self._aspect is None: + aspect = self._axes.get_aspect() + if aspect == "auto": + return False + else: + return True + else: + return self._aspect + + def get_position(self): + if self._pos is None: + bbox = self._axes.get_position(original=True) + return bbox.bounds + else: + return self._pos + + def get_anchor(self): + if self._anchor is None: + return self._axes.get_anchor() + else: + return self._anchor + + + +class LocatableAxesBase: + def __init__(self, *kl, **kw): + + self._axes_class.__init__(self, *kl, **kw) + + self._locator = None + self._locator_renderer = None + + def set_axes_locator(self, locator): + self._locator = locator + + def get_axes_locator(self): + return self._locator + + def apply_aspect(self, position=None): + + if self.get_axes_locator() is None: + self._axes_class.apply_aspect(self, position) + else: + pos = self.get_axes_locator()(self, self._locator_renderer) + self._axes_class.apply_aspect(self, position=pos) + + + def draw(self, renderer=None, inframe=False): + + self._locator_renderer = renderer + + self._axes_class.draw(self, renderer, inframe) + + + +_locatableaxes_classes = {} +def locatable_axes_factory(axes_class): + + new_class = _locatableaxes_classes.get(axes_class) + if new_class is None: + new_class = new.classobj("Locatable%s" % (axes_class.__name__), + (LocatableAxesBase, axes_class), + {'_axes_class': axes_class}) + _locatableaxes_classes[axes_class] = new_class + + return new_class + +#if hasattr(maxes.Axes, "get_axes_locator"): +# LocatableAxes = maxes.Axes +#else: + +def make_axes_locatable(axes): + if not hasattr(axes, "set_axes_locator"): + new_class = locatable_axes_factory(type(axes)) + axes.__class__ = new_class + + divider = AxesDivider(axes) + locator = divider.new_locator(nx=0, ny=0) + axes.set_axes_locator(locator) + + return divider + + +#from matplotlib.axes import Axes +from mpl_axes import Axes +LocatableAxes = locatable_axes_factory(Axes) + + + +def get_demo_image(): + # prepare image + delta = 0.5 + + extent = (-3,4,-4,3) + import numpy as np + x = np.arange(-3.0, 4.001, delta) + y = np.arange(-4.0, 3.001, delta) + X, Y = np.meshgrid(x, y) + import matplotlib.mlab as mlab + Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) + Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1) + Z = (Z1 - Z2) * 10 + + return Z, extent + +def demo_locatable_axes(): + import matplotlib.pyplot as plt + + fig1 = plt.figure(1, (6, 6)) + fig1.clf() + + ## PLOT 1 + # simple image & colorbar + ax = fig1.add_subplot(2, 2, 1) + + Z, extent = get_demo_image() + + im = ax.imshow(Z, extent=extent, interpolation="nearest") + cb = plt.colorbar(im) + plt.setp(cb.ax.get_yticklabels(), visible=False) + + + ## PLOT 2 + # image and colorbar whose location is adjusted in the drawing time. + # a hard way + + divider = SubplotDivider(fig1, 2, 2, 2, aspect=True) + + # axes for image + ax = LocatableAxes(fig1, divider.get_position()) + + # axes for coloarbar + ax_cb = LocatableAxes(fig1, divider.get_position()) + + h = [Size.AxesX(ax), # main axes + Size.Fixed(0.05), # padding, 0.1 inch + Size.Fixed(0.2), # colorbar, 0.3 inch + ] + + v = [Size.AxesY(ax)] + + divider.set_horizontal(h) + divider.set_vertical(v) + + ax.set_axes_locator(divider.new_locator(nx=0, ny=0)) + ax_cb.set_axes_locator(divider.new_locator(nx=2, ny=0)) + + fig1.add_axes(ax) + fig1.add_axes(ax_cb) + + ax_cb.yaxis.set_ticks_position("right") + + Z, extent = get_demo_image() + + im = ax.imshow(Z, extent=extent, interpolation="nearest") + plt.colorbar(im, cax=ax_cb) + plt.setp(ax_cb.get_yticklabels(), visible=False) + + plt.draw() + #plt.colorbar(im, cax=ax_cb) + + + ## PLOT 3 + # image and colorbar whose location is adjusted in the drawing time. + # a easy way + + ax = fig1.add_subplot(2, 2, 3) + divider = make_axes_locatable(ax) + + ax_cb = divider.new_horizontal(size="5%", pad=0.05) + fig1.add_axes(ax_cb) + + im = ax.imshow(Z, extent=extent, interpolation="nearest") + plt.colorbar(im, cax=ax_cb) + plt.setp(ax_cb.get_yticklabels(), visible=False) + + + ## PLOT 4 + # two images side by sied with fixed padding. + + ax = fig1.add_subplot(2, 2, 4) + divider = make_axes_locatable(ax) + + ax2 = divider.new_horizontal(size="100%", pad=0.05) + fig1.add_axes(ax2) + + ax.imshow(Z, extent=extent, interpolation="nearest") + ax2.imshow(Z, extent=extent, interpolation="nearest") + plt.setp(ax2.get_yticklabels(), visible=False) + plt.draw() + plt.show() + + +def demo_fixed_size_axes(): + import matplotlib.pyplot as plt + + fig2 = plt.figure(2, (6, 6)) + + # The first items are for padding and the second items are for the axes. + # sizes are in inch. + h = [Size.Fixed(1.0), Size.Fixed(4.5)] + v = [Size.Fixed(0.7), Size.Fixed(5.)] + + divider = Divider(fig2, (0.0, 0.0, 1., 1.), h, v, aspect=False) + # the width and height of the rectangle is ignored. + + ax = LocatableAxes(fig2, divider.get_position()) + ax.set_axes_locator(divider.new_locator(nx=1, ny=1)) + + fig2.add_axes(ax) + + ax.plot([1,2,3]) + + plt.draw() + plt.show() + #plt.colorbar(im, cax=ax_cb) + + + + + +if __name__ == "__main__": + demo_locatable_axes() + demo_fixed_size_axes() Added: trunk/matplotlib/lib/mpl_toolkits/axes_grid1/axes_grid.py =================================================================== --- trunk/matplotlib/lib/mpl_toolkits/axes_grid1/axes_grid.py (rev 0) +++ trunk/matplotlib/lib/mpl_toolkits/axes_grid1/axes_grid.py 2010-04-06 17:05:51 UTC (rev 8223) @@ -0,0 +1,786 @@ +import matplotlib.cbook as cbook + +import matplotlib.pyplot as plt +import matplotlib.axes as maxes +#import matplotlib.colorbar as mcolorbar +import colorbar as mcolorbar +import matplotlib as mpl +import matplotlib.patches as mpatches +import matplotlib.lines as mlines +import matplotlib.ticker as ticker + +from axes_divider import Size, SubplotDivider, LocatableAxes, Divider + +#import numpy as np + +def _tick_only(ax, bottom_on, left_on): + bottom_off = not bottom_on + left_off = not left_on + # [l.set_visible(bottom_off) for l in ax.get_xticklabels()] + # [l.set_visible(left_off) for l in ax.get_yticklabels()] + # ax.xaxis.label.set_visible(bottom_off) + # ax.yaxis.label.set_visible(left_off) + ax.axis["bottom"].toggle(ticklabels=bottom_off, label=bottom_off) + ax.axis["left"].toggle(ticklabels=left_off, label=left_off) + +class Colorbar(mcolorbar.Colorbar): + def _config_axes_deprecated(self, X, Y): + ''' + Make an axes patch and outline. + ''' + ax = self.ax + ax.set_frame_on(False) + ax.set_navigate(False) + xy = self._outline(X, Y) + ax.update_datalim(xy) + ax.set_xlim(*ax.dataLim.intervalx) + ax.set_ylim(*ax.dataLim.intervaly) + self.outline = mlines.Line2D(xy[:, 0], xy[:, 1], color=mpl.rcParams['axes.edgecolor'], + linewidth=mpl.rcParams['axes.linewidth']) + ax.add_artist(self.outline) + self.outline.set_clip_box(None) + self.outline.set_clip_path(None) + c = mpl.rcParams['axes.facecolor'] + self.patch = mpatches.Polygon(xy, edgecolor=c, + facecolor=c, + linewidth=0.01, + zorder=-1) + ax.add_artist(self.patch) + ticks, ticklabels, offset_string = self._ticker() + + if self.orientation == 'vertical': + ax.set_yticks(ticks) + ax.set_yticklabels(ticklabels) + ax.yaxis.get_major_formatter().set_offset_string(offset_string) + + else: + ax.set_xticks(ticks) + ax.set_xticklabels(ticklabels) + ax.xaxis.get_major_formatter().set_offset_string(offset_string) + + + +class CbarAxesBase(object): + + def colorbar(self, mappable, **kwargs): + locator=kwargs.pop("locator", None) + if locator is None: + locator = ticker.MaxNLocator(5) + self.locator = locator + + kwargs["ticks"] = locator + + + self.hold(True) + if self.orientation in ["top", "bottom"]: + orientation="horizontal" + else: + orientation="vertical" + + cb = Colorbar(self, mappable, orientation=orientation, **kwargs) + self._config_axes() + + def on_changed(m): + #print 'calling on changed', m.get_cmap().name + cb.set_cmap(m.get_cmap()) + cb.set_clim(m.get_clim()) + cb.update_bruteforce(m) + + self.cbid = mappable.callbacksSM.connect('changed', on_changed) + mappable.set_colorbar(cb, self) + return cb + + def _config_axes(self): + ''' + Make an axes patch and outline. + ''' + ax = self + ax.set_navigate(False) + + ax.axis[:].toggle(all=False) + b = self._default_label_on + ax.axis[self.orientation].toggle(all=b) + + # for axis in ax.axis.values(): + # axis.major_ticks.set_visible(False) + # axis.minor_ticks.set_visible(False) + # axis.major_ticklabels.set_visible(False) + # axis.minor_ticklabels.set_visible(False) + # axis.label.set_visible(False) + + # axis = ax.axis[self.orientation] + # axis.major_ticks.set_visible(True) + # axis.minor_ticks.set_visible(True) + + + #axis.major_ticklabels.set_size(int(axis.major_ticklabels.get_size()*.9)) + #axis.major_tick_pad = 3 + + # axis.major_ticklabels.set_visible(b) + # axis.minor_ticklabels.set_visible(b) + # axis.label.set_visible(b) + + + def toggle_label(self, b): + self._default_label_on = b + axis = self.axis[self.orientation] + axis.toggle(ticklabels=b, label=b) + #axis.major_ticklabels.set_visible(b) + #axis.minor_ticklabels.set_visible(b) + #axis.label.set_visible(b) + + + +class CbarAxes(CbarAxesBase, LocatableAxes): + def __init__(self, *kl, **kwargs): + orientation=kwargs.pop("orientation", None) + if orientation is None: + raise ValueError("orientation must be specified") + self.orientation = orientation + self._default_label_on = True + self.locator = None + + super(LocatableAxes, self).__init__(*kl, **kwargs) + + def cla(self): + super(LocatableAxes, self).cla() + self._config_axes() + + +class Grid(object): + """ + A class that creates a grid of Axes. In matplotlib, the axes + location (and size) is specified in the normalized figure + coordinates. This may not be ideal for images that needs to be + displayed with a given aspect ratio. For example, displaying + images of a same size with some fixed padding between them cannot + be easily done in matplotlib. AxesGrid is used in such case. + """ + + _defaultLocatableAxesClass = LocatableAxes + + def __init__(self, fig, + rect, + nrows_ncols, + ngrids = None, + direction="row", + axes_pad = 0.02, + add_all=True, + share_all=False, + share_x=True, + share_y=True, + #aspect=True, + label_mode="L", + axes_class=None, + ): + """ + Build an :class:`Grid` instance with a grid nrows*ncols + :class:`~matplotlib.axes.Axes` in + :class:`~matplotlib.figure.Figure` *fig* with + *rect=[left, bottom, width, height]* (in + :class:`~matplotlib.figure.Figure` coordinates) or + the subplot position code (e.g., "121"). + + Optional keyword arguments: + + ================ ======== ========================================= + Keyword Default Description + ================ ======== ========================================= + direction "row" [ "row" | "column" ] + axes_pad 0.02 float| pad betweein axes given in inches + add_all True [ True | False ] + share_all False [ True | False ] + share_x True [ True | False ] + share_y True [ True | False ] + label_mode "L" [ "L" | "1" | "all" ] + axes_class None a type object which must be a subclass + of :class:`~matplotlib.axes.Axes` + ================ ======== ========================================= + """ + self._nrows, self._ncols = nrows_ncols + + if ngrids is None: + ngrids = self._nrows * self._ncols + else: + if (ngrids > self._nrows * self._ncols) or (ngrids <= 0): + raise Exception("") + + self.ngrids = ngrids + + self._init_axes_pad(axes_pad) + + if direction not in ["column", "row"]: + raise Exception("") + + self._direction = direction + + + if axes_class is None: + axes_class = self._defaultLocatableAxesClass + axes_class_args = {} + else: + if isinstance(axes_class, maxes.Axes): + axes_class_args = {} + else: + axes_class, axes_class_args = axes_class + + self.axes_all = [] + self.axes_column = [[] for i in range(self._ncols)] + self.axes_row = [[] for i in range(self._nrows)] + + + h = [] + v = [] + if cbook.is_string_like(rect) or cbook.is_numlike(rect): + self._divider = SubplotDivider(fig, rect, horizontal=h, vertical=v, + aspect=False) + elif len(rect) == 3: + kw = dict(horizontal=h, vertical=v, aspect=False) + self._divider = SubplotDivider(fig, *rect, **kw) + elif len(rect) == 4: + self._divider = Divider(fig, rect, horizontal=h, vertical=v, + aspect=False) + else: + raise Exception("") + + + rect = self._divider.get_position() + + # reference axes + self._column_refax = [None for i in range(self._ncols)] + self._row_refax = [None for i in range(self._nrows)] + self._refax = None + + for i in range(self.ngrids): + + col, row = self._get_col_row(i) + + if share_all: + sharex = self._refax + sharey = self._refax + else: + if share_x: + sharex = self._column_refax[col] + else: + sharex = None + + if share_y: + sharey = self._row_refax[row] + else: + sharey = None + + ax = axes_class(fig, rect, sharex=sharex, sharey=sharey, + **axes_class_args) + + if share_all: + if self._refax is None: + self._refax = ax + else: + if sharex is None: + self._column_refax[col] = ax + if sharey is None: + self._row_refax[row] = ax + + self.axes_all.append(ax) + self.axes_column[col].append(ax) + self.axes_row[row].append(ax) + + self.axes_llc = self.axes_column[0][-1] + + self._update_locators() + + if add_all: + for ax in self.axes_all: + fig.add_axes(ax) + + self.set_label_mode(label_mode) + + + def _init_axes_pad(self, axes_pad): + self._axes_pad = axes_pad + + self._horiz_pad_size = Size.Fixed(axes_pad) + self._vert_pad_size = Size.Fixed(axes_pad) + + + def _update_locators(self): + + h = [] + + h_ax_pos = [] + h_cb_pos = [] + + for ax in self._column_refax: + #if h: h.append(Size.Fixed(self._axes_pad)) + if h: h.append(self._horiz_pad_size) + + h_ax_pos.append(len(h)) + + sz = Size.Scaled(1) + h.append(sz) + + v = [] + + v_ax_pos = [] + v_cb_pos = [] + for ax in self._row_refax[::-1]: + #if v: v.append(Size.Fixed(self._axes_pad)) + if v: v.append(self._vert_pad_size) + + v_ax_pos.append(len(v)) + sz = Size.Scaled(1) + v.append(sz) + + + for i in range(self.ngrids): + col, row = self._get_col_row(i) + locator = self._divider.new_locator(nx=h_ax_pos[col], + ny=v_ax_pos[self._nrows -1 - row]) + self.axes_all[i].set_axes_locator(locator) + + self._divider.set_horizontal(h) + self._divider.set_vertical(v) + + + + def _get_col_row(self, n): + if self._direction == "column": + col, row = divmod(n, self._nrows) + else: + row, col = divmod(n, self._ncols) + + return col, row + + + def __getitem__(self, i): + return self.axes_all[i] + + + def get_geometry(self): + """ + get geometry of the grid. Returns a tuple of two integer, + representing number of rows and number of columns. + """ + return self._nrows, self._ncols + + def set_axes_pad(self, axes_pad): + "set axes_pad" + self._axes_pad = axes_pad + + self._horiz_pad_size.fixed_size = axes_pad + self._vert_pad_size.fixed_size = axes_pad + + + def get_axes_pad(self): + "get axes_pad" + return self._axes_pad + + def set_aspect(self, aspect): + "set aspect" + self._divider.set_aspect(aspect) + + def get_aspect(self): + "get aspect" + return self._divider.get_aspect() + + def set_label_mode(self, mode): + "set label_mode" + if mode == "all": + for ax in self.axes_all: + _tick_only(ax, False, False) + elif mode == "L": + # left-most axes + for ax in self.axes_column[0][:-1]: + _tick_only(ax, bottom_on=True, left_on=False) + # lower-left axes + ax = self.axes_column[0][-1] + _tick_only(ax, bottom_on=False, left_on=False) + + for col in self.axes_column[1:]: + # axes with no labels + for ax in col[:-1]: + _tick_only(ax, bottom_on=True, left_on=True) + + # bottom + ax = col[-1] + _tick_only(ax, bottom_on=False, left_on=True) + + elif mode == "1": + for ax in self.axes_all: + _tick_only(ax, bottom_on=True, left_on=True) + + ax = self.axes_llc + _tick_only(ax, bottom_on=False, left_on=False) + + +class ImageGrid(Grid): + """ + A class that creates a grid of Axes. In matplotlib, the axes + location (and size) is specified in the normalized figure + coordinates. This may not be ideal for images that needs to be + displayed with a given aspect ratio. For example, displaying + images of a same size with some fixed padding between them cannot + be easily done in matplotlib. ImageGrid is used in such case. + """ + + _defaultCbarAxesClass = CbarAxes + + def __init__(self, fig, + rect, + nrows_ncols, + ngrids = None, + direction="row", + axes_pad = 0.02, + add_all=True, + share_all=False, + aspect=True, + label_mode="L", + cbar_mode=None, + cbar_location="right", + cbar_pad=None, + cbar_size="5%", + cbar_set_cax=True, + axes_class=None, + ): + """ + Build an :class:`ImageGrid` instance with a grid nrows*ncols + :class:`~matplotlib.axes.Axes` in + :class:`~matplotlib.figure.Figure` *fig* with + *rect=[left, bottom, width, height]* (in + :class:`~matplotlib.figure.Figure` coordinates) or + the subplot position code (e.g., "121"). + + Optional keyword arguments: + + ================ ======== ========================================= + Keyword Default Description + ================ ======== ========================================= + direction "row" [ "row" | "column" ] + axes_pad 0.02 float| pad betweein axes given in inches + add_all True [ True | False ] + share_all False [ True | False ] + aspect True [ True | False ] + label_mode "L" [ "L" | "1" | "all" ] + cbar_mode None [ "each" | "single" ] + cbar_location "right" [ "right" | "top" ] + cbar_pad None + cbar_size "5%" + cbar_set_cax True [ True | False ] + axes_class None a type object which must be a subclass + of :class:`~matplotlib.axes.Axes` + ================ ======== ========================================= + + *cbar_set_cax* : if True, each axes in the grid has a cax + attribute that is bind to associated cbar_axes. + """ + self._nrows, self._ncols = nrows_ncols + + if ngrids is None: + ngrids = self._nrows * self._ncols + else: + if (ngrids > self._nrows * self._ncols) or (ngrids <= 0): + raise Exception("") + + self.ngrids = ngrids + + self._axes_pad = axes_pad + + self._colorbar_mode = cbar_mode + self._colorbar_location = cbar_location + if cbar_pad is None: + self._colorbar_pad = axes_pad + else: + self._colorbar_pad = cbar_pad + + self._colorbar_size = cbar_size + + self._init_axes_pad(axes_pad) + + if direction not in ["column", "row"]: + raise Exception("") + + self._direction = direction + + + if axes_class is None: + axes_class = self._defaultLocatableAxesClass + axes_class_args = {} + else: + if isinstance(axes_class, maxes.Axes): + axes_class_args = {} + else: + axes_class, axes_class_args = axes_class + + + + self.axes_all = [] + self.axes_column = [[] for i in range(self._ncols)] + self.axes_row = [[] for i in range(self._nrows)] + + self.cbar_axes = [] + + h = [] + v = [] + if cbook.is_string_like(rect) or cbook.is_numlike(rect): + self._divider = SubplotDivider(fig, rect, horizontal=h, vertical=v, + aspect=aspect) + elif len(rect) == 3: + kw = dict(horizontal=h, vertical=v, aspect=aspect) + self._divider = SubplotDivider(fig, *rect, **kw) + elif len(rect) == 4: + self._divider = Divider(fig, rect, horizontal=h, vertical=v, + aspect=aspect) + else: + raise Exception("") + + + rect = self._divider.get_position() + + # reference axes + self._column_refax = [None for i in range(self._ncols)] + self._row_refax = [None for i in range(self._nrows)] + self._refax = None + + for i in range(self.ngrids): + + col, row = self._get_col_row(i) + + if share_all: + sharex = self._refax + sharey = self._refax + else: + sharex = self._column_refax[col] + sharey = self._row_refax[row] + + ax = axes_class(fig, rect, sharex=sharex, sharey=sharey, + **axes_class_args) + + if share_all: + if self._refax is None: + self._refax = ax + else: + if sharex is None: + self._column_refax[col] = ax + if sharey is None: + self._row_refax[row] = ax + + self.axes_all.append(ax) + self.axes_column[col].append(ax) + self.axes_row[row].append(ax) + + cax = self._defaultCbarAxesClass(fig, rect, + orientation=self._colorbar_location) + self.cbar_axes.append(cax) + + self.axes_llc = self.axes_column[0][-1] + + self._update_locators() + + if add_all: + for ax in self.axes_all+self.cbar_axes: + fig.add_axes(ax) + + if cbar_set_cax: + if self._colorbar_mode == "single": + for ax in self.axes_all: + ax.cax = self.cbar_axes[0] + else: + for ax, cax in zip(self.axes_all, self.cbar_axes): + ax.cax = cax + + self.set_label_mode(label_mode) + + + + def _update_locators(self): + + h = [] + + h_ax_pos = [] + h_cb_pos = [] + for ax in self._column_refax: + if h: h.append(self._horiz_pad_size) #Size.Fixed(self._axes_pad)) + + h_ax_pos.append(len(h)) + + if ax: + sz = Size.AxesX(ax) + else: + sz = Size.AxesX(self.axes_llc) + h.append(sz) + + if self._colorbar_mode == "each" and self._colorbar_location == "right": + h.append(Size.from_any(self._colorbar_pad, sz)) + h_cb_pos.append(len(h)) + h.append(Size.from_any(self._colorbar_size, sz)) + + + v = [] + + v_ax_pos = [] + v_cb_pos = [] + for ax in self._row_refax[::-1]: + if v: v.append(self._horiz_pad_size) #Size.Fixed(self._axes_pad)) + + v_ax_pos.append(len(v)) + if ax: + sz = Size.AxesY(ax) + else: + sz = Size.AxesY(self.axes_llc) + v.append(sz) + + + if self._colorbar_mode == "each" and self._colorbar_location == "top": + v.append(Size.from_any(self._colorbar_pad, sz)) + v_cb_pos.append(len(v)) + v.append(Size.from_any(self._colorbar_size, sz)) + + + for i in range(self.ngrids): + col, row = self._get_col_row(i) + #locator = self._divider.new_locator(nx=4*col, ny=2*(self._nrows - row - 1)) + locator = self._divider.new_locator(nx=h_ax_pos[col], + ny=v_ax_pos[self._nrows -1 - row]) + self.axes_all[i].set_axes_locator(locator) + + if self._colorbar_mode == "each": + if self._colorbar_location == "right": + locator = self._divider.new_locator(nx=h_cb_pos[col], + ny=v_ax_pos[self._nrows -1 - row]) + elif self._colorbar_location == "top": + locator = self._divider.new_locator(nx=h_ax_pos[col], + ny=v_cb_pos[self._nrows -1 - row]) + self.cbar_axes[i].set_axes_locator(locator) + + + if self._colorbar_mode == "single": + if self._colorbar_location == "right": + #sz = Size.Fraction(Size.AxesX(self.axes_llc), self._nrows) + sz = Size.Fraction(self._nrows, Size.AxesX(self.axes_llc)) + h.append(Size.from_any(self._colorbar_pad, sz)) + h.append(Size.from_any(self._colorbar_size, sz)) + locator = self._divider.new_locator(nx=-2, ny=0, ny1=-1) + elif self._colorbar_location == "top": + #sz = Size.Fraction(Size.AxesY(self.axes_llc), self._ncols) + sz = Size.Fraction(self._ncols, Size.AxesY(self.axes_llc)) + v.append(Size.from_any(self._colorbar_pad, sz)) + v.append(Size.from_any(self._colorbar_size, sz)) + locator = self._divider.new_locator(nx=0, nx1=-1, ny=-2) + for i in range(self.ngrids): + self.cbar_axes[i].set_visible(False) + self.cbar_axes[0].set_axes_locator(locator) + self.cbar_axes[0].set_visible(True) + elif self._colorbar_mode == "each": + for i in range(self.ngrids): + self.cbar_axes[i].set_visible(True) + else: + for i in range(self.ngrids): + self.cbar_axes[i].set_visible(False) + self.cbar_axes[i].set_position([1., 1., 0.001, 0.001], + which="active") + + self._divider.set_horizontal(h) + self._divider.set_vertical(v) + + +AxesGrid = ImageGrid + + + +#if __name__ == "__main__": +if 0: + F = plt.figure(1, (7, 6)) + F.clf() + + F.subplots_adjust(left=0.15, right=0.9) + + grid = Grid(F, 111, # similar to subplot(111) + nrows_ncols = (2, 2), + direction="row", + axes_pad = 0.05, + add_all=True, + label_mode = "1", + ) + + + +#if __name__ == "__main__": +if 0: + from axes_divider import get_demo_image + F = plt.figure(1, (9, 3.5)) + F.clf() + + F.subplots_adjust(left=0.05, right=0.98) + + grid = ImageGrid(F, 131, # similar to subplot(111) + nrows_ncols = (2, 2), + direction="row", + axes_pad = 0.05, + add_all=True, + label_mode = "1", + ) + + Z, extent = get_demo_image() + plt.ioff() + for i in range(4): + im = grid[i].imshow(Z, extent=extent, interpolation="nearest") + + # This only affects axes in first column and second row as share_all = False. + grid.axes_llc.set_xticks([-2, 0, 2]) + grid.axes_llc.set_yticks([-2, 0, 2]) + plt.ion() + + + grid = ImageGrid(F, 132, # similar to subplot(111) + nrows_ncols = (2, 2), + direction="row", + axes_pad = 0.0, + add_all=True, + share_all=True, + label_mode = "1", + cbar_mode="single", + ) + + Z, extent = get_demo_image() + plt.ioff() + for i in range(4): + im = grid[i].imshow(Z, extent=extent, interpolation="nearest") + plt.colorbar(im, cax = grid.cbar_axes[0]) + plt.setp(grid.cbar_axes[0].get_yticklabels(), visible=False) + + # This affects all axes as share_all = True. + grid.axes_llc.set_xticks([-2, 0, 2]) + grid.axes_llc.set_yticks([-2, 0, 2]) + + plt.ion() + + + + grid = ImageGrid(F, 133, # similar to subplot(122) + nrows_ncols = (2, 2), + direction="row", + axes_pad = 0.1, + add_all=True, + label_mode = "1", + share_all = True, + cbar_location="top", + cbar_mode="each", + cbar_size="7%", + cbar_pad="2%", + ) + plt.ioff() + for i in range(4): + im = grid[i].imshow(Z, extent=extent, interpolation="nearest") + plt.colorbar(im, cax = grid.cbar_axes[i], + orientation="horizontal") + grid.cbar_axes[i].xaxis.set_ticks_position("top") + plt.setp(grid.cbar_axes[i].get_xticklabels(), visible=False) + + # This affects all axes as share_all = True. + grid.axes_llc.set_xticks([-2, 0, 2]) + grid.axes_llc.set_yticks([-2, 0, 2]) + + plt.ion() + plt.draw() + + Added: trunk/matplotlib/lib/mpl_toolkits/axes_grid1/axes_rgb.py =================================================================== --- trunk/matplotlib/lib/mpl_toolkits/axes_grid1/axes_rgb.py (rev 0) +++ trunk/matplotlib/lib/mpl_toolkits/axes_grid1/axes_rgb.py 2010-04-06 17:05:51 UTC (rev 8223) @@ -0,0 +1,162 @@ +import numpy as np +from axes_divider import make_axes_locatable, Size, locatable_axes_factory + +def make_rgb_axes(ax, pad=0.01, axes_class=None, add_all=True): + """ + pad : fraction of the axes height. + """ + + divider = make_axes_locatable(ax) + + pad_size = Size.Fraction(pad, Size.AxesY(ax)) + + xsize = Size.Fraction((1.-2.*pad)/3., Size.AxesX(ax)) + ysize = Size.Fraction((1.-2.*pad)/3., Size.AxesY(ax)) + + divider.set_horizontal([Size.AxesX(ax), pad_size, xsize]) + divider.set_vertical([ysize, pad_size, ysize, pad_size, ysize]) + + ax.set_axes_locator(divider.new_locator(0, 0, ny1=-1)) + + ax_rgb = [] + if axes_class is None: + try: + axes_class = locatable_axes_factory(ax._axes_class) + except AttributeError: + axes_class = locatable_axes_factory(type(ax)) + + for ny in [4, 2, 0]: + ax1 = axes_class(ax.get_figure(), + ax.get_position(original=True), + sharex=ax, sharey=ax) + locator = divider.new_locator(nx=2, ny=ny) + ax1.set_axes_locator(locator) + for t in ax1.yaxis.get_ticklabels() + ax1.xaxis.get_ticklabels(): + t.set_visible(False) + try: + for axis in ax1.axis.values(): + axis.major_ticklabels.set_visible(False) + except AttributeError: + pass + + ax_rgb.append(ax1) + + if add_all: + fig = ax.get_figure() + for ax1 in ax_rgb: + fig.add_axes(ax1) ... [truncated message content] |
From: <lee...@us...> - 2010-04-06 17:06:59
|
Revision: 8224 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8224&view=rev Author: leejjoon Date: 2010-04-06 17:06:52 +0000 (Tue, 06 Apr 2010) Log Message: ----------- rebase axes_grid using axes_grid1 and axisartist modules Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/mpl_toolkits/axes_grid/anchored_artists.py trunk/matplotlib/lib/mpl_toolkits/axes_grid/angle_helper.py trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_divider.py trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_grid.py trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_rgb.py trunk/matplotlib/lib/mpl_toolkits/axes_grid/axis_artist.py trunk/matplotlib/lib/mpl_toolkits/axes_grid/axisline_style.py trunk/matplotlib/lib/mpl_toolkits/axes_grid/axislines.py trunk/matplotlib/lib/mpl_toolkits/axes_grid/clip_path.py trunk/matplotlib/lib/mpl_toolkits/axes_grid/floating_axes.py trunk/matplotlib/lib/mpl_toolkits/axes_grid/grid_finder.py trunk/matplotlib/lib/mpl_toolkits/axes_grid/grid_helper_curvelinear.py trunk/matplotlib/lib/mpl_toolkits/axes_grid/inset_locator.py trunk/matplotlib/lib/mpl_toolkits/axes_grid/parasite_axes.py Removed Paths: ------------- trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_size.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2010-04-06 17:05:51 UTC (rev 8223) +++ trunk/matplotlib/CHANGELOG 2010-04-06 17:06:52 UTC (rev 8224) @@ -1,3 +1,5 @@ +2010-04-06 rebase axes_grid using axes_grid1 and axisartist modules. -JJL + 2010-04-06 axes_grid toolkit is splitted into two separate modules, axes_grid1 and axisartist. -JJL Modified: trunk/matplotlib/lib/mpl_toolkits/axes_grid/anchored_artists.py =================================================================== --- trunk/matplotlib/lib/mpl_toolkits/axes_grid/anchored_artists.py 2010-04-06 17:05:51 UTC (rev 8223) +++ trunk/matplotlib/lib/mpl_toolkits/axes_grid/anchored_artists.py 2010-04-06 17:06:52 UTC (rev 8224) @@ -1,160 +1,6 @@ - -from matplotlib.patches import Rectangle, Ellipse - -import numpy as np - from matplotlib.offsetbox import AnchoredOffsetbox, AuxTransformBox, VPacker,\ TextArea, AnchoredText, DrawingArea, AnnotationBbox - -class AnchoredDrawingArea(AnchoredOffsetbox): - """ - AnchoredOffsetbox with DrawingArea - """ - - def __init__(self, width, height, xdescent, ydescent, - loc, pad=0.4, borderpad=0.5, prop=None, frameon=True, - **kwargs): - """ - *width*, *height*, *xdescent*, *ydescent* : the dimensions of the DrawingArea. - *prop* : font property. this is only used for scaling the paddings. - """ - - self.da = DrawingArea(width, height, xdescent, ydescent, clip=True) - self.drawing_area = self.da - - super(AnchoredDrawingArea, self).__init__(loc, pad=pad, borderpad=borderpad, - child=self.da, - prop=None, - frameon=frameon, - **kwargs) - - -class AnchoredAuxTransformBox(AnchoredOffsetbox): - def __init__(self, transform, loc, - pad=0.4, borderpad=0.5, prop=None, frameon=True, **kwargs): - - self.drawing_area = AuxTransformBox(transform) - - AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, - child=self.drawing_area, - prop=prop, - frameon=frameon, - **kwargs) - - - -class AnchoredEllipse(AnchoredOffsetbox): - def __init__(self, transform, width, height, angle, loc, - pad=0.1, borderpad=0.1, prop=None, frameon=True, **kwargs): - """ - Draw an ellipse the size in data coordinate of the give axes. - - pad, borderpad in fraction of the legend font size (or prop) - """ - self._box = AuxTransformBox(transform) - self.ellipse = Ellipse((0,0), width, height, angle) - self._box.add_artist(self.ellipse) - - AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, - child=self._box, - prop=prop, - frameon=frameon, **kwargs) - - - -class AnchoredSizeBar(AnchoredOffsetbox): - def __init__(self, transform, size, label, loc, - pad=0.1, borderpad=0.1, sep=2, prop=None, frameon=True, - **kwargs): - """ - Draw a horizontal bar with the size in data coordinate of the give axes. - A label will be drawn underneath (center-alinged). - - pad, borderpad in fraction of the legend font size (or prop) - sep in points. - """ - self.size_bar = AuxTransformBox(transform) - self.size_bar.add_artist(Rectangle((0,0), size, 0, fc="none")) - - self.txt_label = TextArea(label, minimumdescent=False) - - self._box = VPacker(children=[self.size_bar, self.txt_label], - align="center", - pad=0, sep=sep) - - AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, - child=self._box, - prop=prop, - frameon=frameon, **kwargs) - - -if __name__ == "__main__": - - import matplotlib.pyplot as plt - - fig = plt.gcf() - fig.clf() - ax = plt.subplot(111) - - offsetbox = AnchoredText("Test", loc=6, pad=0.3, - borderpad=0.3, prop=None) - xy = (0.5, 0.5) - ax.plot([0.5], [0.5], "xk") - ab = AnnotationBbox(offsetbox, xy, - xybox=(1., .5), - xycoords='data', - boxcoords=("axes fraction", "data"), - arrowprops=dict(arrowstyle="->")) - #arrowprops=None) - - ax.add_artist(ab) - - - from matplotlib.patches import Circle - ada = AnchoredDrawingArea(20, 20, 0, 0, - loc=6, pad=0.1, borderpad=0.3, frameon=True) - p = Circle((10, 10), 10) - ada.da.add_artist(p) - - ab = AnnotationBbox(ada, (0.3, 0.4), - xybox=(1., 0.4), - xycoords='data', - boxcoords=("axes fraction", "data"), - arrowprops=dict(arrowstyle="->")) - #arrowprops=None) - - ax.add_artist(ab) - - - arr = np.arange(100).reshape((10,10)) - im = AnchoredImage(arr, - loc=4, - pad=0.5, borderpad=0.2, prop=None, frameon=True, - zoom=1, - cmap = None, - norm = None, - interpolation=None, - origin=None, - extent=None, - filternorm=1, - filterrad=4.0, - resample = False, - ) - - ab = AnnotationBbox(im, (0.5, 0.5), - xybox=(-10., 10.), - xycoords='data', - boxcoords="offset points", - arrowprops=dict(arrowstyle="->")) - #arrowprops=None) - - ax.add_artist(ab) - - ax.set_xlim(0, 1) - ax.set_ylim(0, 1) - - - plt.draw() - plt.show() - +from mpl_toolkits.axes_grid1.anchored_artists import \ + AnchoredDrawingArea, AnchoredAuxTransformBox, \ + AnchoredEllipse, AnchoredSizeBar Modified: trunk/matplotlib/lib/mpl_toolkits/axes_grid/angle_helper.py =================================================================== --- trunk/matplotlib/lib/mpl_toolkits/axes_grid/angle_helper.py 2010-04-06 17:05:51 UTC (rev 8223) +++ trunk/matplotlib/lib/mpl_toolkits/axes_grid/angle_helper.py 2010-04-06 17:06:52 UTC (rev 8224) @@ -1,345 +1 @@ -from math import floor - -import numpy as np -import math - -A = np.array - -from mpl_toolkits.axes_grid.grid_finder import ExtremeFinderSimple - -def select_step_degree(dv): - - degree_limits_ = [1.5, 3, 7, 13, 20, 40, 70, 120, 270, 520] - degree_steps_ = [ 1, 2, 5, 10, 15, 30, 45, 90, 180, 360] - degree_factors = [1.] * len(degree_steps_) - - minsec_limits_ = [1.5, 2.5, 3.5, 8, 11, 18, 25, 45] - minsec_steps_ = [1, 2, 3, 5, 10, 15, 20, 30] - - minute_limits_ = A(minsec_limits_)*(1./60.) - minute_factors = [60.] * len(minute_limits_) - - second_limits_ = A(minsec_limits_)*(1./3600.) - second_factors = [3600.] * len(second_limits_) - - degree_limits = np.concatenate([second_limits_, - minute_limits_, - degree_limits_]) - - degree_steps = np.concatenate([minsec_steps_, - minsec_steps_, - degree_steps_]) - - degree_factors = np.concatenate([second_factors, - minute_factors, - degree_factors]) - - n = degree_limits.searchsorted(dv) - step = degree_steps[n] - factor = degree_factors[n] - - return step, factor - - - -def select_step_hour(dv): - - hour_limits_ = [1.5, 2.5, 3.5, 5, 7, 10, 15, 21, 36] - hour_steps_ = [1, 2 , 3, 4, 6, 8, 12, 18, 24] - hour_factors = [1.] * len(hour_steps_) - - minsec_limits_ = [1.5, 2.5, 3.5, 4.5, 5.5, 8, 11, 14, 18, 25, 45] - minsec_steps_ = [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30] - - minute_limits_ = A(minsec_limits_)*(1./60.) - minute_factors = [60.] * len(minute_limits_) - - second_limits_ = A(minsec_limits_)*(1./3600.) - second_factors = [3600.] * len(second_limits_) - - hour_limits = np.concatenate([second_limits_, - minute_limits_, - hour_limits_]) - - hour_steps = np.concatenate([minsec_steps_, - minsec_steps_, - hour_steps_]) - - hour_factors = np.concatenate([second_factors, - minute_factors, - hour_factors]) - - n = hour_limits.searchsorted(dv) - step = hour_steps[n] - factor = hour_factors[n] - - return step, factor - - -def select_step_sub(dv): - - # subarcsec or degree - tmp = 10.**(int(math.log10(dv))-1.) - dv2 = dv/tmp - substep_limits_ = [1.5, 3., 7.] - substep_steps_ = [1. , 2., 5.] - - factor = 1./tmp - - if 1.5*tmp >= dv: - step = 1 - elif 3.*tmp >= dv: - step = 2 - elif 7.*tmp >= dv: - step = 5 - else: - step = 1 - factor = 0.1*factor - - return step, factor - - -def select_step(v1, v2, nv, hour=False): - - if v1 > v2: - v1, v2 = v2, v1 - - A = np.array - - dv = float(v2 - v1) / nv - - if hour: - _select_step = select_step_hour - cycle = 24. - else: - _select_step = select_step_degree - cycle = 360. - - # for degree - if dv > 1./3600.: - #print "degree" - step, factor = _select_step(dv) - else: - step, factor = select_step_sub(dv*3600.) - #print "feac", step, factor - - factor = factor * 3600. - - - f1, f2, fstep = v1*factor, v2*factor, step/factor - levs = np.arange(math.floor(f1/step), math.ceil(f2/step)+0.5, - 1, dtype="i") * step - - # n : number valid levels. If there is a cycle, e.g., [0, 90, 180, - # 270, 360], the a grid line needs to be extend from 0 to 360, so - # we need to return the whole array. However, the last level (360) - # needs to be ignored often. In this case, so we return n=4. - - n = len(levs) - - - # we need to check the range of values - # for example, -90 to 90, 0 to 360, - - - if factor == 1. and (levs[-1] >= levs[0]+cycle): # check for cycle - nv = int(cycle / step) - levs = np.arange(0, nv, 1) * step - n = len(levs) - - return np.array(levs), n, factor - - -def select_step24(v1, v2, nv): - v1, v2 = v1/15., v2/15. - levs, n, factor = select_step(v1, v2, nv, hour=True) - return levs*15., n, factor - -def select_step360(v1, v2, nv): - return select_step(v1, v2, nv, hour=False) - - - - -class LocatorHMS(object): - def __init__(self, den): - self.den = den - def __call__(self, v1, v2): - return select_step24(v1, v2, self.den) - - -class LocatorDMS(object): - def __init__(self, den): - self.den = den - def __call__(self, v1, v2): - return select_step360(v1, v2, self.den) - - -class FormatterHMS(object): - def __call__(self, direction, factor, values): # hour - if len(values) == 0: - return [] - ss = [[-1, 1][v>0] for v in values] - values = np.abs(values)/15. - - if factor == 1: - return ["$%d^{\mathrm{h}}$" % (int(v),) for v in values] - elif factor == 60: - return ["$%d^{\mathrm{h}}\,%02d^{\mathrm{m}}$" % (s*floor(v/60.), v%60) \ - for s, v in zip(ss, values)] - elif factor == 3600: - if ss[-1] == -1: - inverse_order = True - values = values[::-1] - else: - inverse_order = False - degree = floor(values[0]/3600.) - hm_fmt = "$%d^{\mathrm{h}}\,%02d^{\mathrm{m}}\," - s_fmt = "%02d^{\mathrm{s}}$" - l_hm_old = "" - r = [] - for v in values-3600*degree: - l_hm = hm_fmt % (ss[0]*degree, floor(v/60.)) - l_s = s_fmt % (v%60,) - if l_hm != l_hm_old: - l_hm_old = l_hm - l = l_hm + l_s - else: - l = "$"+l_s - r.append(l) - if inverse_order: - return r[::-1] - else: - return r - #return [fmt % (ss[0]*degree, floor(v/60.), v%60) \ - # for s, v in zip(ss, values-3600*degree)] - else: # factor > 3600. - return [r"$%s^{\mathrm{h}}$" % (str(v),) for v in ss*values] - - -class FormatterDMS(object): - def __call__(self, direction, factor, values): - if len(values) == 0: - return [] - ss = [[-1, 1][v>0] for v in values] - values = np.abs(values) - if factor == 1: - return ["$%d^{\circ}$" % (s*int(v),) for (s, v) in zip(ss, values)] - elif factor == 60: - return ["$%d^{\circ}\,%02d^{\prime}$" % (s*floor(v/60.), v%60) \ - for s, v in zip(ss, values)] - elif factor == 3600: - if ss[-1] == -1: - inverse_order = True - values = values[::-1] - else: - inverse_order = False - degree = floor(values[0]/3600.) - hm_fmt = "$%d^{\circ}\,%02d^{\prime}\," - s_fmt = "%02d^{\prime\prime}$" - l_hm_old = "" - r = [] - for v in values-3600*degree: - l_hm = hm_fmt % (ss[0]*degree, floor(v/60.)) - l_s = s_fmt % (v%60,) - if l_hm != l_hm_old: - l_hm_old = l_hm - l = l_hm + l_s - else: - l = "$"+l_s - r.append(l) - if inverse_order: - return r[::-1] - else: - return r - #return [fmt % (ss[0]*degree, floor(v/60.), v%60) \ - # for s, v in zip(ss, values-3600*degree)] - else: # factor > 3600. - return [r"$%s^{\circ}$" % (str(v),) for v in ss*values] - - - - -class ExtremeFinderCycle(ExtremeFinderSimple): - """ - When there is a cycle, e.g., longitude goes from 0-360. - """ - def __init__(self, - nx, ny, - lon_cycle = 360., - lat_cycle = None, - lon_minmax = None, - lat_minmax = (-90, 90) - ): - #self.transfrom_xy = transform_xy - #self.inv_transfrom_xy = inv_transform_xy - self.nx, self.ny = nx, ny - self.lon_cycle, self.lat_cycle = lon_cycle, lat_cycle - self.lon_minmax = lon_minmax - self.lat_minmax = lat_minmax - - - def __call__(self, transform_xy, x1, y1, x2, y2): - """ - get extreme values. - - x1, y1, x2, y2 in image coordinates (0-based) - nx, ny : number of dvision in each axis - """ - x_, y_ = np.linspace(x1, x2, self.nx), np.linspace(y1, y2, self.ny) - x, y = np.meshgrid(x_, y_) - lon, lat = transform_xy(np.ravel(x), np.ravel(y)) - - # iron out jumps, but algorithm should be improved. - # Tis is just naive way of doing and my fail for some cases. - if self.lon_cycle is not None: - lon0 = np.nanmin(lon) - lon -= 360. * ((lon - lon0) > 180.) - if self.lat_cycle is not None: - lat0 = np.nanmin(lat) - lat -= 360. * ((lat - lat0) > 180.) - - lon_min, lon_max = np.nanmin(lon), np.nanmax(lon) - lat_min, lat_max = np.nanmin(lat), np.nanmax(lat) - - lon_min, lon_max, lat_min, lat_max = \ - self._adjust_extremes(lon_min, lon_max, lat_min, lat_max) - - return lon_min, lon_max, lat_min, lat_max - - - def _adjust_extremes(self, lon_min, lon_max, lat_min, lat_max): - - lon_min, lon_max, lat_min, lat_max = \ - self._add_pad(lon_min, lon_max, lat_min, lat_max) - - # check cycle - if self.lon_cycle: - lon_max = min(lon_max, lon_min + self.lon_cycle) - if self.lat_cycle: - lat_max = min(lat_max, lat_min + self.lat_cycle) - - if self.lon_minmax is not None: - min0 = self.lon_minmax[0] - lon_min = max(min0, lon_min) - max0 = self.lon_minmax[1] - lon_max = min(max0, lon_max) - - if self.lat_minmax is not None: - min0 = self.lat_minmax[0] - lat_min = max(min0, lat_min) - max0 = self.lat_minmax[1] - lat_max = min(max0, lat_max) - - return lon_min, lon_max, lat_min, lat_max - - - - - -if __name__ == "__main__": - #test2() - print select_step360(21.2, 33.3, 5) - print select_step360(20+21.2/60., 21+33.3/60., 5) - print select_step360(20.5+21.2/3600., 20.5+33.3/3600., 5) - print select_step360(20+21.2/60., 20+53.3/60., 5) +from mpl_toolkits.axisartist.angle_helper import * Modified: trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_divider.py =================================================================== --- trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_divider.py 2010-04-06 17:05:51 UTC (rev 8223) +++ trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_divider.py 2010-04-06 17:06:52 UTC (rev 8224) @@ -1,751 +1,8 @@ -""" -The axes_divider module provide helper classes to adjust the positions of -multiple axes at the drawing time. +#from mpl_toolkits.axes_grid1.axes_divider import * - Divider: this is the class that is used calculates the axes - position. It divides the given renctangular area into several sub - rectangles. You intialize the divider by setting the horizontal - and vertical list of sizes that the division will be based on. You - then use the new_locator method, whose return value is a callable - object that can be used to set the axes_locator of the axes. +from mpl_toolkits.axes_grid1.axes_divider import Divider, AxesLocator, SubplotDivider, \ + AxesDivider, locatable_axes_factory, make_axes_locatable -""" - -import matplotlib.transforms as mtransforms - -from matplotlib.axes import SubplotBase - -import new - -import axes_size as Size - - -class Divider(object): - """ - This is the class that is used calculates the axes position. It - divides the given renctangular area into several - sub-rectangles. You intialize the divider by setting the - horizontal and vertical lists of sizes - (:mod:`mpl_toolkits.axes_grid.axes_size`) that the division will - be based on. You then use the new_locator method to create a - callable object that can be used to as the axes_locator of the - axes. - """ - - - def __init__(self, fig, pos, horizontal, vertical, aspect=None, anchor="C"): - """ - :param fig: matplotlib figure - :param pos: position (tuple of 4 floats) of the rectangle that - will be divided. - :param horizontal: list of sizes - (:mod:`~mpl_toolkits.axes_grid.axes_size`) - for horizontal division - :param vertical: list of sizes - (:mod:`~mpl_toolkits.axes_grid.axes_size`) - for vertical division - :param aspect: if True, the overall rectalngular area is reduced - so that the relative part of the horizontal and - vertical scales have same scale. - :param anchor: Detrmine how the reduced rectangle is placed - when aspect is True, - """ - - self._fig = fig - self._pos = pos - self._horizontal = horizontal - self._vertical = vertical - self._anchor = anchor - self._aspect = aspect - self._xrefindex = 0 - self._yrefindex = 0 - - - @staticmethod - def _calc_k(l, total_size, renderer): - - rs_sum, as_sum = 0., 0. - - for s in l: - _rs, _as = s.get_size(renderer) - rs_sum += _rs - as_sum += _as - - if rs_sum != 0.: - k = (total_size - as_sum) / rs_sum - return k - else: - return 0. - - - @staticmethod - def _calc_offsets(l, k, renderer): - - offsets = [0.] - - for s in l: - _rs, _as = s.get_size(renderer) - offsets.append(offsets[-1] + _rs*k + _as) - - return offsets - - - def set_position(self, pos): - """ - set the position of the rectangle. - - :param pos: position (tuple of 4 floats) of the rectangle that - will be divided. - """ - self._pos = pos - - def get_position(self): - "return the position of the rectangle." - return self._pos - - def set_anchor(self, anchor): - """ - :param anchor: anchor position - - ===== ============ - value description - ===== ============ - 'C' Center - 'SW' bottom left - 'S' bottom - 'SE' bottom right - 'E' right - 'NE' top right - 'N' top - 'NW' top left - 'W' left - ===== ============ - - """ - if anchor in mtransforms.Bbox.coefs.keys() or len(anchor) == 2: - self._anchor = anchor - else: - raise ValueError('argument must be among %s' % - ', '.join(mtransforms.BBox.coefs.keys())) - - def get_anchor(self): - "return the anchor" - return self._anchor - - def set_horizontal(self, h): - """ - :param horizontal: list of sizes - (:mod:`~mpl_toolkits.axes_grid.axes_size`) - for horizontal division - """ - self._horizontal = h - - - def get_horizontal(self): - "return horizontal sizes" - return self._horizontal - - def set_vertical(self, v): - """ - :param horizontal: list of sizes - (:mod:`~mpl_toolkits.axes_grid.axes_size`) - for horizontal division - """ - self._vertical = v - - def get_vertical(self): - "return vertical sizes" - return self._vertical - - - def set_aspect(self, aspect=False): - """ - :param anchor: True or False - """ - self._aspect = aspect - - def get_aspect(self): - "return aspect" - return self._aspect - - - def locate(self, nx, ny, nx1=None, ny1=None, renderer=None): - """ - - :param nx, nx1: Integers specifying the column-position of the - cell. When nx1 is None, a single nx-th column is - specified. Otherwise location of columns spanning between nx - to nx1 (but excluding nx1-th column) is specified. - - :param ny, ny1: same as nx and nx1, but for row positions. - """ - - - figW,figH = self._fig.get_size_inches() - x, y, w, h = self.get_position() - - k_h = self._calc_k(self._horizontal, figW*w, renderer) - k_v = self._calc_k(self._vertical, figH*h, renderer) - - if self.get_aspect(): - k = min(k_h, k_v) - ox = self._calc_offsets(self._horizontal, k, renderer) - oy = self._calc_offsets(self._vertical, k, renderer) - - ww = (ox[-1] - ox[0])/figW - hh = (oy[-1] - oy[0])/figH - pb = mtransforms.Bbox.from_bounds(x, y, w, h) - pb1 = mtransforms.Bbox.from_bounds(x, y, ww, hh) - pb1_anchored = pb1.anchored(self.get_anchor(), pb) - x0, y0 = pb1_anchored.x0, pb1_anchored.y0 - - else: - ox = self._calc_offsets(self._horizontal, k_h, renderer) - oy = self._calc_offsets(self._vertical, k_v, renderer) - x0, y0 = x, y - - - if nx1 is None: - nx1=nx+1 - if ny1 is None: - ny1=ny+1 - - x1, w1 = x0 + ox[nx]/figW, (ox[nx1] - ox[nx])/figW - y1, h1 = y0 + oy[ny]/figH, (oy[ny1] - oy[ny])/figH - - return mtransforms.Bbox.from_bounds(x1, y1, w1, h1) - - - def new_locator(self, nx, ny, nx1=None, ny1=None): - """ - returns a new locator - (:class:`mpl_toolkits.axes_grid.axes_divider.AxesLocator`) for - specified cell. - - :param nx, nx1: Integers specifying the column-position of the - cell. When nx1 is None, a single nx-th column is - specified. Otherwise location of columns spanning between nx - to nx1 (but excluding nx1-th column) is specified. - - :param ny, ny1: same as nx and nx1, but for row positions. - """ - return AxesLocator(self, nx, ny, nx1, ny1) - - - -class AxesLocator(object): - """ - A simple callable object, initiallized with AxesDivider class, - returns the position and size of the given cell. - """ - def __init__(self, axes_divider, nx, ny, nx1=None, ny1=None): - """ - :param axes_divider: An instance of AxesDivider class. - - :param nx, nx1: Integers specifying the column-position of the - cell. When nx1 is None, a single nx-th column is - specified. Otherwise location of columns spanning between nx - to nx1 (but excluding nx1-th column) is is specified. - - :param ny, ny1: same as nx and nx1, but for row positions. - """ - self._axes_divider = axes_divider - - _xrefindex = axes_divider._xrefindex - _yrefindex = axes_divider._yrefindex - - self._nx, self._ny = nx - _xrefindex, ny - _yrefindex - - if nx1 is None: - nx1 = nx+1 - if ny1 is None: - ny1 = ny+1 - - self._nx1 = nx1 - _xrefindex - self._ny1 = ny1 - _yrefindex - - - def __call__(self, axes, renderer): - - _xrefindex = self._axes_divider._xrefindex - _yrefindex = self._axes_divider._yrefindex - - return self._axes_divider.locate(self._nx + _xrefindex, - self._ny + _yrefindex, - self._nx1 + _xrefindex, - self._ny1 + _yrefindex, - renderer) - - - -class SubplotDivider(Divider): - """ - The Divider class whose rectangle area is specified as a subplot grometry. - """ - - - def __init__(self, fig, *args, **kwargs): - """ - *fig* is a :class:`matplotlib.figure.Figure` instance. - - *args* is the tuple (*numRows*, *numCols*, *plotNum*), where - the array of subplots in the figure has dimensions *numRows*, - *numCols*, and where *plotNum* is the number of the subplot - being created. *plotNum* starts at 1 in the upper left - corner and increases to the right. - - If *numRows* <= *numCols* <= *plotNum* < 10, *args* can be the - decimal integer *numRows* * 100 + *numCols* * 10 + *plotNum*. - """ - - self.figure = fig - - if len(args)==1: - s = str(args[0]) - if len(s) != 3: - raise ValueError('Argument to subplot must be a 3 digits long') - rows, cols, num = map(int, s) - elif len(args)==3: - rows, cols, num = args - else: - raise ValueError( 'Illegal argument to subplot') - - - total = rows*cols - 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 - self._cols = cols - self._num = num - - self.update_params() - - pos = self.figbox.bounds - horizontal = kwargs.pop("horizontal", []) - vertical = kwargs.pop("vertical", []) - aspect = kwargs.pop("aspect", None) - anchor = kwargs.pop("anchor", "C") - - if kwargs: - raise Exception("") - - Divider.__init__(self, fig, pos, horizontal, vertical, - aspect=aspect, anchor=anchor) - - - def get_position(self): - "return the bounds of the subplot box" - self.update_params() - return self.figbox.bounds - - - def update_params(self): - 'update the subplot position from fig.subplotpars' - - rows = self._rows - cols = self._cols - num = self._num - - pars = self.figure.subplotpars - left = pars.left - right = pars.right - bottom = pars.bottom - top = pars.top - wspace = pars.wspace - hspace = pars.hspace - totWidth = right-left - totHeight = top-bottom - - figH = totHeight/(rows + hspace*(rows-1)) - sepH = hspace*figH - - figW = totWidth/(cols + wspace*(cols-1)) - sepW = wspace*figW - - rowNum, colNum = divmod(num, cols) - - figBottom = top - (rowNum+1)*figH - rowNum*sepH - figLeft = left + colNum*(figW + sepW) - - self.figbox = mtransforms.Bbox.from_bounds(figLeft, figBottom, - figW, figH) - - -class AxesDivider(Divider): - """ - Divider based on the pre-existing axes. - """ - - def __init__(self, axes): - """ - :param axes: axes - """ - self._axes = axes - self._xref = Size.AxesX(axes) - self._yref = Size.AxesY(axes) - Divider.__init__(self, fig=axes.get_figure(), pos=None, - horizontal=[self._xref], vertical=[self._yref], - aspect=None, anchor="C") - - def _get_new_axes(self, **kwargs): - axes = self._axes - - axes_class = kwargs.pop("axes_class", None) - - if axes_class is None: - if isinstance(axes, SubplotBase): - axes_class = axes._axes_class - else: - axes_class = type(axes) - - ax = axes_class(axes.get_figure(), - axes.get_position(original=True), **kwargs) - - return ax - - - def new_horizontal(self, size, pad=None, pack_start=False, **kwargs): - """ - Add a new axes on the right (or left) side of the main axes. - - :param size: A width of the axes. A :mod:`~mpl_toolkits.axes_grid.axes_size` - instance or if float or string is given, *from_any* - fucntion is used to create one, with *ref_size* set to AxesX instance - of the current axes. - :param pad: pad between the axes. It takes same argument as *size*. - :param pack_start: If False, the new axes is appended at the end - of the list, i.e., it became the right-most axes. If True, it is - inseted at the start of the list, and becomes the left-most axes. - - All extra keywords argument is passed to when creating a axes. - if *axes_class* is given, the new axes will be created as an - instance of the given class. Otherwise, the same class of the - main axes will be used. if Not provided - - """ - - if pad: - if not isinstance(pad, Size._Base): - pad = Size.from_any(pad, - fraction_ref=self._xref) - if pack_start: - self._horizontal.insert(0, pad) - self._xrefindex += 1 - else: - self._horizontal.append(pad) - - if not isinstance(size, Size._Base): - size = Size.from_any(size, - fraction_ref=self._xref) - - if pack_start: - self._horizontal.insert(0, size) - self._xrefindex += 1 - locator = self.new_locator(nx=0, ny=0) - else: - self._horizontal.append(size) - locator = self.new_locator(nx=len(self._horizontal)-1, ny=0) - - ax = self._get_new_axes(**kwargs) - ax.set_axes_locator(locator) - - return ax - - def new_vertical(self, size, pad=None, pack_start=False, **kwargs): - """ - Add a new axes on the top (or bottom) side of the main axes. - - :param size: A height of the axes. A :mod:`~mpl_toolkits.axes_grid.axes_size` - instance or if float or string is given, *from_any* - fucntion is used to create one, with *ref_size* set to AxesX instance - of the current axes. - :param pad: pad between the axes. It takes same argument as *size*. - :param pack_start: If False, the new axes is appended at the end - of the list, i.e., it became the top-most axes. If True, it is - inseted at the start of the list, and becomes the bottom-most axes. - - All extra keywords argument is passed to when creating a axes. - if *axes_class* is given, the new axes will be created as an - instance of the given class. Otherwise, the same class of the - main axes will be used. if Not provided - - """ - - if pad: - if not isinstance(pad, Size._Base): - pad = Size.from_any(pad, - fraction_ref=self._yref) - if pack_start: - self._vertical.insert(0, pad) - self._yrefindex += 1 - else: - self._vertical.append(pad) - - if not isinstance(size, Size._Base): - size = Size.from_any(size, - fraction_ref=self._yref) - - if pack_start: - self._vertical.insert(0, size) - self._yrefindex += 1 - locator = self.new_locator(nx=0, ny=0) - else: - self._vertical.append(size) - locator = self.new_locator(nx=0, ny=len(self._vertical)-1) - - ax = self._get_new_axes(**kwargs) - ax.set_axes_locator(locator) - - return ax - - - def append_axes(self, position, size, pad=None, **kwargs): - """ - create an axes at the given *position* with the same height - (or width) of the main axes. - - *position* - ["left"|"right"|"bottom"|"top"] - - *size* and *pad* should be axes_grid.axes_size compatible. - """ - - if position == "left": - ax = self.new_horizontal(size, pad, pack_start=True, **kwargs) - elif position == "right": - ax = self.new_horizontal(size, pad, pack_start=False, **kwargs) - elif position == "bottom": - ax = self.new_vertical(size, pad, pack_start=True, **kwargs) - elif position == "top": - ax = self.new_vertical(size, pad, pack_start=False, **kwargs) - else: - raise ValueError("the position must be one of left, right, bottom, or top") - - self._fig.add_axes(ax) - return ax - - def get_aspect(self): - if self._aspect is None: - aspect = self._axes.get_aspect() - if aspect == "auto": - return False - else: - return True - else: - return self._aspect - - def get_position(self): - if self._pos is None: - bbox = self._axes.get_position(original=True) - return bbox.bounds - else: - return self._pos - - def get_anchor(self): - if self._anchor is None: - return self._axes.get_anchor() - else: - return self._anchor - - - -class LocatableAxesBase: - def __init__(self, *kl, **kw): - - self._axes_class.__init__(self, *kl, **kw) - - self._locator = None - self._locator_renderer = None - - def set_axes_locator(self, locator): - self._locator = locator - - def get_axes_locator(self): - return self._locator - - def apply_aspect(self, position=None): - - if self.get_axes_locator() is None: - self._axes_class.apply_aspect(self, position) - else: - pos = self.get_axes_locator()(self, self._locator_renderer) - self._axes_class.apply_aspect(self, position=pos) - - - def draw(self, renderer=None, inframe=False): - - self._locator_renderer = renderer - - self._axes_class.draw(self, renderer, inframe) - - - -_locatableaxes_classes = {} -def locatable_axes_factory(axes_class): - - new_class = _locatableaxes_classes.get(axes_class) - if new_class is None: - new_class = new.classobj("Locatable%s" % (axes_class.__name__), - (LocatableAxesBase, axes_class), - {'_axes_class': axes_class}) - _locatableaxes_classes[axes_class] = new_class - - return new_class - -#if hasattr(maxes.Axes, "get_axes_locator"): -# LocatableAxes = maxes.Axes -#else: - from mpl_toolkits.axes_grid.axislines import Axes LocatableAxes = locatable_axes_factory(Axes) - -def make_axes_locatable(axes): - if not hasattr(axes, "set_axes_locator"): - new_class = locatable_axes_factory(type(axes)) - axes.__class__ = new_class - - divider = AxesDivider(axes) - locator = divider.new_locator(nx=0, ny=0) - axes.set_axes_locator(locator) - - return divider - - -def get_demo_image(): - # prepare image - delta = 0.5 - - extent = (-3,4,-4,3) - import numpy as np - x = np.arange(-3.0, 4.001, delta) - y = np.arange(-4.0, 3.001, delta) - X, Y = np.meshgrid(x, y) - import matplotlib.mlab as mlab - Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) - Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1) - Z = (Z1 - Z2) * 10 - - return Z, extent - -def demo_locatable_axes(): - import matplotlib.pyplot as plt - - fig1 = plt.figure(1, (6, 6)) - fig1.clf() - - ## PLOT 1 - # simple image & colorbar - ax = fig1.add_subplot(2, 2, 1) - - Z, extent = get_demo_image() - - im = ax.imshow(Z, extent=extent, interpolation="nearest") - cb = plt.colorbar(im) - plt.setp(cb.ax.get_yticklabels(), visible=False) - - - ## PLOT 2 - # image and colorbar whose location is adjusted in the drawing time. - # a hard way - - divider = SubplotDivider(fig1, 2, 2, 2, aspect=True) - - # axes for image - ax = LocatableAxes(fig1, divider.get_position()) - - # axes for coloarbar - ax_cb = LocatableAxes(fig1, divider.get_position()) - - h = [Size.AxesX(ax), # main axes - Size.Fixed(0.05), # padding, 0.1 inch - Size.Fixed(0.2), # colorbar, 0.3 inch - ] - - v = [Size.AxesY(ax)] - - divider.set_horizontal(h) - divider.set_vertical(v) - - ax.set_axes_locator(divider.new_locator(nx=0, ny=0)) - ax_cb.set_axes_locator(divider.new_locator(nx=2, ny=0)) - - fig1.add_axes(ax) - fig1.add_axes(ax_cb) - - ax_cb.yaxis.set_ticks_position("right") - - Z, extent = get_demo_image() - - im = ax.imshow(Z, extent=extent, interpolation="nearest") - plt.colorbar(im, cax=ax_cb) - plt.setp(ax_cb.get_yticklabels(), visible=False) - - plt.draw() - #plt.colorbar(im, cax=ax_cb) - - - ## PLOT 3 - # image and colorbar whose location is adjusted in the drawing time. - # a easy way - - ax = fig1.add_subplot(2, 2, 3) - divider = make_axes_locatable(ax) - - ax_cb = divider.new_horizontal(size="5%", pad=0.05) - fig1.add_axes(ax_cb) - - im = ax.imshow(Z, extent=extent, interpolation="nearest") - plt.colorbar(im, cax=ax_cb) - plt.setp(ax_cb.get_yticklabels(), visible=False) - - - ## PLOT 4 - # two images side by sied with fixed padding. - - ax = fig1.add_subplot(2, 2, 4) - divider = make_axes_locatable(ax) - - ax2 = divider.new_horizontal(size="100%", pad=0.05) - fig1.add_axes(ax2) - - ax.imshow(Z, extent=extent, interpolation="nearest") - ax2.imshow(Z, extent=extent, interpolation="nearest") - plt.setp(ax2.get_yticklabels(), visible=False) - plt.draw() - plt.show() - - -def demo_fixed_size_axes(): - import matplotlib.pyplot as plt - - fig2 = plt.figure(2, (6, 6)) - - # The first items are for padding and the second items are for the axes. - # sizes are in inch. - h = [Size.Fixed(1.0), Size.Fixed(4.5)] - v = [Size.Fixed(0.7), Size.Fixed(5.)] - - divider = Divider(fig2, (0.0, 0.0, 1., 1.), h, v, aspect=False) - # the width and height of the rectangle is ignored. - - ax = LocatableAxes(fig2, divider.get_position()) - ax.set_axes_locator(divider.new_locator(nx=1, ny=1)) - - fig2.add_axes(ax) - - ax.plot([1,2,3]) - - plt.draw() - plt.show() - #plt.colorbar(im, cax=ax_cb) - - - - - -if __name__ == "__main__": - demo_locatable_axes() - demo_fixed_size_axes() Modified: trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_grid.py =================================================================== --- trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_grid.py 2010-04-06 17:05:51 UTC (rev 8223) +++ trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_grid.py 2010-04-06 17:06:52 UTC (rev 8224) @@ -1,71 +1,9 @@ -import matplotlib.cbook as cbook -import matplotlib.pyplot as plt -import matplotlib.axes as maxes -#import matplotlib.colorbar as mcolorbar -import colorbar as mcolorbar -import matplotlib as mpl -import matplotlib.patches as mpatches -import matplotlib.lines as mlines -import matplotlib.ticker as ticker -from axes_divider import Size, SubplotDivider, LocatableAxes, Divider +import mpl_toolkits.axes_grid1.axes_grid as axes_grid_orig +from axes_divider import LocatableAxes -import numpy as np - -def _tick_only(ax, bottom_on, left_on): - bottom_off = not bottom_on - left_off = not left_on - [l.set_visible(bottom_off) for l in ax.get_xticklabels()] - [l.set_visible(left_off) for l in ax.get_yticklabels()] - ax.xaxis.label.set_visible(bottom_off) - ax.yaxis.label.set_visible(left_off) - if hasattr(ax, "_axislines"): - ax._axislines["bottom"].major_ticklabels.set_visible(bottom_off) - ax._axislines["left"].major_ticklabels.set_visible(left_off) - ax._axislines["bottom"].minor_ticklabels.set_visible(bottom_off) - ax._axislines["left"].minor_ticklabels.set_visible(left_off) - ax.axis["bottom"].label.set_visible(bottom_off) - ax.axis["left"].label.set_visible(left_off) - -class Colorbar(mcolorbar.Colorbar): - def _config_axes_deprecated(self, X, Y): - ''' - Make an axes patch and outline. - ''' - ax = self.ax - ax.set_frame_on(False) - ax.set_navigate(False) - xy = self._outline(X, Y) - ax.update_datalim(xy) - ax.set_xlim(*ax.dataLim.intervalx) - ax.set_ylim(*ax.dataLim.intervaly) - self.outline = mlines.Line2D(xy[:, 0], xy[:, 1], color=mpl.rcParams['axes.edgecolor'], - linewidth=mpl.rcParams['axes.linewidth']) - ax.add_artist(self.outline) - self.outline.set_clip_box(None) - self.outline.set_clip_path(None) - c = mpl.rcParams['axes.facecolor'] - self.patch = mpatches.Polygon(xy, edgecolor=c, - facecolor=c, - linewidth=0.01, - zorder=-1) - ax.add_artist(self.patch) - ticks, ticklabels, offset_string = self._ticker() - - if self.orientation == 'vertical': - ax.set_yticks(ticks) - ax.set_yticklabels(ticklabels) - ax.yaxis.get_major_formatter().set_offset_string(offset_string) - - else: - ax.set_xticks(ticks) - ax.set_xticklabels(ticklabels) - ax.xaxis.get_major_formatter().set_offset_string(offset_string) - - - -class CbarAxes(LocatableAxes): +class CbarAxes(axes_grid_orig.CbarAxesBase, LocatableAxes): def __init__(self, *kl, **kwargs): orientation=kwargs.pop("orientation", None) if orientation is None: @@ -74,706 +12,19 @@ self._default_label_on = False self.locator = None - super(CbarAxes, self).__init__(*kl, **kwargs) + super(LocatableAxes, self).__init__(*kl, **kwargs) - - def colorbar(self, mappable, **kwargs): - locator=kwargs.pop("locator", None) - if locator is None: - locator = ticker.MaxNLocator(5) - self.locator = locator - - kwargs["ticks"] = locator - - - self.hold(True) - if self.orientation in ["top", "bottom"]: - orientation="horizontal" - else: - orientation="vertical" - - cb = Colorbar(self, mappable, orientation=orientation, **kwargs) - #self._config_axes() - - def on_changed(m): - #print 'calling on changed', m.get_cmap().name - cb.set_cmap(m.get_cmap()) - cb.set_clim(m.get_clim()) - cb.update_bruteforce(m) - - self.cbid = mappable.callbacksSM.connect('changed', on_changed) - mappable.set_colorbar(cb, self) - return cb - def cla(self): - super(CbarAxes, self).cla() + super(LocatableAxes, self).cla() self._config_axes() - def _config_axes(self): - ''' - Make an axes patch and outline. - ''' - ax = self - ax.set_navigate(False) - for axis in ax.axis.values(): - axis.major_ticks.set_visible(False) - axis.minor_ticks.set_visible(False) - axis.major_ticklabels.set_visible(False) - axis.minor_ticklabels.set_visible(False) - axis.label.set_visible(False) +class Grid(axes_grid_orig.Grid): + _defaultLocatableAxesClass = LocatableAxes - axis = ax.axis[self.orientation] - axis.major_ticks.set_visible(True) - axis.minor_ticks.set_visible(True) - axis.major_ticklabels.set_size(int(axis.major_ticklabels.get_size()*.9)) - axis.major_tick_pad = 3 +class ImageGrid(axes_grid_orig.ImageGrid): + _defaultLocatableAxesClass = LocatableAxes + _defaultCbarAxesClass = CbarAxes - b = self._default_label_on - axis.major_ticklabels.set_visible(b) - axis.minor_ticklabels.set_visible(b) - axis.label.set_visible(b) - - - def toggle_label(self, b): - self._default_label_on = b - axis = self.axis[self.orientation] - axis.major_ticklabels.set_visible(b) - axis.minor_ticklabels.set_visible(b) - axis.label.set_visible(b) - - - -class Grid(object): - """ - A class that creates a grid of Axes. In matplotlib, the axes - location (and size) is specified in the normalized figure - coordinates. This may not be ideal for images that needs to be - displayed with a given aspect ratio. For example, displaying - images of a same size with some fixed padding between them cannot - be easily done in matplotlib. AxesGrid is used in such case. - """ - - def __init__(self, fig, - rect, - nrows_ncols, - ngrids = None, - direction="row", - axes_pad = 0.02, - add_all=True, - share_all=False, - share_x=True, - share_y=True, - #aspect=True, - label_mode="L", - axes_class=None, - ): - """ - Build an :class:`Grid` instance with a grid nrows*ncols - :class:`~matplotlib.axes.Axes` in - :class:`~matplotlib.figure.Figure` *fig* with - *rect=[left, bottom, width, height]* (in - :class:`~matplotlib.figure.Figure` coordinates) or - the subplot position code (e.g., "121"). - - Optional keyword arguments: - - ================ ======== ========================================= - Keyword Default Description - ================ ======== ========================================= - direction "row" [ "row" | "column" ] - axes_pad 0.02 float| pad betweein axes given in inches - add_all True [ True | False ] - share_all False [ True | False ] - share_x True [ True | False ] - share_y True [ True | False ] - label_mode "L" [ "L" | "1" | "all" ] - axes_class None a type object which must be a subclass - of :class:`~matplotlib.axes.Axes` - ================ ======== ========================================= - """ - self._nrows, self._ncols = nrows_ncols - - if ngrids is None: - ngrids = self._nrows * self._ncols - else: - if (ngrids > self._nrows * self._ncols) or (ngrids <= 0): - raise Exception("") - - self.ngrids = ngrids - - self._init_axes_pad(axes_pad) - - if direction not in ["column", "row"]: - raise Exception("") - - self._direction = direction - - - if axes_class is None: - axes_class = LocatableAxes - axes_class_args = {} - else: - if isinstance(axes_class, maxes.Axes): - axes_class_args = {} - else: - axes_class, axes_class_args = axes_class - - self.axes_all = [] - self.axes_column = [[] for i in range(self._ncols)] - self.axes_row = [[] for i in range(self._nrows)] - - - h = [] - v = [] - if cbook.is_string_like(rect) or cbook.is_numlike(rect): - self._divider = SubplotDivider(fig, rect, horizontal=h, vertical=v, - aspect=False) - elif len(rect) == 3: - kw = dict(horizontal=h, vertical=v, aspect=False) - self._divider = SubplotDivider(fig, *rect, **kw) - elif len(rect) == 4: - self._divider = Divider(fig, rect, horizontal=h, vertical=v, - aspect=False) - else: - raise Exception("") - - - rect = self._divider.get_position() - - # reference axes - self._column_refax = [None for i in range(self._ncols)] - self._row_refax = [None for i in range(self._nrows)] - self._refax = None - - for i in range(self.ngrids): - - col, row = self._get_col_row(i) - - if share_all: - sharex = self._refax - sharey = self._refax - else: - if share_x: - sharex = self._column_refax[col] - else: - sharex = None - - if share_y: - sharey = self._row_refax[row] - else: - sharey = None - - ax = axes_class(fig, rect, sharex=sharex, sharey=sharey, - **axes_class_args) - - if share_all: - if self._refax is None: - self._refax = ax - else: - if sharex is None: - self._column_refax[col] = ax - if sharey is None: - self._row_refax[row] = ax - - self.axes_all.append(ax) - self.axes_column[col].append(ax) - self.axes_row[row].append(ax) - - self.axes_llc = self.axes_column[0][-1] - - self._update_locators() - - if add_all: - for ax in self.axes_all: - fig.add_axes(ax) - - self.set_label_mode(label_mode) - - - def _init_axes_pad(self, axes_pad): - self._axes_pad = axes_pad - - self._horiz_pad_size = Size.Fixed(axes_pad) - self._vert_pad_size = Size.Fixed(axes_pad) - - - def _update_locators(self): - - h = [] - - h_ax_pos = [] - h_cb_pos = [] - - for ax in self._column_refax: - #if h: h.append(Size.Fixed(self._axes_pad)) - if h: h.append(self._horiz_pad_size) - - h_ax_pos.append(len(h)) - - sz = Size.Scaled(1) - h.append(sz) - - v = [] - - v_ax_pos = [] - v_cb_pos = [] - for ax in self._row_refax[::-1]: - #if v: v.append(Size.Fixed(self._axes_pad)) - if v: v.append(self._vert_pad_size) - - v_ax_pos.append(len(v)) - sz = Size.Scaled(1) - v.append(sz) - - - for i in range(self.ngrids): - col, row = self._get_col_row(i) - locator = self._divider.new_locator(nx=h_ax_pos[col], - ny=v_ax_pos[self._nrows -1 - row]) - self.axes_all[i].set_axes_locator(locator) - - self._divider.set_horizontal(h) - self._divider.set_vertical(v) - - - - def _get_col_row(self, n): - if self._direction == "column": - col, row = divmod(n, self._nrows) - else: - row, col = divmod(n, self._ncols) - - return col, row - - - def __getitem__(self, i): - return self.axes_all[i] - - - def get_geometry(self): - """ - get geometry of the grid. Returns a tuple of two integer, - representing number of rows and number of columns. - """ - return self._nrows, self._ncols - - def set_axes_pad(self, axes_pad): - "set axes_pad" - self._axes_pad = axes_pad - - self._horiz_pad_size.fixed_size = axes_pad - self._vert_pad_size.fixed_size = axes_pad - - - def get_axes_pad(self): - "get axes_pad" - return self._axes_pad - - def set_aspect(self, aspect): - "set aspect" - self._divider.set_aspect(aspect) - - def get_aspect(self): - "get aspect" - return self._divider.get_aspect() - - def set_label_mode(self, mode): - "set label_mode" - if mode == "all": - for ax in self.axes_all: - _tick_only(ax, False, False) - elif mode == "L": - # left-most axes - for ax in self.axes_column[0][:-1]: - _tick_only(ax, bottom_on=True, left_on=False) - # lower-left axes - ax = self.axes_column[0][-1] - _tick_only(ax, bottom_on=False, left_on=False) - - for col in self.axes_column[1:]: - # axes with no labels - for ax in col[:-1]: - _tick_only(ax, bottom_on=True, left_on=True) - - # bottom - ax = col[-1] - _tick_only(ax, bottom_on=False, left_on=True) - - elif mode == "1": - for ax in self.axes_all: - _tick_only(ax, bottom_on=True, left_on=True) - - ax = self.axes_llc - _tick_only(ax, bottom_on=False, left_on=False) - - -class ImageGrid(Grid): - """ - A class that creates a grid of Axes. In matplotlib, the axes - location (and size) is specified in the normalized figure - coordinates. This may not be ideal for images that needs to be - displayed with a given aspect ratio. For example, displaying - images of a same size with some fixed padding between them cannot - be easily done in matplotlib. ImageGrid is used in such case. - """ - - def __init__(self, fig, - rect, - nrows_ncols, - ngrids = None, - direction="row", - axes_pad = 0.02, - add_all=True, - share_all=False, - aspect=True, - label_mode="L", - cbar_mode=None, - cbar_location="right", - cbar_pad=None, - cbar_size="5%", - cbar_set_cax=True, - axes_class=None, - ): - """ - Build an :class:`ImageGrid` instance with a grid nrows*ncols - :class:`~matplotlib.axes.Axes` in - :class:`~matplotlib.figure.Figure` *fig* with - *rect=[left, bottom, width, height]* (in - :class:`~matplotlib.figure.Figure` coordinates) or - the subplot position code (e.g., "121"). - - Optional keyword arguments: - - ================ ======== ========================================= - Keyword Default Description - ================ ======== ========================================= - direction "row" [ "row" | "column" ] - axes_pad 0.02 float| pad betweein axes given in inches - add_all True [ True | False ] - share_all False [ True | False ] - aspect True [ True | False ] - label_mode "L" [ "L" | "1" | "all" ] - cbar_mode None [ "each" | "single" ] - cbar_location "right" [ "right" | "top" ] - cbar_pad None - cbar_size "5%" - cbar_set_cax True [ True | False ] - axes_class None a type object which must be a subclass - of :class:`~matplotlib.axes.Axes` - ================ ======== ========================================= - - *cbar_set_cax* : if True, each axes in the grid has a cax - attribute that is bind to associated cbar_axes. - """ - self._nrows, self._ncols = nrows_ncols - - if ngrids is None: - ngrids = self._nrows * self._ncols - else: - if (ngrids > self._nrows * self._ncols) or (ngrids <= 0): - raise Exception("") - - self.ngrids = ngrids - - self._axes_pad = axes_pad - - self._colorbar_mode = cbar_mode - self._colorbar_location = cbar_location - if cbar_pad is None: - self._colorbar_pad = axes_pad - else: - self._colorbar_pad = cbar_pad - - self._colorbar_size = cbar_size - - self._init_axes_pad(axes_pad) - - if direction not in ["column", "row"]: - raise Exception("") - - self._direction = direction - - - if axes_class is None: - axes_class = LocatableAxes - axes_class_args = {} - else: - if isinstance(axes_class, maxes.Axes): - axes_class_args = {} - else: - axes_class, axes_class_args = axes_class - - cbar_axes_class = CbarAxes - - - self.axes_all = [] - self.axes_column = [[] for i in range(self._ncols)] - self.axes_row = [[] for i in range(self._nrows)] - - self.cbar_axes = [] - - h = [] - v = [] - if cbook.is_string_like(rect) or cbook.is_numlike(rect): - self._divider = SubplotDivider(fig, rect, horizontal=h, vertical=v, - aspec... [truncated message content] |
From: <lee...@us...> - 2010-04-06 20:38:38
|
Revision: 8226 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8226&view=rev Author: leejjoon Date: 2010-04-06 20:38:31 +0000 (Tue, 06 Apr 2010) Log Message: ----------- modify axes_grid toolkit examples to use axes_grid1 and axisartist Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/examples/axes_grid/demo_axes_divider.py trunk/matplotlib/examples/axes_grid/demo_axes_grid.py trunk/matplotlib/examples/axes_grid/demo_axes_grid2.py trunk/matplotlib/examples/axes_grid/demo_axes_rgb.py trunk/matplotlib/examples/axes_grid/demo_colorbar_with_inset_locator.py trunk/matplotlib/examples/axes_grid/demo_floating_axes.py trunk/matplotlib/examples/axes_grid/demo_floating_axis.py trunk/matplotlib/examples/axes_grid/demo_parasite_axes2.py trunk/matplotlib/examples/axes_grid/inset_locator_demo.py trunk/matplotlib/examples/axes_grid/inset_locator_demo2.py trunk/matplotlib/examples/axes_grid/parasite_simple2.py trunk/matplotlib/examples/axes_grid/scatter_hist.py trunk/matplotlib/examples/axes_grid/simple_anchored_artists.py trunk/matplotlib/examples/axes_grid/simple_axesgrid.py trunk/matplotlib/examples/axes_grid/simple_axesgrid2.py trunk/matplotlib/examples/axes_grid/simple_axisline4.py trunk/matplotlib/examples/pylab_examples/axes_zoom_effect.py trunk/matplotlib/examples/pylab_examples/demo_text_rotation_mode.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2010-04-06 19:47:30 UTC (rev 8225) +++ trunk/matplotlib/CHANGELOG 2010-04-06 20:38:31 UTC (rev 8226) @@ -1,3 +1,5 @@ +2010-04-06 modify axes_grid examples to use axes_grid1 and axisartist. -JJL + 2010-04-06 rebase axes_grid using axes_grid1 and axisartist modules. -JJL 2010-04-06 axes_grid toolkit is splitted into two separate modules, Modified: trunk/matplotlib/examples/axes_grid/demo_axes_divider.py =================================================================== --- trunk/matplotlib/examples/axes_grid/demo_axes_divider.py 2010-04-06 19:47:30 UTC (rev 8225) +++ trunk/matplotlib/examples/axes_grid/demo_axes_divider.py 2010-04-06 20:38:31 UTC (rev 8226) @@ -19,7 +19,7 @@ def demo_locatable_axes_hard(fig1): - from mpl_toolkits.axes_grid \ + from mpl_toolkits.axes_grid1 \ import SubplotDivider, LocatableAxes, Size divider = SubplotDivider(fig1, 2, 2, 2, aspect=True) @@ -57,7 +57,7 @@ def demo_locatable_axes_easy(ax): - from mpl_toolkits.axes_grid import make_axes_locatable + from mpl_toolkits.axes_grid1 import make_axes_locatable divider = make_axes_locatable(ax) @@ -76,7 +76,7 @@ def demo_images_side_by_sied(ax): - from mpl_toolkits.axes_grid import make_axes_locatable + from mpl_toolkits.axes_grid1 import make_axes_locatable divider = make_axes_locatable(ax) Modified: trunk/matplotlib/examples/axes_grid/demo_axes_grid.py =================================================================== --- trunk/matplotlib/examples/axes_grid/demo_axes_grid.py 2010-04-06 19:47:30 UTC (rev 8225) +++ trunk/matplotlib/examples/axes_grid/demo_axes_grid.py 2010-04-06 20:38:31 UTC (rev 8226) @@ -1,5 +1,5 @@ import matplotlib.pyplot as plt -from mpl_toolkits.axes_grid import AxesGrid +from mpl_toolkits.axes_grid1 import AxesGrid def get_demo_image(): import numpy as np @@ -38,6 +38,7 @@ axes_pad = 0.0, share_all=True, label_mode = "L", + cbar_location = "top", cbar_mode="single", ) @@ -47,6 +48,9 @@ #plt.colorbar(im, cax = grid.cbar_axes[0]) grid.cbar_axes[0].colorbar(im) + for cax in grid.cbar_axes: + cax.toggle_label(False) + # This affects all axes as share_all = True. grid.axes_llc.set_xticks([-2, 0, 2]) grid.axes_llc.set_yticks([-2, 0, 2]) @@ -72,6 +76,9 @@ im = grid[i].imshow(Z, extent=extent, interpolation="nearest") grid.cbar_axes[i].colorbar(im) + for cax in grid.cbar_axes: + cax.toggle_label(False) + # This affects all axes because we set share_all = True. grid.axes_llc.set_xticks([-2, 0, 2]) grid.axes_llc.set_yticks([-2, 0, 2]) Modified: trunk/matplotlib/examples/axes_grid/demo_axes_grid2.py =================================================================== --- trunk/matplotlib/examples/axes_grid/demo_axes_grid2.py 2010-04-06 19:47:30 UTC (rev 8225) +++ trunk/matplotlib/examples/axes_grid/demo_axes_grid2.py 2010-04-06 20:38:31 UTC (rev 8226) @@ -1,5 +1,5 @@ import matplotlib.pyplot as plt -from mpl_toolkits.axes_grid import ImageGrid +from mpl_toolkits.axes_grid1 import ImageGrid import numpy as np def get_demo_image(): @@ -57,10 +57,10 @@ for ax, z in zip(grid, ZS): ax.cax.toggle_label(True) - axis = ax.cax.axis[ax.cax.orientation] - axis.label.set_text("counts s$^{-1}$") - axis.label.set_size(10) - axis.major_ticklabels.set_size(6) + #axis = ax.cax.axis[ax.cax.orientation] + #axis.label.set_text("counts s$^{-1}$") + #axis.label.set_size(10) + #axis.major_ticklabels.set_size(6) # changing the colorbar ticks grid[1].cax.set_xticks([-1, 0, 1]) Modified: trunk/matplotlib/examples/axes_grid/demo_axes_rgb.py =================================================================== --- trunk/matplotlib/examples/axes_grid/demo_axes_rgb.py 2010-04-06 19:47:30 UTC (rev 8225) +++ trunk/matplotlib/examples/axes_grid/demo_axes_rgb.py 2010-04-06 20:38:31 UTC (rev 8226) @@ -1,9 +1,17 @@ import numpy as np import matplotlib.pyplot as plt -from demo_axes_divider import get_demo_image -from mpl_toolkits.axes_grid.axes_rgb import make_rgb_axes, RGBAxes +from mpl_toolkits.axes_grid1.axes_rgb import make_rgb_axes, RGBAxes +def get_demo_image(): + from matplotlib.cbook import get_sample_data + f = get_sample_data("axes_grid/bivariate_normal.npy", asfileobj=False) + z = np.load(f) + # z is a numpy array of 15x15 + return z, (-3,4,-4,3) + + + def get_rgb(): Z, extent = get_demo_image() @@ -67,9 +75,11 @@ ax.RGB.set_ylim(0.9, 10.6) for ax1 in [ax.RGB, ax.R, ax.G, ax.B]: - for axisline in ax1._axislines.values(): - axisline.line.set_color("w") - axisline.major_ticks.set_mec("w") + for sp1 in ax1.spines.values(): + sp1.set_color("w") + for tick in ax1.xaxis.get_major_ticks() + ax1.yaxis.get_major_ticks(): + tick.tick1line.set_mec("w") + tick.tick2line.set_mec("w") return ax Modified: trunk/matplotlib/examples/axes_grid/demo_colorbar_with_inset_locator.py =================================================================== --- trunk/matplotlib/examples/axes_grid/demo_colorbar_with_inset_locator.py 2010-04-06 19:47:30 UTC (rev 8225) +++ trunk/matplotlib/examples/axes_grid/demo_colorbar_with_inset_locator.py 2010-04-06 20:38:31 UTC (rev 8226) @@ -1,7 +1,6 @@ import matplotlib.pyplot as plt -from mpl_toolkits.axes_grid.inset_locator import inset_axes -from mpl_toolkits.axes_grid.colorbar import colorbar +from mpl_toolkits.axes_grid1.inset_locator import inset_axes fig = plt.figure(1, [6, 3]) @@ -14,7 +13,7 @@ loc=1) im1=ax1.imshow([[1,2],[2, 3]]) -colorbar(im1, cax=axins1, orientation="horizontal", ticks=[1,2,3]) +plt.colorbar(im1, cax=axins1, orientation="horizontal", ticks=[1,2,3]) axins1.xaxis.set_ticks_position("bottom") # first subplot @@ -34,7 +33,7 @@ # the bbox_to_anchor coordinate. im=ax.imshow([[1,2],[2, 3]]) -colorbar(im, cax=axins, ticks=[1,2,3]) +plt.colorbar(im, cax=axins, ticks=[1,2,3]) plt.draw() plt.show() Modified: trunk/matplotlib/examples/axes_grid/demo_floating_axes.py =================================================================== --- trunk/matplotlib/examples/axes_grid/demo_floating_axes.py 2010-04-06 19:47:30 UTC (rev 8225) +++ trunk/matplotlib/examples/axes_grid/demo_floating_axes.py 2010-04-06 20:38:31 UTC (rev 8226) @@ -1,12 +1,11 @@ from matplotlib.transforms import Affine2D -from mpl_toolkits.axes_grid.floating_axes import FloatingSubplot,\ - GridHelperCurveLinear +import mpl_toolkits.axisartist.floating_axes as floating_axes import numpy as np -import mpl_toolkits.axes_grid.angle_helper as angle_helper +import mpl_toolkits.axisartist.angle_helper as angle_helper from matplotlib.projections import PolarAxes -from mpl_toolkits.axes_grid.grid_finder import FixedLocator, MaxNLocator, \ +from mpl_toolkits.axisartist.grid_finder import FixedLocator, MaxNLocator, \ DictFormatter def setup_axes1(fig, rect): @@ -15,9 +14,9 @@ """ tr = Affine2D().scale(2, 1).rotate_deg(30) - grid_helper = GridHelperCurveLinear(tr, extremes=(0, 4, 0, 4)) + grid_helper = floating_axes.GridHelperCurveLinear(tr, extremes=(0, 4, 0, 4)) - ax1 = FloatingSubplot(fig, rect, grid_helper=grid_helper) + ax1 = floating_axes.FloatingSubplot(fig, rect, grid_helper=grid_helper) fig.add_subplot(ax1) grid_helper.grid_finder.grid_locator1._nbins = 4 @@ -45,7 +44,7 @@ grid_locator2 = MaxNLocator(2) - grid_helper = GridHelperCurveLinear(tr, + grid_helper = floating_axes.GridHelperCurveLinear(tr, extremes=(.5*pi, 0, 2, 1), grid_locator1=grid_locator1, grid_locator2=grid_locator2, @@ -53,7 +52,7 @@ tick_formatter2=None, ) - ax1 = FloatingSubplot(fig, rect, grid_helper=grid_helper) + ax1 = floating_axes.FloatingSubplot(fig, rect, grid_helper=grid_helper) fig.add_subplot(ax1) # create a parasite axes whose transData in RA, cz @@ -88,7 +87,7 @@ ra0, ra1 = 8.*15, 14.*15 cz0, cz1 = 0, 14000 - grid_helper = GridHelperCurveLinear(tr, + grid_helper = floating_axes.GridHelperCurveLinear(tr, extremes=(ra0, ra1, cz0, cz1), grid_locator1=grid_locator1, grid_locator2=grid_locator2, @@ -96,7 +95,7 @@ tick_formatter2=None, ) - ax1 = FloatingSubplot(fig, rect, grid_helper=grid_helper) + ax1 = floating_axes.FloatingSubplot(fig, rect, grid_helper=grid_helper) fig.add_subplot(ax1) # adjust axis Modified: trunk/matplotlib/examples/axes_grid/demo_floating_axis.py =================================================================== --- trunk/matplotlib/examples/axes_grid/demo_floating_axis.py 2010-04-06 19:47:30 UTC (rev 8225) +++ trunk/matplotlib/examples/axes_grid/demo_floating_axis.py 2010-04-06 20:38:31 UTC (rev 8226) @@ -9,13 +9,13 @@ """ global ax1 import numpy as np - import mpl_toolkits.axes_grid.angle_helper as angle_helper + import mpl_toolkits.axisartist.angle_helper as angle_helper from matplotlib.projections import PolarAxes from matplotlib.transforms import Affine2D - from mpl_toolkits.axes_grid.parasite_axes import SubplotHost + from mpl_toolkits.axisartist import SubplotHost - from mpl_toolkits.axes_grid.grid_helper_curvelinear import GridHelperCurveLinear + from mpl_toolkits.axisartist import GridHelperCurveLinear # see demo_curvelinear_grid.py for details tr = Affine2D().scale(np.pi/180., 1.) + PolarAxes.PolarTransform() Modified: trunk/matplotlib/examples/axes_grid/demo_parasite_axes2.py =================================================================== --- trunk/matplotlib/examples/axes_grid/demo_parasite_axes2.py 2010-04-06 19:47:30 UTC (rev 8225) +++ trunk/matplotlib/examples/axes_grid/demo_parasite_axes2.py 2010-04-06 20:38:31 UTC (rev 8226) @@ -1,4 +1,4 @@ -from mpl_toolkits.axes_grid.parasite_axes import SubplotHost +from mpl_toolkits.axes_grid1.parasite_axes import SubplotHost import matplotlib.pyplot as plt if 1: @@ -6,25 +6,24 @@ host = SubplotHost(fig, 111) - host.set_ylabel("Density") - host.set_xlabel("Distance") - par1 = host.twinx() par2 = host.twinx() - par1.set_ylabel("Temperature") + offset = 60 + if hasattr(par2.axis["right"].line, "set_position"): + # use spine method + par2.axis["right"].line.set_position(('outward',offset)) + # set_position calls axis.cla() + par2.axis["left"].toggle(all=False) + else: + new_axisline = par2.get_grid_helper().new_fixed_axis + par2.axis["right"] = new_axisline(loc="right", + axes=par2, + offset=(offset, 0)) + + par2.axis["right"].toggle(all=True) - par2.axis["right"].set_visible(False) - offset = 60, 0 - new_axisline = par2.get_grid_helper().new_fixed_axis - par2.axis["right2"] = new_axisline(loc="right", - axes=par2, - offset=offset) - - par2.axis["right2"].label.set_visible(True) - par2.axis["right2"].set_label("Velocity") - fig.add_axes(host) plt.subplots_adjust(right=0.75) @@ -34,6 +33,7 @@ host.set_xlabel("Distance") host.set_ylabel("Density") par1.set_ylabel("Temperature") + par2.set_ylabel("Velocity") p1, = host.plot([0, 1, 2], [0, 1, 2], label="Density") p2, = par1.plot([0, 1, 2], [0, 3, 2], label="Temperature") @@ -46,7 +46,7 @@ host.axis["left"].label.set_color(p1.get_color()) par1.axis["right"].label.set_color(p2.get_color()) - par2.axis["right2"].label.set_color(p3.get_color()) + par2.axis["right"].label.set_color(p3.get_color()) plt.draw() plt.show() Modified: trunk/matplotlib/examples/axes_grid/inset_locator_demo.py =================================================================== --- trunk/matplotlib/examples/axes_grid/inset_locator_demo.py 2010-04-06 19:47:30 UTC (rev 8225) +++ trunk/matplotlib/examples/axes_grid/inset_locator_demo.py 2010-04-06 20:38:31 UTC (rev 8226) @@ -1,7 +1,7 @@ import matplotlib.pyplot as plt -from mpl_toolkits.axes_grid.inset_locator import inset_axes, zoomed_inset_axes -from mpl_toolkits.axes_grid.anchored_artists import AnchoredSizeBar +from mpl_toolkits.axes_grid1.inset_locator import inset_axes, zoomed_inset_axes +from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar def add_sizebar(ax, size): Modified: trunk/matplotlib/examples/axes_grid/inset_locator_demo2.py =================================================================== --- trunk/matplotlib/examples/axes_grid/inset_locator_demo2.py 2010-04-06 19:47:30 UTC (rev 8225) +++ trunk/matplotlib/examples/axes_grid/inset_locator_demo2.py 2010-04-06 20:38:31 UTC (rev 8226) @@ -1,7 +1,7 @@ import matplotlib.pyplot as plt -from mpl_toolkits.axes_grid.inset_locator import zoomed_inset_axes -from mpl_toolkits.axes_grid.inset_locator import mark_inset +from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes +from mpl_toolkits.axes_grid1.inset_locator import mark_inset import numpy as np Modified: trunk/matplotlib/examples/axes_grid/parasite_simple2.py =================================================================== --- trunk/matplotlib/examples/axes_grid/parasite_simple2.py 2010-04-06 19:47:30 UTC (rev 8225) +++ trunk/matplotlib/examples/axes_grid/parasite_simple2.py 2010-04-06 20:38:31 UTC (rev 8226) @@ -1,6 +1,6 @@ import matplotlib.transforms as mtransforms import matplotlib.pyplot as plt -from mpl_toolkits.axes_grid.parasite_axes import SubplotHost +from mpl_toolkits.axes_grid1.parasite_axes import SubplotHost obs = [["01_S1", 3.88, 0.14, 1970, 63], ["01_S4", 5.6, 0.82, 1622, 150], Modified: trunk/matplotlib/examples/axes_grid/scatter_hist.py =================================================================== --- trunk/matplotlib/examples/axes_grid/scatter_hist.py 2010-04-06 19:47:30 UTC (rev 8225) +++ trunk/matplotlib/examples/axes_grid/scatter_hist.py 2010-04-06 20:38:31 UTC (rev 8226) @@ -8,7 +8,7 @@ fig = plt.figure(1, figsize=(5.5,5.5)) -from mpl_toolkits.axes_grid import make_axes_locatable +from mpl_toolkits.axes_grid1 import make_axes_locatable axScatter = plt.subplot(111) divider = make_axes_locatable(axScatter) Modified: trunk/matplotlib/examples/axes_grid/simple_anchored_artists.py =================================================================== --- trunk/matplotlib/examples/axes_grid/simple_anchored_artists.py 2010-04-06 19:47:30 UTC (rev 8225) +++ trunk/matplotlib/examples/axes_grid/simple_anchored_artists.py 2010-04-06 20:38:31 UTC (rev 8226) @@ -2,7 +2,7 @@ def draw_text(ax): - from mpl_toolkits.axes_grid.anchored_artists import AnchoredText + from mpl_toolkits.axes_grid1.anchored_artists import AnchoredText at = AnchoredText("Figure 1a", loc=2, prop=dict(size=8), frameon=True, ) @@ -18,7 +18,7 @@ ax.add_artist(at2) def draw_circle(ax): # circle in the canvas coordinate - from mpl_toolkits.axes_grid.anchored_artists import AnchoredDrawingArea + from mpl_toolkits.axes_grid1.anchored_artists import AnchoredDrawingArea from matplotlib.patches import Circle ada = AnchoredDrawingArea(20, 20, 0, 0, loc=1, pad=0., frameon=False) @@ -27,7 +27,7 @@ ax.add_artist(ada) def draw_ellipse(ax): - from mpl_toolkits.axes_grid.anchored_artists import AnchoredEllipse + from mpl_toolkits.axes_grid1.anchored_artists import AnchoredEllipse # draw an ellipse of width=0.1, height=0.15 in the data coordinate ae = AnchoredEllipse(ax.transData, width=0.1, height=0.15, angle=0., loc=3, pad=0.5, borderpad=0.4, frameon=True) @@ -35,7 +35,7 @@ ax.add_artist(ae) def draw_sizebar(ax): - from mpl_toolkits.axes_grid.anchored_artists import AnchoredSizeBar + from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar # draw a horizontal bar with length of 0.1 in Data coordinate # (ax.transData) with a label underneath. asb = AnchoredSizeBar(ax.transData, Modified: trunk/matplotlib/examples/axes_grid/simple_axesgrid.py =================================================================== --- trunk/matplotlib/examples/axes_grid/simple_axesgrid.py 2010-04-06 19:47:30 UTC (rev 8225) +++ trunk/matplotlib/examples/axes_grid/simple_axesgrid.py 2010-04-06 20:38:31 UTC (rev 8226) @@ -1,12 +1,12 @@ import matplotlib.pyplot as plt -from mpl_toolkits.axes_grid import AxesGrid +from mpl_toolkits.axes_grid1 import ImageGrid import numpy as np im = np.arange(100) im.shape = 10, 10 fig = plt.figure(1, (4., 4.)) -grid = AxesGrid(fig, 111, # similar to subplot(111) +grid = ImageGrid(fig, 111, # similar to subplot(111) nrows_ncols = (2, 2), # creates 2x2 grid of axes axes_pad=0.1, # pad between axes in inch. ) Modified: trunk/matplotlib/examples/axes_grid/simple_axesgrid2.py =================================================================== --- trunk/matplotlib/examples/axes_grid/simple_axesgrid2.py 2010-04-06 19:47:30 UTC (rev 8225) +++ trunk/matplotlib/examples/axes_grid/simple_axesgrid2.py 2010-04-06 20:38:31 UTC (rev 8226) @@ -1,5 +1,5 @@ import matplotlib.pyplot as plt -from mpl_toolkits.axes_grid import AxesGrid +from mpl_toolkits.axes_grid1 import ImageGrid def get_demo_image(): import numpy as np @@ -10,7 +10,7 @@ return z, (-3,4,-4,3) F = plt.figure(1, (5.5, 3.5)) -grid = AxesGrid(F, 111, # similar to subplot(111) +grid = ImageGrid(F, 111, # similar to subplot(111) nrows_ncols = (1, 3), axes_pad = 0.1, add_all=True, Modified: trunk/matplotlib/examples/axes_grid/simple_axisline4.py =================================================================== --- trunk/matplotlib/examples/axes_grid/simple_axisline4.py 2010-04-06 19:47:30 UTC (rev 8225) +++ trunk/matplotlib/examples/axes_grid/simple_axisline4.py 2010-04-06 20:38:31 UTC (rev 8226) @@ -1,5 +1,5 @@ import matplotlib.pyplot as plt -from mpl_toolkits.axes_grid.parasite_axes import SubplotHost +from mpl_toolkits.axes_grid1.parasite_axes import SubplotHost import numpy as np fig = plt.figure(1, (4,3)) @@ -12,7 +12,7 @@ ax2 = ax.twin() # ax2 is responsible for "top" axis and "right" axis ax2.set_xticks([0., .5*np.pi, np.pi, 1.5*np.pi, 2*np.pi]) -ax2.set_xticklabels(["0", r"$\frac{1}{2}\pi$", +ax2.set_xticklabels(["$0$", r"$\frac{1}{2}\pi$", r"$\pi$", r"$\frac{3}{2}\pi$", r"$2\pi$"]) ax2.axis["right"].major_ticklabels.set_visible(False) Modified: trunk/matplotlib/examples/pylab_examples/axes_zoom_effect.py =================================================================== --- trunk/matplotlib/examples/pylab_examples/axes_zoom_effect.py 2010-04-06 19:47:30 UTC (rev 8225) +++ trunk/matplotlib/examples/pylab_examples/axes_zoom_effect.py 2010-04-06 20:38:31 UTC (rev 8226) @@ -1,7 +1,7 @@ from matplotlib.transforms import Bbox, TransformedBbox, \ blended_transform_factory -from mpl_toolkits.axes_grid.inset_locator import BboxPatch, BboxConnector,\ +from mpl_toolkits.axes_grid1.inset_locator import BboxPatch, BboxConnector,\ BboxConnectorPatch Modified: trunk/matplotlib/examples/pylab_examples/demo_text_rotation_mode.py =================================================================== --- trunk/matplotlib/examples/pylab_examples/demo_text_rotation_mode.py 2010-04-06 19:47:30 UTC (rev 8225) +++ trunk/matplotlib/examples/pylab_examples/demo_text_rotation_mode.py 2010-04-06 20:38:31 UTC (rev 8226) @@ -1,11 +1,11 @@ #clf() -from mpl_toolkits.axes_grid.axes_grid import AxesGrid +from mpl_toolkits.axes_grid1.axes_grid import ImageGrid def test_rotation_mode(fig, mode, subplot_location): ha_list = "left center right".split() va_list = "top center baseline bottom".split() - grid = AxesGrid(fig, subplot_location, + grid = ImageGrid(fig, subplot_location, nrows_ncols=(len(va_list), len(ha_list)), share_all=True, aspect=True, #label_mode='1', cbar_mode=None) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ry...@us...> - 2010-04-16 18:32:59
|
Revision: 8235 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8235&view=rev Author: ryanmay Date: 2010-04-16 18:32:53 +0000 (Fri, 16 Apr 2010) Log Message: ----------- Add a generic close event that notifies when the figure has been closed. Useful for disable other thing like timers when figure is closed. Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/backend_bases.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2010-04-16 14:28:06 UTC (rev 8234) +++ trunk/matplotlib/CHANGELOG 2010-04-16 18:32:53 UTC (rev 8235) @@ -1,3 +1,5 @@ +2010-04-16 Add a close_event to the backends. -RM + 2010-04-06 modify axes_grid examples to use axes_grid1 and axisartist. -JJL 2010-04-06 rebase axes_grid using axes_grid1 and axisartist modules. -JJL @@ -2,3 +4,3 @@ -2010-04-06 axes_grid toolkit is splitted into two separate modules, +2010-04-06 axes_grid toolkit is splitted into two separate modules, axes_grid1 and axisartist. -JJL Modified: trunk/matplotlib/lib/matplotlib/backend_bases.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backend_bases.py 2010-04-16 14:28:06 UTC (rev 8234) +++ trunk/matplotlib/lib/matplotlib/backend_bases.py 2010-04-16 18:32:53 UTC (rev 8235) @@ -920,6 +920,16 @@ Event.__init__(self, name, canvas) self.width, self.height = canvas.get_width_height() +class CloseEvent(Event): + """ + An event triggered by a figure being closed + + In addition to the :class:`Event` attributes, the following event attributes are defined: + """ + def __init__(self, name, canvas, guiEvent=None): + Event.__init__(self, name, canvas, guiEvent) + print 'Initing CloseEvent' + class LocationEvent(Event): """ A event that has a screen location @@ -1157,7 +1167,8 @@ 'figure_enter_event', 'figure_leave_event', 'axes_enter_event', - 'axes_leave_event' + 'axes_leave_event', + 'close_event' ] @@ -1293,6 +1304,15 @@ event = ResizeEvent(s, self) self.callbacks.process(s, event) + def close_event(self, guiEvent=None): + """ + This method will be called by all functions connected to the + 'close_event' with a :class:`CloseEvent` + """ + s = 'close_event' + event = CloseEvent(s, self, guiEvent=guiEvent) + self.callbacks.process(s, event) + def key_press_event(self, key, guiEvent=None): """ This method will be call all functions connected to the @@ -1742,6 +1762,7 @@ - 'figure_leave_event', - 'axes_enter_event', - 'axes_leave_event' + - 'close_event' For the location events (button and key press/release), if the mouse is over the axes, the variable ``event.inaxes`` will be This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ef...@us...> - 2010-04-18 23:11:30
|
Revision: 8241 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8241&view=rev Author: efiring Date: 2010-04-18 23:11:24 +0000 (Sun, 18 Apr 2010) Log Message: ----------- Improve access to ScalarFormatter useOffset and offset parameters Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/boilerplate.py trunk/matplotlib/lib/matplotlib/axes.py trunk/matplotlib/lib/matplotlib/pyplot.py trunk/matplotlib/lib/matplotlib/ticker.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2010-04-17 13:45:13 UTC (rev 8240) +++ trunk/matplotlib/CHANGELOG 2010-04-18 23:11:24 UTC (rev 8241) @@ -1,3 +1,6 @@ +2010-04-18 Control ScalarFormatter offsets directly and via the + Axes.ticklabel_format() method, and add that to pyplot. -EF + 2010-04-16 Add a close_event to the backends. -RM 2010-04-06 modify axes_grid examples to use axes_grid1 and axisartist. -JJL Modified: trunk/matplotlib/boilerplate.py =================================================================== --- trunk/matplotlib/boilerplate.py 2010-04-17 13:45:13 UTC (rev 8240) +++ trunk/matplotlib/boilerplate.py 2010-04-18 23:11:24 UTC (rev 8241) @@ -101,6 +101,7 @@ 'table', 'text', 'annotate', + 'ticklabel_format', ) cmappable = { Modified: trunk/matplotlib/lib/matplotlib/axes.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axes.py 2010-04-17 13:45:13 UTC (rev 8240) +++ trunk/matplotlib/lib/matplotlib/axes.py 2010-04-18 23:11:24 UTC (rev 8241) @@ -1880,6 +1880,11 @@ be used for numbers outside the range 10`-m`:sup: to 10`n`:sup:. Use (0,0) to include all numbers. + *useOffset* [True | False | offset]; if True, + the offset will be calculated as needed; + if False, no offset will be used; if a + numeric offset is specified, it will be + used. *axis* [ 'x' | 'y' | 'both' ] ============ ===================================== @@ -1892,13 +1897,14 @@ """ style = kwargs.pop('style', '').lower() scilimits = kwargs.pop('scilimits', None) + useOffset = kwargs.pop('useOffset', None) + axis = kwargs.pop('axis', 'both').lower() if scilimits is not None: try: m, n = scilimits m+n+1 # check that both are numbers except (ValueError, TypeError): raise ValueError("scilimits must be a sequence of 2 integers") - axis = kwargs.pop('axis', 'both').lower() if style[:3] == 'sci': sb = True elif style in ['plain', 'comma']: @@ -1923,6 +1929,11 @@ self.xaxis.major.formatter.set_powerlimits(scilimits) if axis == 'both' or axis == 'y': self.yaxis.major.formatter.set_powerlimits(scilimits) + if useOffset is not None: + if axis == 'both' or axis == 'x': + self.xaxis.major.formatter.set_useOffset(useOffset) + if axis == 'both' or axis == 'y': + self.yaxis.major.formatter.set_useOffset(useOffset) except AttributeError: raise AttributeError( "This method only works with the ScalarFormatter.") Modified: trunk/matplotlib/lib/matplotlib/pyplot.py =================================================================== --- trunk/matplotlib/lib/matplotlib/pyplot.py 2010-04-17 13:45:13 UTC (rev 8240) +++ trunk/matplotlib/lib/matplotlib/pyplot.py 2010-04-18 23:11:24 UTC (rev 8241) @@ -2529,6 +2529,14 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost +...@do...py_dedent(Axes.ticklabel_format) +def ticklabel_format(**kwargs): + ret = gca().ticklabel_format(**kwargs) + draw_if_interactive() + return ret + +# This function was autogenerated by boilerplate.py. Do not edit as +# changes will be lost def autumn(): ''' set the default colormap to autumn and apply to current image if any. Modified: trunk/matplotlib/lib/matplotlib/ticker.py =================================================================== --- trunk/matplotlib/lib/matplotlib/ticker.py 2010-04-17 13:45:13 UTC (rev 8240) +++ trunk/matplotlib/lib/matplotlib/ticker.py 2010-04-18 23:11:24 UTC (rev 8241) @@ -321,22 +321,34 @@ data < 10^-n or data >= 10^m, where n and m are the power limits set using set_powerlimits((n,m)). The defaults for these are controlled by the axes.formatter.limits rc parameter. + """ def __init__(self, useOffset=True, useMathText=False): # useOffset allows plotting small data ranges with large offsets: # for example: [1+1e-9,1+2e-9,1+3e-9] # useMathText will render the offset and scientific notation in mathtext - self._useOffset = useOffset + self.set_useOffset(useOffset) self._usetex = rcParams['text.usetex'] self._useMathText = useMathText - self.offset = 0 self.orderOfMagnitude = 0 self.format = '' self._scientific = True self._powerlimits = rcParams['axes.formatter.limits'] + def get_useOffset(self): + return self._useOffset + def set_useOffset(self, val): + if val in [True, False]: + self.offset = 0 + self._useOffset = val + else: + self._useOffset = False + self.offset = val + + useOffset = property(fget=get_useOffset, fset=set_useOffset) + def fix_minus(self, s): 'use a unicode minus rather than hyphen' if rcParams['text.usetex'] or not rcParams['axes.unicode_minus']: return s @@ -412,7 +424,8 @@ if len(self.locs) > 0: vmin, vmax = self.axis.get_view_interval() d = abs(vmax-vmin) - if self._useOffset: self._set_offset(d) + if self._useOffset: + self._set_offset(d) self._set_orderOfMagnitude(d) self._set_format() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ef...@us...> - 2010-04-19 01:14:01
|
Revision: 8242 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8242&view=rev Author: efiring Date: 2010-04-19 01:13:54 +0000 (Mon, 19 Apr 2010) Log Message: ----------- Tame that obscure MaxNLocator: change parameters after instantiation. Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/boilerplate.py trunk/matplotlib/lib/matplotlib/axes.py trunk/matplotlib/lib/matplotlib/pyplot.py trunk/matplotlib/lib/matplotlib/ticker.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2010-04-18 23:11:24 UTC (rev 8241) +++ trunk/matplotlib/CHANGELOG 2010-04-19 01:13:54 UTC (rev 8242) @@ -1,3 +1,7 @@ +2010-04-18 Control MaxNLocator parameters after instantiation, + and via Axes.locator_params method, with corresponding + pyplot function. -EF + 2010-04-18 Control ScalarFormatter offsets directly and via the Axes.ticklabel_format() method, and add that to pyplot. -EF Modified: trunk/matplotlib/boilerplate.py =================================================================== --- trunk/matplotlib/boilerplate.py 2010-04-18 23:11:24 UTC (rev 8241) +++ trunk/matplotlib/boilerplate.py 2010-04-19 01:13:54 UTC (rev 8242) @@ -102,6 +102,7 @@ 'text', 'annotate', 'ticklabel_format', + 'locator_params', ) cmappable = { Modified: trunk/matplotlib/lib/matplotlib/axes.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axes.py 2010-04-18 23:11:24 UTC (rev 8241) +++ trunk/matplotlib/lib/matplotlib/axes.py 2010-04-19 01:13:54 UTC (rev 8242) @@ -1938,6 +1938,45 @@ raise AttributeError( "This method only works with the ScalarFormatter.") + def locator_params(self, axis='both', tight=False, **kwargs): + """ + Convenience method for controlling tick locators. + + Keyword arguments: + + *axis* + ['x' | 'y' | 'both'] Axis on which to operate; + default is 'both'. + + *tight* + [True | False] Parameter passed to :meth:`autoscale_view`. + + Remaining keyword arguments are passed to directly to the + :meth:`~matplotlib.ticker.MaxNLocator.set_params` method. + + Typically one might want to reduce the maximum number + of ticks and use tight bounds when plotting small + subplots, for example:: + + ax.set_locator_params(tight=True, nbins=4) + + Because the locator is involved in autoscaling, + :meth:`autoscale_view` is called automatically after + the parameters are changed. + + This presently works only for the + :class:`~matplotlib.ticker.MaxNLocator` used + by default on linear axes, but it may be generalized. + """ + _x = axis in ['x', 'both'] + _y = axis in ['y', 'both'] + if _x: + self.xaxis.get_major_locator().set_params(**kwargs) + if _y: + self.yaxis.get_major_locator().set_params(**kwargs) + self.autoscale_view(tight=tight, scalex=_x, scaley=_y) + + def set_axis_off(self): """turn off the axis""" self.axison = False Modified: trunk/matplotlib/lib/matplotlib/pyplot.py =================================================================== --- trunk/matplotlib/lib/matplotlib/pyplot.py 2010-04-18 23:11:24 UTC (rev 8241) +++ trunk/matplotlib/lib/matplotlib/pyplot.py 2010-04-19 01:13:54 UTC (rev 8242) @@ -2537,6 +2537,14 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost +...@do...py_dedent(Axes.locator_params) +def locator_params(axis='both', tight=False, **kwargs): + ret = gca().locator_params(axis, tight, **kwargs) + draw_if_interactive() + return ret + +# This function was autogenerated by boilerplate.py. Do not edit as +# changes will be lost def autumn(): ''' set the default colormap to autumn and apply to current image if any. Modified: trunk/matplotlib/lib/matplotlib/ticker.py =================================================================== --- trunk/matplotlib/lib/matplotlib/ticker.py 2010-04-18 23:11:24 UTC (rev 8241) +++ trunk/matplotlib/lib/matplotlib/ticker.py 2010-04-19 01:13:54 UTC (rev 8242) @@ -1052,37 +1052,74 @@ """ Select no more than N intervals at nice locations. """ - - def __init__(self, nbins = 10, steps = None, - trim = True, - integer=False, - symmetric=False, - prune=None): + default_params = dict(nbins = 10, + steps = None, + trim = True, + integer=False, + symmetric=False, + prune=None) + def __init__(self, **kwargs): """ Keyword args: + + *nbins* + Maximum number of intervals; one less than max number of ticks. + + *steps* + Sequence of nice numbers starting with 1 and ending with 10; + e.g., [1, 2, 4, 5, 10] + + *integer* + If True, ticks will take only integer values. + + *symmetric* + If True, autoscaling will result in a range symmetric + about zero. + *prune* + ['lower' | 'upper' | 'both' | None] Remove edge ticks -- useful for stacked or ganged plots where the upper tick of one axes overlaps with the lower - tick of the axes above it. One of 'lower' | 'upper' | - 'both' | None. If prune=='lower', the smallest tick will + tick of the axes above it. + If prune=='lower', the smallest tick will be removed. If prune=='upper', the largest tick will be removed. If prune=='both', the largest and smallest ticks will be removed. If prune==None, no ticks will be removed. """ - self._nbins = int(nbins) - self._trim = trim - self._integer = integer - self._symmetric = symmetric - self._prune = prune - if steps is None: - self._steps = [1, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10] - else: - if int(steps[-1]) != 10: - steps = list(steps) - steps.append(10) - self._steps = steps - if integer: + # I left "trim" out; it defaults to True, and it is not + # clear that there is any use case for False, so we may + # want to remove that kwarg. EF 2010/04/18 + self.set_params(**self.default_params) + self.set_params(**kwargs) + + def set_params(self, **kwargs): + if 'nbins' in kwargs: + self._nbins = int(kwargs['nbins']) + if 'trim' in kwargs: + self._trim = kwargs['trim'] + if 'integer' in kwargs: + self._integer = kwargs['integer'] + if 'symmetric' in kwargs: + self._symmetric = kwargs['symmetric'] + if 'prune' in kwargs: + prune = kwargs['prune'] + if prune is not None and prune not in ['upper', 'lower', 'both']: + raise ValueError( + "prune must be 'upper', 'lower', 'both', or None") + self._prune = prune + if 'steps' in kwargs: + steps = kwargs['steps'] + if steps is None: + self._steps = [1, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10] + else: + if int(steps[-1]) != 10: + steps = list(steps) + steps.append(10) + self._steps = steps + if 'integer' in kwargs: + self._integer = kwargs['integer'] + if self._integer: self._steps = [n for n in self._steps if divmod(n,1)[1] < 0.001] def bin_boundaries(self, vmin, vmax): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <lee...@us...> - 2010-04-20 16:44:08
|
Revision: 8247 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8247&view=rev Author: leejjoon Date: 2010-04-20 16:44:01 +0000 (Tue, 20 Apr 2010) Log Message: ----------- update axes_grid toolkit documentation Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/axis_direction_demo_step01.py trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/axis_direction_demo_step02.py trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/axis_direction_demo_step03.py trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/axis_direction_demo_step04.py trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/demo_axis_direction.py trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/demo_ticklabel_alignment.py trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/parasite_simple.py trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_axis_direction01.py trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_axis_direction03.py trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_axis_pad.py trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_rgb.py trunk/matplotlib/doc/mpl_toolkits/axes_grid/index.rst trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/index.rst trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/overview.rst trunk/matplotlib/examples/axes_grid/demo_curvelinear_grid.py trunk/matplotlib/examples/axes_grid/demo_parasite_axes2.py trunk/matplotlib/examples/axes_grid/scatter_hist.py trunk/matplotlib/examples/axes_grid/simple_axisline4.py Added Paths: ----------- trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_axisartist1.py trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_colorbar.py trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/axisartist.rst Removed Paths: ------------- trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/axislines.rst Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2010-04-20 16:43:42 UTC (rev 8246) +++ trunk/matplotlib/CHANGELOG 2010-04-20 16:44:01 UTC (rev 8247) @@ -1,3 +1,5 @@ +2010-04-18 update the axes_grid documentation. -JJL + 2010-04-18 Control MaxNLocator parameters after instantiation, and via Axes.locator_params method, with corresponding pyplot function. -EF Modified: trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/axis_direction_demo_step01.py =================================================================== --- trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/axis_direction_demo_step01.py 2010-04-20 16:43:42 UTC (rev 8246) +++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/axis_direction_demo_step01.py 2010-04-20 16:44:01 UTC (rev 8247) @@ -1,8 +1,8 @@ import matplotlib.pyplot as plt -import mpl_toolkits.axes_grid.axislines as axislines +import mpl_toolkits.axisartist as axisartist def setup_axes(fig, rect): - ax = axislines.Subplot(fig, rect) + ax = axisartist.Subplot(fig, rect) fig.add_axes(ax) ax.set_ylim(-0.1, 1.5) Modified: trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/axis_direction_demo_step02.py =================================================================== --- trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/axis_direction_demo_step02.py 2010-04-20 16:43:42 UTC (rev 8246) +++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/axis_direction_demo_step02.py 2010-04-20 16:44:01 UTC (rev 8247) @@ -1,8 +1,8 @@ import matplotlib.pyplot as plt -import mpl_toolkits.axes_grid.axislines as axislines +import mpl_toolkits.axisartist as axisartist def setup_axes(fig, rect): - ax = axislines.Subplot(fig, rect) + ax = axisartist.Subplot(fig, rect) fig.add_axes(ax) ax.set_ylim(-0.1, 1.5) Modified: trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/axis_direction_demo_step03.py =================================================================== --- trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/axis_direction_demo_step03.py 2010-04-20 16:43:42 UTC (rev 8246) +++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/axis_direction_demo_step03.py 2010-04-20 16:44:01 UTC (rev 8247) @@ -1,8 +1,8 @@ import matplotlib.pyplot as plt -import mpl_toolkits.axes_grid.axislines as axislines +import mpl_toolkits.axisartist as axisartist def setup_axes(fig, rect): - ax = axislines.Subplot(fig, rect) + ax = axisartist.Subplot(fig, rect) fig.add_axes(ax) ax.set_ylim(-0.1, 1.5) Modified: trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/axis_direction_demo_step04.py =================================================================== --- trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/axis_direction_demo_step04.py 2010-04-20 16:43:42 UTC (rev 8246) +++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/axis_direction_demo_step04.py 2010-04-20 16:44:01 UTC (rev 8247) @@ -1,8 +1,8 @@ import matplotlib.pyplot as plt -import mpl_toolkits.axes_grid.axislines as axislines +import mpl_toolkits.axisartist as axisartist def setup_axes(fig, rect): - ax = axislines.Subplot(fig, rect) + ax = axisartist.Subplot(fig, rect) fig.add_axes(ax) ax.set_ylim(-0.1, 1.5) Modified: trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/demo_axis_direction.py =================================================================== --- trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/demo_axis_direction.py 2010-04-20 16:43:42 UTC (rev 8246) +++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/demo_axis_direction.py 2010-04-20 16:44:01 UTC (rev 8247) @@ -1,14 +1,14 @@ import numpy as np -import mpl_toolkits.axes_grid.angle_helper as angle_helper -import mpl_toolkits.axes_grid.grid_finder as grid_finder +import mpl_toolkits.axisartist.angle_helper as angle_helper +import mpl_toolkits.axisartist.grid_finder as grid_finder from matplotlib.projections import PolarAxes from matplotlib.transforms import Affine2D -import mpl_toolkits.axes_grid.axislines as axislines +import mpl_toolkits.axisartist as axisartist -from mpl_toolkits.axes_grid.grid_helper_curvelinear import GridHelperCurveLinear +from mpl_toolkits.axisartist.grid_helper_curvelinear import GridHelperCurveLinear def setup_axes(fig, rect): @@ -39,7 +39,7 @@ ) - ax1 = axislines.Subplot(fig, rect, grid_helper=grid_helper) + ax1 = axisartist.Subplot(fig, rect, grid_helper=grid_helper) ax1.axis[:].toggle(ticklabels=False) fig.add_subplot(ax1) Modified: trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/demo_ticklabel_alignment.py =================================================================== --- trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/demo_ticklabel_alignment.py 2010-04-20 16:43:42 UTC (rev 8246) +++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/demo_ticklabel_alignment.py 2010-04-20 16:44:01 UTC (rev 8247) @@ -1,12 +1,12 @@ import matplotlib.pyplot as plt -import mpl_toolkits.axes_grid.axislines as axislines +import mpl_toolkits.axisartist as axisartist def setup_axes(fig, rect): - ax = axislines.Subplot(fig, rect) + ax = axisartist.Subplot(fig, rect) fig.add_subplot(ax) ax.set_yticks([0.2, 0.8]) Modified: trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/parasite_simple.py =================================================================== --- trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/parasite_simple.py 2010-04-20 16:43:42 UTC (rev 8246) +++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/parasite_simple.py 2010-04-20 16:44:01 UTC (rev 8247) @@ -1,11 +1,8 @@ -from mpl_toolkits.axes_grid.parasite_axes import SubplotHost +from mpl_toolkits.axes_grid1 import host_subplot import matplotlib.pyplot as plt -fig = plt.figure(1) +host = host_subplot(111) -host = SubplotHost(fig, 111) -fig.add_subplot(host) - par = host.twinx() host.set_xlabel("Distance") @@ -15,10 +12,13 @@ p1, = host.plot([0, 1, 2], [0, 1, 2], label="Density") p2, = par.plot([0, 1, 2], [0, 3, 2], label="Temperature") -host.axis["left"].label.set_color(p1.get_color()) -par.axis["right"].label.set_color(p2.get_color()) +leg = plt.legend() -host.legend() +host.yaxis.get_label().set_color(p1.get_color()) +leg.texts[0].set_color(p1.get_color()) +par.yaxis.get_label().set_color(p2.get_color()) +leg.texts[1].set_color(p2.get_color()) + plt.show() Modified: trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_axis_direction01.py =================================================================== --- trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_axis_direction01.py 2010-04-20 16:43:42 UTC (rev 8246) +++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_axis_direction01.py 2010-04-20 16:44:01 UTC (rev 8247) @@ -1,8 +1,8 @@ import matplotlib.pyplot as plt -import mpl_toolkits.axes_grid.axislines as axislines +import mpl_toolkits.axisartist as axisartist fig = plt.figure(figsize=(4,2.5)) -ax1 = fig.add_subplot(axislines.Subplot(fig, "111")) +ax1 = fig.add_subplot(axisartist.Subplot(fig, "111")) fig.subplots_adjust(right=0.8) ax1.axis["left"].major_ticklabels.set_axis_direction("top") Modified: trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_axis_direction03.py =================================================================== --- trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_axis_direction03.py 2010-04-20 16:43:42 UTC (rev 8246) +++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_axis_direction03.py 2010-04-20 16:44:01 UTC (rev 8247) @@ -1,9 +1,9 @@ import matplotlib.pyplot as plt -import mpl_toolkits.axes_grid.axislines as axislines +import mpl_toolkits.axisartist as axisartist def setup_axes(fig, rect): - ax = axislines.Subplot(fig, rect) + ax = axisartist.Subplot(fig, rect) fig.add_subplot(ax) ax.set_yticks([0.2, 0.8]) Modified: trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_axis_pad.py =================================================================== --- trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_axis_pad.py 2010-04-20 16:43:42 UTC (rev 8246) +++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_axis_pad.py 2010-04-20 16:44:01 UTC (rev 8247) @@ -1,14 +1,14 @@ import numpy as np -import mpl_toolkits.axes_grid.angle_helper as angle_helper -import mpl_toolkits.axes_grid.grid_finder as grid_finder +import mpl_toolkits.axisartist.angle_helper as angle_helper +import mpl_toolkits.axisartist.grid_finder as grid_finder from matplotlib.projections import PolarAxes from matplotlib.transforms import Affine2D -import mpl_toolkits.axes_grid.axislines as axislines +import mpl_toolkits.axisartist as axisartist -from mpl_toolkits.axes_grid.grid_helper_curvelinear import GridHelperCurveLinear +from mpl_toolkits.axisartist.grid_helper_curvelinear import GridHelperCurveLinear def setup_axes(fig, rect): @@ -39,7 +39,7 @@ ) - ax1 = axislines.Subplot(fig, rect, grid_helper=grid_helper) + ax1 = axisartist.Subplot(fig, rect, grid_helper=grid_helper) #ax1.axis[:].toggle(all=False) ax1.axis[:].set_visible(False) Added: trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_axisartist1.py =================================================================== --- trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_axisartist1.py (rev 0) +++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_axisartist1.py 2010-04-20 16:44:01 UTC (rev 8247) @@ -0,0 +1,22 @@ +import matplotlib.pyplot as plt +import mpl_toolkits.axisartist as AA + +fig = plt.figure(1) +fig.subplots_adjust(right=0.85) +ax = AA.Subplot(fig, 1, 1, 1) +fig.add_subplot(ax) + +# make some axis invisible +ax.axis["bottom", "top", "right"].set_visible(False) + +# make an new axis along the first axis axis (x-axis) which pass +# throught y=0. +ax.axis["y=0"] = ax.new_floating_axis(nth_coord=0, value=0, + axis_direction="bottom") +ax.axis["y=0"].toggle(all=True) +ax.axis["y=0"].label.set_text("y = 0") + +ax.set_ylim(-2, 4) + +plt.show() + Added: trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_colorbar.py =================================================================== --- trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_colorbar.py (rev 0) +++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_colorbar.py 2010-04-20 16:44:01 UTC (rev 8247) @@ -0,0 +1,14 @@ +import matplotlib.pyplot as plt +from mpl_toolkits.axes_grid1 import make_axes_locatable +import numpy as np + +ax = plt.subplot(111) +im = ax.imshow(np.arange(100).reshape((10,10))) + +# create an axes on the right side of ax. The width of cax will be 5% +# of ax and the padding between cax and ax will be fixed at 0.05 inch. +divider = make_axes_locatable(ax) +cax = divider.append_axes("right", size="5%", pad=0.05) + +plt.colorbar(im, cax=cax) + Modified: trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_rgb.py =================================================================== --- trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_rgb.py 2010-04-20 16:43:42 UTC (rev 8246) +++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures/simple_rgb.py 2010-04-20 16:44:01 UTC (rev 8247) @@ -1,6 +1,6 @@ import matplotlib.pyplot as plt -from mpl_toolkits.axes_grid.axes_rgb import RGBAxes +from mpl_toolkits.axes_grid1.axes_rgb import RGBAxes def get_demo_image(): import numpy as np Modified: trunk/matplotlib/doc/mpl_toolkits/axes_grid/index.rst =================================================================== --- trunk/matplotlib/doc/mpl_toolkits/axes_grid/index.rst 2010-04-20 16:43:42 UTC (rev 8246) +++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/index.rst 2010-04-20 16:44:01 UTC (rev 8247) @@ -13,13 +13,30 @@ .. image:: ../../_static/demo_axes_grid.png +.. note:: + AxesGrid toolkit has been a part of matplotlib since v + 0.99. Originally, the toolkit had a single namespace of + *axes_grid*. In more recent version (since svn r8226), the toolkit + has divided into two separate namespace (*axes_grid1* and *axisartist*). + While *axes_grid* namespace is maintained for he backward compatibility, + use of *axes_grid1* and *axisartist* is recommended. +.. warning:: + *axes_grid* and *axisartist* (but not *axes_grid1*) uses + a custome Axes class (derived from the mpl's original Axes class). + As a sideeffect, some commands (mostly tick-related) do not work. + Use *axes_grid1* to avoid this, or see how things are different in + *axes_grid* and *axisartist* (LINK needed) + + + Documentation ============= .. toctree:: :maxdepth: 2 + users/overview.rst users/index.rst howtos/index.rst api/index.rst Copied: trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/axisartist.rst (from rev 8246, trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/axislines.rst) =================================================================== --- trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/axisartist.rst (rev 0) +++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/axisartist.rst 2010-04-20 16:44:01 UTC (rev 8247) @@ -0,0 +1,456 @@ +.. _axisartist-manual: + +==================== +AXISARTIST namespace +==================== + +The AxisArtist namesapce includes a derived Axes implementation. The +biggest difference is that the artists responsible to draw axis line, +ticks, ticklabel and axis labels are separated out from the mpl's Axis +class, which are much more than artists in the original mpl. This +change was strongly motivated to support curvlinear grid. Here are a +few things that mpl_tootlkits.axisartist.Axes is different from original +Axes from mpl. + +* Axis elements (axis line(spine), ticks, ticklabel and axis labels) + are drawn by a AxisArtist instance. Unlike Axis, left, right, top + and bottom axis are drawn by separate artists. And each of them may + have different tick location and different tick labels. + +* gridlines are drawn by a Gridlines instance. The change was + motivated that in curvelinear coordinate, a gridline may not cross + axis-lines (i.e., no associated ticks). In the original Axes class, + gridlines are tied to ticks. + +* ticklines can be rotated if necessary (i.e, along the gridlines) + +In summary, all these changes was to support + +* a curvelinear grid. +* a floating axis + +.. plot:: mpl_toolkits/axes_grid/examples/demo_floating_axis.py + + +*mpl_toolkits.axisartist.Axes* class defines a *axis* attribute, which +is a dictionary of AxisArtist instances. By default, the dictionary +has 4 AxisArtist instances, responsible for drawing of left, right, +bottom and top axis. + +xaxis and yaxis attributes are still available, however they are set +to not visible. As separate artists are used for rendering axis, some +axis-related method in mpl may have no effect. +In addition to AxisArtist instances, the mpl_toolkits.axisartist.Axes will +have *gridlines* attribute (Gridlines), which obviously draws grid +lines. + +In both AxisArtist and Gridlines, the calculation of tick and grid +location is delegated to an instance of GridHelper class. +mpl_toolkits.axisartist.Axes class uses GridHelperRectlinear as a grid +helper. The GridHelperRectlinear class is a wrapper around the *xaxis* +and *yaxis* of mpl's original Axes, and it was meant to work as the +way how mpl's original axes works. For example, tick location changes +using set_ticks method and etc. should work as expected. But change in +artist properties (e.g., color) will not work in general, although +some effort has been made so that some often-change attributes (color, +etc.) are respected. + + +AxisArtist +========== + +AxisArtist can be considered as a container artist with following +attributes which will draw ticks, labels, etc. + + * line + * major_ticks, major_ticklabels + * minor_ticks, minor_ticklabels + * offsetText + * label + + +line +---- + +Derived from Line2d class. Responsible for drawing a spinal(?) line. + +major_ticks, minor_ticks +------------------------ + +Derived from Line2d class. Note that ticks are markers. + + +major_ticklabels, minor_ticklabels +---------------------------------- + +Derived from Text. Note that it is not a list of Text artist, but a +single artist (similar to a collection). + +axislabel +--------- + +Derived from Text. + + +Default AxisArtists +------------------- + +By default, following for axis artists are defined.:: + + ax.axis["left"], ax.axis["bottom"], ax.axis["right"], ax.axis["top"] + +The ticklabels and axislabel of the top and the right axis are set to +not visible. + +For example, if you want to change the color attributes of +major_ticklabels of the bottom x-axis :: + + ax.axis["bottom"].major_ticklabels.set_color("b") + +Similarly, to make ticklabels invisible :: + + ax.axis["bottom"].major_ticklabels.set_visible(False) + +AxisAritst provides a helper method to control the visibility of ticks, ticklabels, and label. To make ticklabel invisible, :: + + ax.axis["bottom"].toggle(ticklabels=False) + +To make all of ticks, ticklabels, and (axis) label invisible :: + + ax.axis["bottom"].toggle(all=False) + +To turn all off but ticks on :: + + ax.axis["bottom"].toggle(all=False, ticks=True) + +To turn all on but (axis) label off :: + + ax.axis["bottom"].toggle(all=True, label=False)) + + +ax.axis's __getitem__ method can take multiple axis names. For +example, to turn ticklabels of "top" and "right" axis on, :: + + ax.axis["top","right"].toggle(ticklabels=True)) + +Note that 'ax.axis["top","right"]' returns a simple proxy object that translate above code to something like below. :: + + for n in ["top","right"]: + ax.axis[n].toggle(ticklabels=True)) + +So, any return values in the for loop are ignored. And you shoud not +use it anything more than a simple method. + +Like the list indexing ":" means all items, i.e., :: + + ax.axis[:].major_ticks.set_color("r") + +changes tick color in all axis. + + +HowTo +===== + +1. Changing tick locations and label. + + Same as the original mpl's axes.:: + + ax.set_xticks([1,2,3]) + +2. Changing axis properties like color, etc. + + Change the properties of appropriate artists. For example, to change + the color of the ticklabels:: + + ax.axis["left"].major_ticklabels.set_color("r") + +3. To change the attributes of multiple axis:: + + ax.axis["left","bottom"].major_ticklabels.set_color("r") + + or to change the attributes of all axis:: + + ax.axis[:].major_ticklabels.set_color("r") + +4. To change the tick size (length), you need to use + axis.major_ticks.set_ticksize method. To change the direction of + the ticks (ticks are in opposite direction of ticklabels by + default), use axis.major_ticks.set_tick_out method. + + To change the pad between ticks and ticklabels, use + axis.major_ticklabels.set_pad method. + + To change the pad between ticklabels and axis label, + axis.label.set_pad method. + + +Rotaion and Alignment of TickLabels +=================================== + +This is also quite different from the original mpl and can be +confusing. When you want to rotate the ticklabels, first consider +using "set_axis_direction" method. :: + + ax1.axis["left"].major_ticklabels.set_axis_direction("top") + ax1.axis["right"].label.set_axis_direction("left") + +.. plot:: mpl_toolkits/axes_grid/figures/simple_axis_direction01.py + +The parameter for set_axis_direction is one of ["left", "right", +"bottom", "top"]. + +You must understand some underlying concept of directions. + + 1. There is a reference direction which is defined as the direction + of the axis line with increasing coordinate. For example, the + reference direction of the left x-axis is from bottom to top. + + .. plot:: mpl_toolkits/axes_grid/figures/axis_direction_demo_step01.py + + The direction, text angle, and alignments of the ticks, ticklabels and + axis-label is determined with respect to the reference direction + + 2. *ticklabel_direction* is either the right-hand side (+) of the + reference direction or the left-hand side (-). + + .. plot:: mpl_toolkits/axes_grid/figures/axis_direction_demo_step02.py + + 3. same for the *label_direction* + + .. plot:: mpl_toolkits/axes_grid/figures/axis_direction_demo_step03.py + + 4. ticks are by default drawn toward the opposite direction of the ticklabels. + + 5. text rotation of ticklabels and label is determined in reference + to the *ticklabel_direction* or *label_direction*, + respectively. The rotation of ticklabels and label is anchored. + + .. plot:: mpl_toolkits/axes_grid/figures/axis_direction_demo_step04.py + + +On the other hand, there is a concept of "axis_direction". This is a +default setting of above properties for each, "bottom", "left", "top", +and "right" axis. + + ========== =========== ========= ========== ========= ========== + ? ? left bottom right top + ---------- ----------- --------- ---------- --------- ---------- + axislabel direction '-' '+' '+' '-' + axislabel rotation 180 0 0 180 + axislabel va center top center bottom + axislabel ha right center right center + ticklabel direction '-' '+' '+' '-' + ticklabels rotation 90 0 -90 180 + ticklabel ha right center right center + ticklabel va center baseline center baseline + ========== =========== ========= ========== ========= ========== + + +And, 'set_axis_direction("top")' means to adjust the text rotation +etc, for settings suitable for "top" axis. The concept of axis +direction can be more clear with curved axis. + +.. plot:: mpl_toolkits/axes_grid/figures/demo_axis_direction.py + +The axis_drection can be adjusted in the AxisArtist level, or in the +level of its child arists, i.e., ticks, ticklabels, and axis-label. :: + + ax1.axis["left"].set_axis_direction("top") + +changes axis_direction of all the associated artist with the "left" +axis, while :: + + ax1.axis["left"].major_ticklabels.set_axis_direction("top") + +changes the axis_direction of only the major_ticklabels. Note that +set_axis_direction in the AxisArtist level changes the +ticklabel_direction and label_direction, while chainging the +axis_direction of ticks, ticklabels, and axis-label does not affect +them. + + +If you want to make ticks outward and ticklabels inside the axes, +use invert_ticklabel_direction method. :: + + ax.axis[:].invert_ticklabel_direction() + +A related method is "set_tick_out". It makes ticks outward (as a +matter of fact, it makes ticks toward the opposite direction of the +default direction). :: + + ax.axis[:].major_ticks.set_tick_out(True) + +.. plot:: mpl_toolkits/axes_grid/figures/simple_axis_direction03.py + + +So, in summary, + + * AxisArtist's methods + * set_axis_direction : "left", "right", "bottom", or "top" + * set_ticklabel_direction : "+" or "-" + * set_axislabel_direction : "+" or "-" + * invert_ticklabel_direction + * Ticks' methods (major_ticks and minor_ticks) + * set_tick_out : True or False + * set_ticksize : size in points + * TickLabels' methods (major_ticklabels and minor_ticklabels) + * set_axis_direction : "left", "right", "bottom", or "top" + * set_rotation : angle with respect to the renference direction + * set_ha and set_va : see below + * AxisLabels' methods (label) + * set_axis_direction : "left", "right", "bottom", or "top" + * set_rotation : angle with respect to the renference direction + * set_ha and set_va + + + +Adjusting ticklabels alignment +------------------------------ + +Alignment of TickLabels are treated specially. See below + +.. plot:: mpl_toolkits/axes_grid/figures/demo_ticklabel_alignment.py + +Adjusting pad +-------------- + +To change the pad between ticks and ticklabels :: + + ax.axis["left"].major_ticklabels.set_pad(10) + +Or ticklabels and axis-label :: + + ax.axis["left"].label.set_pad(10) + + +.. plot:: mpl_toolkits/axes_grid/figures/simple_axis_pad.py + + +GridHelper +========== + +To actually define a curvelinear coordinate, you have to use your own +grid helper. A generalised version of grid helper class is supplied +and this class should suffice in most of cases. A user may provide +two functions which defines a transformation (and its inverse pair) +from the curved coordinate to (rectlinear) image coordinate. Note that +while ticks and grids are drawn for curved coordinate, the data +transform of the axes itself (ax.transData) is still rectlinear +(image) coordinate. :: + + + from mpl_toolkits.axisartist.grid_helper_curvelinear \ + import GridHelperCurveLinear + from mpl_toolkits.axisartist import Subplot + + # from curved coordinate to rectlinear coordinate. + def tr(x, y): + x, y = np.asarray(x), np.asarray(y) + return x, y-x + + # from rectlinear coordinate to curved coordinate. + def inv_tr(x,y): + x, y = np.asarray(x), np.asarray(y) + return x, y+x + + + grid_helper = GridHelperCurveLinear((tr, inv_tr)) + + ax1 = Subplot(fig, 1, 1, 1, grid_helper=grid_helper) + + fig.add_subplot(ax1) + + +You may use matplotlib's Transform instance instead (but a +inverse transformation must be defined). Often, coordinate range in a +curved coordinate system may have a limited range, or may have +cycles. In those cases, a more customized version of grid helper is +required. :: + + + import mpl_toolkits.axisartist.angle_helper as angle_helper + + # PolarAxes.PolarTransform takes radian. However, we want our coordinate + # system in degree + tr = Affine2D().scale(np.pi/180., 1.) + PolarAxes.PolarTransform() + + + # extreme finder : find a range of coordinate. + # 20, 20 : number of sampling points along x, y direction + # The first coordinate (longitude, but theta in polar) + # has a cycle of 360 degree. + # The second coordinate (latitude, but radius in polar) has a minimum of 0 + extreme_finder = angle_helper.ExtremeFinderCycle(20, 20, + lon_cycle = 360, + lat_cycle = None, + lon_minmax = None, + lat_minmax = (0, np.inf), + ) + + # Find a grid values appropriate for the coordinate (degree, + # minute, second). The argument is a approximate number of grids. + grid_locator1 = angle_helper.LocatorDMS(12) + + # And also uses an appropriate formatter. Note that,the + # acceptable Locator and Formatter class is a bit different than + # that of mpl's, and you cannot directly use mpl's Locator and + # Formatter here (but may be possible in the future). + tick_formatter1 = angle_helper.FormatterDMS() + + grid_helper = GridHelperCurveLinear(tr, + extreme_finder=extreme_finder, + grid_locator1=grid_locator1, + tick_formatter1=tick_formatter1 + ) + + +Again, the *transData* of the axes is still a rectlinear coordinate +(image coordinate). You may manually do conversion between two +coordinates, or you may use Parasite Axes for convenience.:: + + ax1 = SubplotHost(fig, 1, 2, 2, grid_helper=grid_helper) + + # A parasite axes with given transform + ax2 = ParasiteAxesAuxTrans(ax1, tr, "equal") + # note that ax2.transData == tr + ax1.transData + # Anthing you draw in ax2 will match the ticks and grids of ax1. + ax1.parasites.append(ax2) + + +.. plot:: mpl_toolkits/axes_grid/examples/demo_curvelinear_grid.py + + + +FloatingAxis +============ + +A floating axis is an axis one of whose data coordinate is fixed, i.e, +its location is not fixed in Axes coordinate but changes as axes data +limits changes. A floating axis can be created using +*new_floating_axis* method. However, it is your responsibility that +the resulting AxisArtist is properly added to the axes. A recommended +way is to add it as an item of Axes's axis attribute.:: + + # floating axis whose first (index starts from 0) coordinate + # (theta) is fixed at 60 + + ax1.axis["lat"] = axis = ax1.new_floating_axis(0, 60) + axis.label.set_text(r"$\theta = 60^{\circ}$") + axis.label.set_visible(True) + + +See the first example of this page. + +Current Limitations and TODO's +============================== + +The code need more refinement. Here is a incomplete list of issues and TODO's + +* No easy way to support a user customized tick location (for + curvelinear grid). A new Locator class needs to be created. + +* FloatingAxis may have coordinate limits, e.g., a floating axis of x + = 0, but y only spans from 0 to 1. + +* The location of axislabel of FloatingAxis needs to be optionally + given as a coordinate value. ex, a floating axis of x=0 with label at y=1 Deleted: trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/axislines.rst =================================================================== --- trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/axislines.rst 2010-04-20 16:43:42 UTC (rev 8246) +++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/axislines.rst 2010-04-20 16:44:01 UTC (rev 8247) @@ -1,456 +0,0 @@ -.. _axislines-manual: - -========= -Axislines -========= - -Axislines includes a derived Axes implementation. The -biggest difference is that the artists responsible to draw axis line, -ticks, ticklabel and axis labels are separated out from the mpl's Axis -class, which are much more than artists in the original -mpl. This change was strongly motivated to support curvlinear -grid. Here are a few things that axes_grid.axislines.Axes is different -from original Axes from mpl. - -* Axis elements (axis line(spine), ticks, ticklabel and axis labels) - are drawn by a AxisArtist instance. Unlike Axis, left, right, top - and bottom axis are drawn by separate artists. And each of them may - have different tick location and different tick labels. - -* gridlines are drawn by a Gridlines instance. The change was - motivated that in curvelinear coordinate, a gridline may not cross - axislines (i.e., no associated ticks). In the original Axes class, - gridlines are tied to ticks. - -* ticklines can be rotated if necessary (i.e, along the gridlines) - -In summary, all these changes was to support - -* a curvelinear grid. -* a floating axis - -.. plot:: mpl_toolkits/axes_grid/examples/demo_floating_axis.py - - -*axes_grid.axislines.Axes* defines a *axis* attribute, which is a -dictionary of AxisArtist instances. By default, the dictionary has 4 -AxisArtist instances, responsible for drawing of left, right, bottom -and top axis. - -xaxis and yaxis attributes are still available, however they are set -to not visible. As separate artists are used for rendering axis, some -axis-related method in mpl may have no effect. -In addition to AxisArtist instances, the axes_grid.axislines.Axes will -have *gridlines* attribute (Gridlines), which obviously draws grid -lines. - -In both AxisArtist and Gridlines, the calculation of tick and grid -location is delegated to an instance of GridHelper class. -axes_grid.axislines.Axes class uses GridHelperRectlinear as a grid -helper. The GridHelperRectlinear class is a wrapper around the *xaxis* -and *yaxis* of mpl's original Axes, and it was meant to work as the -way how mpl's original axes works. For example, tick location changes -using set_ticks method and etc. should work as expected. But change in -artist properties (e.g., color) will not work in general, although -some effort has been made so that some often-change attributes (color, -etc.) are respected. - - -AxisArtist -========== - -AxisArtist can be considered as a container artist with following -attributes which will draw ticks, labels, etc. - - * line - * major_ticks, major_ticklabels - * minor_ticks, minor_ticklabels - * offsetText - * label - - -line ----- - -Derived from Line2d class. Responsible for drawing a spinal(?) line. - -major_ticks, minor_ticks ------------------------- - -Derived from Line2d class. Note that ticks are markers. - - -major_ticklabels, minor_ticklabels ----------------------------------- - -Derived from Text. Note that it is not a list of Text artist, but a -single artist (similar to a collection). - -axislabel ---------- - -Derived from Text. - - -Default AxisArtists -------------------- - -By default, following for axis artists are defined.:: - - ax.axis["left"], ax.axis["bottom"], ax.axis["right"], ax.axis["top"] - -The ticklabels and axislabel of the top and the right axis are set to -not visible. - -For example, if you want to change the color attributes of -major_ticklabels of the bottom x-axis :: - - ax.axis["bottom"].major_ticklabels.set_color("b") - -Similarly, to make ticklabels invisible :: - - ax.axis["bottom"].major_ticklabels.set_visible(False) - -AxisAritst provides a helper method to control the visibility of ticks, ticklabels, and label. To make ticklabel invisible, :: - - ax.axis["bottom"].toggle(ticklabels=False) - -To make all of ticks, ticklabels, and (axis) label invisible :: - - ax.axis["bottom"].toggle(all=False) - -To turn all off but ticks on :: - - ax.axis["bottom"].toggle(all=False, ticks=True) - -To turn all on but (axis) label off :: - - ax.axis["bottom"].toggle(all=True, label=False)) - - -ax.axis's __getitem__ method can take multiple axis names. For -example, to turn ticklabels of "top" and "right" axis on, :: - - ax.axis["top","right"].toggle(ticklabels=True)) - -Note that 'ax.axis["top","right"]' returns a simple proxy object that translate above code to something like below. :: - - for n in ["top","right"]: - ax.axis[n].toggle(ticklabels=True)) - -So, any return values in the for loop are ignored. And you shoud not -use it anything more than a simple method. - -Like the list indexing ":" means all items, i.e., :: - - ax.axis[:].major_ticks.set_color("r") - -changes tick color in all axis. - - -HowTo -===== - -1. Changing tick locations and label. - - Same as the original mpl's axes.:: - - ax.set_xticks([1,2,3]) - -2. Changing axis properties like color, etc. - - Change the properties of appropriate artists. For example, to change - the color of the ticklabels:: - - ax.axis["left"].major_ticklabels.set_color("r") - -3. To change the attributes of multiple axis:: - - ax.axis["left","bottom"].major_ticklabels.set_color("r") - - or to change the attributes of all axis:: - - ax.axis[:].major_ticklabels.set_color("r") - -4. To change the tick size (length), you need to use - axis.major_ticks.set_ticksize method. To change the direction of - the ticks (ticks are in opposite direction of ticklabels by - default), use axis.major_ticks.set_tick_out method. - - To change the pad between ticks and ticklabels, use - axis.major_ticklabels.set_pad method. - - To change the pad between ticklabels and axis label, - axis.label.set_pad method. - - -Rotaion and Alignment of TickLabels -=================================== - -This is also quite different from the original mpl and can be -confusing. When you want to rotate the ticklabels, first consider -using "set_axis_direction" method. :: - - ax1.axis["left"].major_ticklabels.set_axis_direction("top") - ax1.axis["right"].label.set_axis_direction("left") - -.. plot:: mpl_toolkits/axes_grid/figures/simple_axis_direction01.py - -The parameter for set_axis_direction is one of ["left", "right", -"bottom", "top"]. - -You must understand some underlying concept of directions. - - 1. There is a reference direction which is defined as the direction - of the axis line with increasing coordinate. For example, the - reference direction of the left x-axis is from bottom to top. - - .. plot:: mpl_toolkits/axes_grid/figures/axis_direction_demo_step01.py - - The direction, text angle, and alignments of the ticks, ticklabels and - axis-label is determined width respect to the reference direction - - 2. *ticklabel_direction* is either the right-hand side (+) of the - reference direction or the left-hand side (-). - - .. plot:: mpl_toolkits/axes_grid/figures/axis_direction_demo_step02.py - - 3. same for the *label_direction* - - .. plot:: mpl_toolkits/axes_grid/figures/axis_direction_demo_step03.py - - 4. ticks are by default drawn toward the opposite direction of the ticklabels. - - 5. text rotation of ticklabels and label is determined in reference - to the *ticklabel_direction* or *label_direction*, - respectively. The rotation of ticklabels and tlabel is anchored. - - .. plot:: mpl_toolkits/axes_grid/figures/axis_direction_demo_step04.py - - -On the other hand, there is a concept of "axis_direction". This is a -default setting of above properties for each, "bottom", "left", "top", -and "right" axis. - - ========== =========== ========= ========== ========= ========== - ? ? left bottom right top - ---------- ----------- --------- ---------- --------- ---------- - axislabel direction '-' '+' '+' '-' - axislabel rotation 180 0 0 180 - axislabel va center top center bottom - axislabel ha right center right center - ticklabel direction '-' '+' '+' '-' - ticklabels rotation 90 0 -90 180 - ticklabel ha right center right center - ticklabel va center baseline center baseline - ========== =========== ========= ========== ========= ========== - - -And, 'set_axis_direction("top")' means to adjust the text rotation -etc, for settings suitable for "top" axis. The concept of axis -direction can be more clear with curved axis. - -.. plot:: mpl_toolkits/axes_grid/figures/demo_axis_direction.py - -The axis_drection can be adjusted in the AxisArtist level, or in the -level of its child arists, i.e., ticks, ticklabels, and axis-label. :: - - ax1.axis["left"].set_axis_direction("top") - -changes axis_direction of all the associated artist with the "left" -axis, while :: - - ax1.axis["left"].major_ticklabels.set_axis_direction("top") - -changes the axis_direction of only the major_ticklabels. Note that -set_axis_direction in the AxisArtist level changes the -ticklabel_direction and label_direction, while chainging the -axis_direction of ticks, ticklabels, and axis-label does not affect -them. - - -If you want to make ticks outward and ticklabels inside the axes, -use invert_ticklabel_direction method. :: - - ax.axis[:].invert_ticklabel_direction() - -A related method is "set_tick_out". It makes ticks outward (as a -matter of fact, it makes ticks toward the opposite direction of the -default direction). :: - - ax.axis[:].major_ticks.set_tick_out(True) - -.. plot:: mpl_toolkits/axes_grid/figures/simple_axis_direction03.py - - -So, in summary, - - * AxisArtist's methods - * set_axis_direction : "left", "right", "bottom", or "top" - * set_ticklabel_direction : "+" or "-" - * set_axislabel_direction : "+" or "-" - * invert_ticklabel_direction - * Ticks' methods (major_ticks and minor_ticks) - * set_tick_out : True or False - * set_ticksize : size in points - * TickLabels' methods (major_ticklabels and minor_ticklabels) - * set_axis_direction : "left", "right", "bottom", or "top" - * set_rotation : angle with respect to the renference direction - * set_ha and set_va : see below - * AxisLabels' methods (label) - * set_axis_direction : "left", "right", "bottom", or "top" - * set_rotation : angle with respect to the renference direction - * set_ha and set_va - - - -Adjusting ticklabels alignment ------------------------------- - -Alignment of TickLabels are treated specially. See below - -.. plot:: mpl_toolkits/axes_grid/figures/demo_ticklabel_alignment.py - -Adjusting pad --------------- - -To change the pad between ticks and ticklabels :: - - ax.axis["left"].major_ticklabels.set_pad(10) - -Or ticklabels and axis-label :: - - ax.axis["left"].label.set_pad(10) - - -.. plot:: mpl_toolkits/axes_grid/figures/simple_axis_pad.py - - -GridHelper -========== - -To actually define a curvelinear coordinate, you have to use your own -grid helper. A generalised version of grid helper class is supplied -and this class should be suffice in most of cases. A user may provide -two functions which defines a transformation (and its inverse pair) -from the curved coordinate to (rectlinear) image coordinate. Note that -while ticks and grids are drawn for curved coordinate, the data -transform of the axes itself (ax.transData) is still rectlinear -(image) coordinate. :: - - - from mpl_toolkits.axes_grid.grid_helper_curvelinear \ - import GridHelperCurveLinear - from mpl_toolkits.axes_grid.axislines import Subplot - - # from curved coordinate to rectlinear coordinate. - def tr(x, y): - x, y = np.asarray(x), np.asarray(y) - return x, y-x - - # from rectlinear coordinate to curved coordinate. - def inv_tr(x,y): - x, y = np.asarray(x), np.asarray(y) - return x, y+x - - - grid_helper = GridHelperCurveLinear((tr, inv_tr)) - - ax1 = Subplot(fig, 1, 1, 1, grid_helper=grid_helper) - - fig.add_subplot(ax1) - - -You may use matplotlib's Transform instance instead (but a -inverse transformation must be defined). Often, coordinate range in a -curved coordinate system may have a limited range, or may have -cycles. In those cases, a more customized version of grid helper is -required. :: - - - import mpl_toolkits.axes_grid.angle_helper as angle_helper - - # PolarAxes.PolarTransform takes radian. However, we want our coordinate - # system in degree - tr = Affine2D().scale(np.pi/180., 1.) + PolarAxes.PolarTransform() - - - # extreme finder : find a range of coordinate. - # 20, 20 : number of sampling points along x, y direction - # The first coordinate (longitude, but theta in polar) - # has a cycle of 360 degree. - # The second coordinate (latitude, but radius in polar) has a minimum of 0 - extreme_finder = angle_helper.ExtremeFinderCycle(20, 20, - lon_cycle = 360, - lat_cycle = None, - lon_minmax = None, - lat_minmax = (0, np.inf), - ) - - # Find a grid values appropriate for the coordinate (degree, - # minute, second). The argument is a approximate number of grids. - grid_locator1 = angle_helper.LocatorDMS(12) - - # And also uses an appropriate formatter. Note that,the - # acceptable Locator and Formatter class is a bit different than - # that of mpl's, and you cannot directly use mpl's Locator and - # Formatter here (but may be possible in the future). - tick_formatter1 = angle_helper.FormatterDMS() - - grid_helper = GridHelperCurveLinear(tr, - extreme_finder=extreme_finder, - grid_locator1=grid_locator1, - tick_formatter1=tick_formatter1 - ) - - -Again, the *transData* of the axes is still a rectlinear coordinate -(image coordinate). You may manually do conversion between two -coordinates, or you may use Parasite Axes for convenience.:: - - ax1 = SubplotHost(fig, 1, 2, 2, grid_helper=grid_helper) - - # A parasite axes with given transform - ax2 = ParasiteAxesAuxTrans(ax1, tr, "equal") - # note that ax2.transData == tr + ax1.transData - # Anthing you draw in ax2 will match the ticks and grids of ax1. - ax1.parasites.append(ax2) - - -.. plot:: mpl_toolkits/axes_grid/examples/demo_curvelinear_grid.py - - - -FloatingAxis -============ - -A floating axis is an axis one of whose data coordinate is fixed, i.e, -its location is not fixed in Axes coordinate but changes as axes data -limits changes. A floating axis can be created using -*new_floating_axis* method. However, it is your responsibility that -the resulting AxisArtist is properly added to the axes. A recommended -way is to add it as an item of Axes's axis attribute.:: - - # floating axis whose first (index starts from 0) coordinate - # (theta) is fixed at 60 - - ax1.axis["lat"] = axis = ax1.new_floating_axis(0, 60) - axis.label.set_text(r"$\theta = 60^{\circ}$") - axis.label.set_visible(True) - - -See the first example of this page. - -Current Limitations and TODO's -============================== - -The code need more refinement. Here is a incomplete list of issues and TODO's - -* No easy way to support a user customized tick location (for - curvelinear grid). A new Locator class needs to be created. - -* FloatingAxis may have coordinate limits, e.g., a floating axis of x - = 0, but y only spans from 0 to 1. - -* The location of axislabel of FloatingAxis needs to be optionally - given as a coordinate value. ex, a floating axis of x=0 with label at y=1 Modified: trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/index.rst =================================================================== --- trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/index.rst 2010-04-20 16:43:42 UTC (rev 8246) +++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/index.rst 2010-04-20 16:44:01 UTC (rev 8247) @@ -9,6 +9,6 @@ .. toctree:: - overview.rst axes_divider.rst - axislines.rst + axisartist.rst + Modified: trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/overview.rst =================================================================== --- trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/overview.rst 2010-04-20 16:43:42 UTC (rev 8246) +++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/overview.rst 2010-04-20 16:44:01 UTC (rev 8247) @@ -1,7 +1,10 @@ -======== -Overview -======== +============================ +Overview of AxesGrid toolkit +============================ +What is AxesGrid toolkit? +========================= + The matplotlib AxesGrid toolkit is a collection of helper classes, mainly to ease displaying (multiple) images in matplotlib. @@ -9,30 +12,65 @@ :depth: 1 :local: -`AxesGrid`_, `RGB Axes`_ and `AxesDivider`_ are helper classes that -deals with adjusting the location of (multiple) Axes, mainly for -displaying images. It provides a framework to adjust the position of -multiple axes at the drawing time. `ParasiteAxes`_ provides twinx(or -twiny)-like features so that you can plot different data (e.g., -different y-scale) in a same Axes. `AxisLine`_ is a custom Axes -class. Unlike default Axes in matpotlib, each axis (left, right, top -and bottom) is associated with a separate artist (which is resposible -to draw axis-line, ticks, ticklabels, label). `AnchoredArtists`_ +.. note:: + AxesGrid toolkit has been a part of matplotlib since v + 0.99. Originally, the toolkit had a single namespace of + *axes_grid*. In more recent version (since svn r8226), the toolkit + has divided into two separate namespace (*axes_grid1* and *axisartist*). + While *axes_grid* namespace is maintained for he backward compatibility, + use of *axes_grid1* and *axisartist* is recommended. + +.. warning:: + *axes_grid* and *axisartist* (but not *axes_grid1*) uses + a custome Axes class (derived from the mpl's original Axes class). + As a sideeffect, some commands (mostly tick-related) do not work. + Use *axes_grid1* to avoid this, or see how things are different in + *axes_grid* and *axisartist* (LINK needed) + + +AxesGrid toolkit has two namespaces (*axes_grid1* and *axisartist*). +*axisartist* contains custome Axes class that is meant to support for +curvilinear grids (e.g., the world coordinate system in astronomy). +Unlike mpl's original Axes class which uses Axes.xaxis and Axes.yaxis +to draw ticks, ticklines and etc., Axes in axisartist uses special +artist (AxisArtist) which can handle tick, ticklines and etc. for +curved coordinate systems. + +.. plot:: mpl_toolkits/axes_grid/examples/demo_floating_axis.py + +Since it uses a special artists, some mpl commands that work on +Axes.xaxis and Axes.yaxis may not work. See LINK for more detail. + + +*axes_grid1* is a collection of helper classes to ease displaying +(multiple) images with matplotlib. In matplotlib, the axes location +(and size) is specified in the normalized figure coordinates, which +may not be ideal for displaying images that needs to have a given +aspect ratio. For example, it helps you to have a colobar whose +height always matches that of the image. `AxesGrid`_, `RGB Axes`_ and +`AxesDivider`_ are helper classes that deals with adjusting the +location of (multiple) Axes. They provides a framework to adjust the +position of multiple axes at the drawing time. `ParasiteAxes`_ +provides twinx(or twiny)-like features so that you can plot different +data (e.g., different y-scale) in a same Axes. `AnchoredArtists`_ includes custom artists which are placed at some anchored position, like the legend. +.. plot:: mpl_toolkits/axes_grid/examples/demo_axes_grid.py +AXES_GRID1 +========== -AxesGrid -======== +ImageGrid +--------- A class that creates a grid of Axes. In matplotlib, the axes location (and size) is specified in the normalized figure coordinates. This may not be ideal for images that needs to be displayed with a given aspect ratio. For example, displaying images of a same size with some fixed -padding between them cannot be easily done in matplotlib. AxesGrid is +padding between them cannot be easily done in matplotlib. ImageGrid is used in such case. .. plot:: mpl_toolkits/axes_grid/examples/simple_axesgrid.py @@ -60,7 +98,7 @@ -When initialized, AxesGrid creates given number (*ngrids* or *ncols* * +When initialized, ImageGrid creates given number (*ngrids* or *ncols* * *nrows* if *ngrids* is None) of Axes instances. A sequence-like interface is provided to access the individual Axes instances (e.g., grid[0] is the first Axes in the grid. See below for the order of @@ -140,32 +178,10 @@ .. plot:: mpl_toolkits/axes_grid/examples/demo_axes_grid.py -RGB Axes -======== - -RGBAxes is a helper clase to conveniently show RGB composite -images. Like AxesGrid, the location of axes are adjusted so that the -area occupied by them fits in a given rectangle. Also, the xaxis and -yaxis of each axes are shared. :: - - from mpl_toolkits.axes_grid.axes_rgb import RGBAxes - - fig = plt.figure(1) - ax = RGBAxes(fig, [0.1, 0.1, 0.8, 0.8]) - - r, g, b = get_rgb() # r,g,b are 2-d images - ax.imshow_rgb(r, g, b, - origin="lower", interpolation="nearest") - - -.. plot:: mpl_toolkits/axes_grid/figures/simple_rgb.py - - - AxesDivider -=========== +----------- -Behind the scene, the AxesGrid class and the RGBAxes class utilize the +Behind the scene, the ImageGrid class and the RGBAxes class utilize the AxesDivider class, whose role is to calculate the location of the axes at drawing time. While a more about the AxesDivider is (will be) explained in (yet to be written) AxesDividerGuide, direct use of the @@ -181,44 +197,45 @@ *make_axes_locatable* returns an isntance of the AxesLocator class, -derived from the Locator. It has *new_vertical*, and *new_horizontal* -methods. The *new_vertical* (*new_horizontal*) creates a new axes on -the upper (right) side of the original axes. +derived from the Locator. It provides *append_axes* method that +creates a new axes on the given side of ("top", "right", "bottom" and +"left") of the original axes. -scatter_hist.py with AxesDivider --------------------------------- -The "scatter_hist.py" example in mpl can be rewritten using -*make_axes_locatable*. :: +colorbar whose height (or width) in sync with the master axes +------------------------------------------------------------- - from mpl_toolkits.axes_grid import make_axes_locatable +.. plot:: mpl_toolkits/axes_grid/figures/simple_colorbar.py + :include-source: - axScatter = subplot(111) - divider = make_axes_locatable(axScatter) - # create new axes on the right and on the top of the current axes - # The first argument of the new_vertical(new_horizontal) method is - # the height (width) of the axes to be created in inches. - axHistx = divider.new_vertical(1.2, pad=0.1, sharex=axScatter) - axHisty = divider.new_horizontal(1.2, pad=0.1, sharey=axScatter) - fig.add_axes(axHistx) - fig.add_axes(axHisty) +scatter_hist.py with AxesDivider +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - # the scatter plot: +The "scatter_hist.py" example in mpl can be rewritten using +*make_axes_locatable*. :: + + axScatter = subplot(111) axScatter.scatter(x, y) axScatter.set_aspect(1.) + # create new axes on the right and on the top of the current axes. + divider = make_axes_locatable(axScatter) + axHistx = divider.append_axes("top", size=1.2, pad=0.1, sharex=axScatter) + axHisty = divider.append_axes("right", size=1.2, pad=0.1, sharey=axScatter) + + # the scatter plot: # histograms bins = np.arange(-lim, lim + binwidth, binwidth) axHistx.hist(x, bins=bins) axHisty.hist(y, bins=bins, orientation='horizontal') + See the full source code below. - .. plot:: mpl_toolkits/axes_grid/examples/scatter_hist.py @@ -229,86 +246,42 @@ ParasiteAxes -============ +------------ -The ParasiteAxes is a axes whose location is identical to its host +The ParasiteAxes is an axes whose location is identical to its host axes. The location is adjusted in the drawing time, thus it works even -if the host change its location (e.g., images). It provides *twinx*, -*twiny* (similar to twinx and twiny in the matplotlib). Also it -provides *twin*, which takes an arbitraty tranfromation that maps -between the data coordinates of the host and the parasite axes. -Artists in each axes are mergred and drawn acrroding to their zorder. -It also modifies some behavior of the axes. For example, color cycle -for plot lines are shared between host and parasites. Also, the legend -command in host, creates a legend that includes lines in the parasite -axes. +if the host change its location (e.g., images). +In most cases, you first create a host axes, which provides a few +method that can be used to create parasite axes. They are *twinx*, +*twiny* (which are similar to twinx and twiny in the matplotlib) and +*twin*. *twin* takes an arbitraty tranfromation that maps between the +data coordinates of the host axes and the parasite axes. *draw* +method of the parasite axes are never called. Instead, host axes +collects artists in parasite axes and draw them as if they belong to +the host axes, i.e., artists in parasite axes are merged to those of +the host axes and then drawn according to their zorder. The host and +parasite axes modifies some of the axes behavior. For example, color +cycle for plot lines are shared between host and parasites. Also, the +legend command in host, creates a legend that includes lines in the +parasite axes. To create a host axes, you may use *host_suplot* or +*host_axes* command. + + Example 1. twinx ----------------- +~~~~~~~~~~~~~~~~ .. plot:: mpl_toolkits/axes_grid/figures/parasite_simple.py :include-source: Example 2. twin ---------------- +~~~~~~~~~~~~~~~ -A more sophiscated example using twin. Note that if you change the -x-limit in the host axes, the x-limit of the parasite axes will change -accordingly. +*twin* without a transform argument treat the parasite axes to have a +same data transform as the host. This can be useful when you want the +top(or right)-axis to have different tick-locations, tick-labels, or +tick-formatter for bottom(or left)-axis. :: - -.. plot:: mpl_toolkits/axes_grid/examples/parasite_simple2.py - - - -AxisLine -======== - -AxisLine is a custom (and very experimenta) Axes class, where each -axis (left, right, top and bottom) have a separate artist associated -(which is resposible to draw axis-line, ticks, ticklabels, label). -Also, you can create your own axis, which can pass through a fixed -position in the axes coordinate, or a fixed position in the data -coordinate (i.e., the axis floats around when viewlimit changes). - -Most of the class in this toolkit is based on this class. And it has -not been tested extensibly. You may go back to the original mpl -behanvior, by :: - - ax.toggle_axisline(False) - -The axes class, by default, provides 4 artists which are responsible -to draw axis in "left","right","bottom" and "top". They are accessed -as ax.axis["left"], ax.axis["right"], and so on, i.e., ax.axis is a -dictionary that contains artists (note that ax.axis is still a -callable methods and it behaves as an original Axes.axis method in -mpl). - -For example, you can hide right, and top axis by :: - - ax.axis["right"].set_visible(False) - ax.axis["top"].set_visible(False) - - -.. plot:: mpl_toolkits/axes_grid/figures/simple_axisline3.py - - -SubplotZero gives you two more additional (floating?) axis of x=0 and -y=0 (in data coordinate) - -.. plot:: mpl_toolkits/axes_grid/figures/simple_axisline2.py - :include-source: - - -Axisline with ParasiteAxes --------------------------- - -Most of axes class in the axes_grid toolkit, including ParasiteAxes, -is based on the Axisline axes. The combination of the two can be -useful in some case. For example, you can have different tick-location, -tick-label, or tick-formatter for bottom and top (or left and right) -axis. :: - ax2 = ax.twin() # now, ax2 is responsible for "top" axis and "right" axis ax2.set_xticks([0., .5*np.pi, np.pi, 1.5*np.pi, 2*np.pi]) ax2.set_xticklabels(["0", r"$\frac{1}{2}\pi$", @@ -318,23 +291,17 @@ .. plot:: mpl_toolkits/axes_grid/examples/simple_axisline4.py -AxisLine Axes lets you create a custom axis, :: - # make new (right-side) yaxis, but w... [truncated message content] |