|
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] |