Browse files

Shared colorbar axes working.

  • Loading branch information...
pelson committed Jun 15, 2012
1 parent 6b442b8 commit be049b26cfa73e7c69baa73d681ea2a7f44b61b6
Showing with 93 additions and 22 deletions.
  1. +86 −13 lib/matplotlib/
  2. +2 −2 lib/matplotlib/
  3. +5 −7 lib/matplotlib/
@@ -35,6 +35,7 @@
import matplotlib.patches as mpatches
import matplotlib.path as mpath
import matplotlib.ticker as ticker
import matplotlib.transforms as mtrans
from matplotlib import docstring
@@ -52,7 +53,8 @@
*anchor* (0.0, 0.5) if vertical; (0.5, 1.0) if horizontal;
the anchor point of the colorbar axes
*panchor* (1.0, 0.5) if vertical; (0.5, 0.0) if horizontal;
the anchor point of the colorbar parent axes
the anchor point of the colorbar parent axes. If
False, the parent axes' anchor will be unchanged
============= ====================================================
@@ -149,8 +151,9 @@
None | axes object into which the colorbar will be drawn
None | parent axes object from which space for a new
colorbar axes will be stolen
None | parent axes object(s) from which space for a new
colorbar axes will be stolen. If a list of axes is given
they will be resized to make room for the colorbar axes.
False | If *cax* is None, a new *cax* is created as an instance of
Axes. If *ax* is an instance of Subplot and *use_gridspec* is True,
@@ -255,6 +258,7 @@ def __init__(self, ax, cmap=None,
spacing='uniform', # uniform or proportional
@@ -278,6 +282,7 @@ def __init__(self, ax, cmap=None,
self._inside = self._slice_dict[extend]
self.spacing = spacing
self.orientation = orientation
self.location = location
self.drawedges = drawedges
self.filled = filled
self.extendfrac = extendfrac
@@ -336,11 +341,15 @@ def config_axis(self):
ax =
if self.orientation == 'vertical':
# location is either one of 'bottom' or 'top'
# location is either one of 'left' or 'right'
# XXX This wasn't enabled before...
@@ -835,11 +844,10 @@ class Colorbar(ColorbarBase):
def __init__(self, ax, mappable, **kw):
mappable.autoscale_None() # Ensure mappable.norm.vmin, vmax
# are set when colorbar is called,
# even if mappable.draw has not yet
# been called. This will not change
# vmin, vmax if they are already set.
# Ensure the given mappable's norm has appropriate vmin and vmax set
# even if mappable.draw has not yet been called.
self.mappable = mappable
kw['cmap'] = mappable.cmap
kw['norm'] = mappable.norm
@@ -948,7 +956,7 @@ def update_bruteforce(self, mappable):
def make_axes(parent, **kw):
def make_axes_orig(parent, **kw):
Resize and reposition a parent axes, and return a child
axes suitable for a colorbar::
@@ -994,6 +1002,71 @@ def make_axes(parent, **kw):
return cax, kw
def make_axes(parent, location=None, orientation=None, fraction=0.15, shrink=1.0, aspect=20, **kw):
locations = ["left", "right", "top", "bottom"]
if orientation is not None and location is not None:
raise TypeError('position and orientation are mutually exclusive. Consider ' \
'setting the position to any of %s' % ','.join(locations))
# must pump out an orientation for colorbar creation
if location in ['left', 'right']:
kw['orientation'] = 'vertical'
kw['location'] = location
anchor = kw.pop('anchor', (0.0, 0.5))
# define the parent's anchor to be next to the new colorbar axes
panchor = kw.pop('panchor', (1.0, 0.5))
kw['orientation'] = 'horizontal'
kw['location'] = location
anchor = kw.pop('anchor', (0.5, 1.0))
# define the parent's anchor to be next to the new colorbar axes
panchor = kw.pop('panchor', (0.5, 0.0))
# define padding between colorbar axes and parent axes in axes coordinates.
# For best outcomes, pad is best at 0.15 when location is "bottom"
if location == 'bottom':
pad = kw.pop('pad', 0.0)
pad = kw.pop('pad', 0.00)
if isinstance(parent, list):
parents_bbox = mtrans.Bbox.union([ax.get_position(original=True).frozen() \
for ax in parent])
pb = parents_bbox
if location in ('left', 'right'):
if location == 'left':
pbcb, _, pb1 = pb.splitx(1 - fraction, fraction + pad)
pb1, _, pbcb = pb.splitx(1 - fraction - pad, 1 - fraction)
pbcb = pbcb.shrunk(1.0, shrink).anchored('C', pbcb)
if location == 'top':
pb1, _, pbcb = pb.splity(1 - fraction - pad, fraction)
pbcb, _, pb1 = pb.splity(fraction, fraction + pad)
pbcb = pbcb.shrunk(shrink, 1.0).anchored('C', pbcb)
# define the aspect ratio in terms of y's per x rather than x's per y
aspect = 1.0/aspect
shrinking_trans = mtrans.BboxTransform(parents_bbox, pb1)
for ax in parent:
new_posn = shrinking_trans.transform(ax.get_position())
new_posn = mtrans.Bbox(new_posn)
if panchor is not False:
# XXX test all axes must be on the same figure...
fig = parent[0].get_figure()
cax = fig.add_axes(pbcb)
cax.set_aspect(aspect, anchor=anchor, adjustable='box')
return cax, kw
def make_axes_gridspec(parent, **kw):
@@ -1018,7 +1091,7 @@ def make_axes_gridspec(parent, **kw):
Keyword arguments may include the following (with defaults):
'vertical' or 'horizontal'
'vertical' or 'horizontal'
@@ -1418,7 +1418,7 @@ def savefig(self, *args, **kwargs):
def colorbar(self, mappable, cax=None, ax=None, **kw):
def colorbar(self, mappable, cax=None, ax=None, use_gridspec=False, **kw):
Create a colorbar for a ScalarMappable instance, *mappable*.
@@ -1427,7 +1427,7 @@ def colorbar(self, mappable, cax=None, ax=None, **kw):
if ax is None:
ax = self.gca()
use_gridspec = kw.pop("use_gridspec", True)
if cax is None:
if use_gridspec and isinstance(ax, SubplotBase):
cax, kw = cbar.make_axes_gridspec(ax, **kw)
@@ -21,11 +21,13 @@
import warnings
import matplotlib
import matplotlib.colorbar
from matplotlib import _pylab_helpers, interactive
from matplotlib.cbook import dedent, silent_list, is_string_like, is_numlike
from matplotlib import docstring
from matplotlib.figure import Figure, figaspect
from matplotlib.backend_bases import FigureCanvasBase
from matplotlib.figure import Figure, figaspect
from matplotlib.gridspec import GridSpec
from matplotlib.image import imread as _imread
from matplotlib.image import imsave as _imsave
from matplotlib import rcParams, rcParamsDefault, get_backend
@@ -207,16 +209,16 @@ def rc_context(rc=None, fname=None):
return matplotlib.rc_context(rc, fname)
def rcdefaults():
# The current "image" (ScalarMappable) is retrieved or set
# only via the pyplot interface using the following two
# functions:
def gci():
Get the current colorable artist. Specifically, returns the
@@ -246,9 +248,7 @@ def sci(im):
## Any Artist ##
# (getp is simply imported)
def setp(*args, **kwargs):
ret = _setp(*args, **kwargs)
@@ -1099,7 +1099,6 @@ def subplots(nrows=1, ncols=1, sharex=False, sharey=False, squeeze=True,
return ret
from gridspec import GridSpec
def subplot2grid(shape, loc, rowspan=1, colspan=1, **kwargs):
Create a subplot in a grid. The grid is specified by *shape*, at
@@ -2091,7 +2090,6 @@ def pad(s, l):
## Plotting part 1: manually generated functions and wrappers ##
import matplotlib.colorbar
def colorbar(mappable=None, cax=None, ax=None, **kw):
if mappable is None:
mappable = gci()

0 comments on commit be049b2

Please sign in to comment.