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