Skip to content

Commit

Permalink
Shared colorbar axes working.
Browse files Browse the repository at this point in the history
  • Loading branch information
pelson committed May 14, 2013
1 parent 6b442b8 commit be049b2
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 22 deletions.
99 changes: 86 additions & 13 deletions lib/matplotlib/colorbar.py
Expand Up @@ -35,6 +35,7 @@
import matplotlib.patches as mpatches import matplotlib.patches as mpatches
import matplotlib.path as mpath import matplotlib.path as mpath
import matplotlib.ticker as ticker import matplotlib.ticker as ticker
import matplotlib.transforms as mtrans


from matplotlib import docstring from matplotlib import docstring


Expand All @@ -52,7 +53,8 @@
*anchor* (0.0, 0.5) if vertical; (0.5, 1.0) if horizontal; *anchor* (0.0, 0.5) if vertical; (0.5, 1.0) if horizontal;
the anchor point of the colorbar axes the anchor point of the colorbar axes
*panchor* (1.0, 0.5) if vertical; (0.5, 0.0) if horizontal; *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
============= ==================================================== ============= ====================================================
''' '''
Expand Down Expand Up @@ -149,8 +151,9 @@
*cax* *cax*
None | axes object into which the colorbar will be drawn None | axes object into which the colorbar will be drawn
*ax* *ax*
None | parent axes object from which space for a new None | parent axes object(s) from which space for a new
colorbar axes will be stolen colorbar axes will be stolen. If a list of axes is given
they will be resized to make room for the colorbar axes.
*use_gridspec* *use_gridspec*
False | If *cax* is None, a new *cax* is created as an instance of 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, Axes. If *ax* is an instance of Subplot and *use_gridspec* is True,
Expand Down Expand Up @@ -255,6 +258,7 @@ def __init__(self, ax, cmap=None,
values=None, values=None,
boundaries=None, boundaries=None,
orientation='vertical', orientation='vertical',
location='right',
extend='neither', extend='neither',
spacing='uniform', # uniform or proportional spacing='uniform', # uniform or proportional
ticks=None, ticks=None,
Expand All @@ -278,6 +282,7 @@ def __init__(self, ax, cmap=None,
self._inside = self._slice_dict[extend] self._inside = self._slice_dict[extend]
self.spacing = spacing self.spacing = spacing
self.orientation = orientation self.orientation = orientation
self.location = location
self.drawedges = drawedges self.drawedges = drawedges
self.filled = filled self.filled = filled
self.extendfrac = extendfrac self.extendfrac = extendfrac
Expand Down Expand Up @@ -336,11 +341,15 @@ def config_axis(self):
ax = self.ax ax = self.ax
if self.orientation == 'vertical': if self.orientation == 'vertical':
ax.xaxis.set_ticks([]) ax.xaxis.set_ticks([])
ax.yaxis.set_label_position('right') # location is either one of 'bottom' or 'top'
ax.yaxis.set_ticks_position('right') ax.yaxis.set_label_position(self.location)
ax.yaxis.set_ticks_position(self.location)
else: else:
ax.yaxis.set_ticks([]) ax.yaxis.set_ticks([])
ax.xaxis.set_label_position('bottom') # location is either one of 'left' or 'right'
ax.xaxis.set_label_position(self.location)
# XXX This wasn't enabled before...
ax.xaxis.set_ticks_position(self.location)


self._set_label() self._set_label()


Expand Down Expand Up @@ -835,11 +844,10 @@ class Colorbar(ColorbarBase):
""" """
def __init__(self, ax, mappable, **kw): def __init__(self, ax, mappable, **kw):
mappable.autoscale_None() # Ensure mappable.norm.vmin, vmax # Ensure the given mappable's norm has appropriate vmin and vmax set
# are set when colorbar is called, # even if mappable.draw has not yet been called.
# even if mappable.draw has not yet mappable.autoscale_None()
# been called. This will not change
# vmin, vmax if they are already set.
self.mappable = mappable self.mappable = mappable
kw['cmap'] = mappable.cmap kw['cmap'] = mappable.cmap
kw['norm'] = mappable.norm kw['norm'] = mappable.norm
Expand Down Expand Up @@ -948,7 +956,7 @@ def update_bruteforce(self, mappable):




@docstring.Substitution(make_axes_kw_doc) @docstring.Substitution(make_axes_kw_doc)
def make_axes(parent, **kw): def make_axes_orig(parent, **kw):
''' '''
Resize and reposition a parent axes, and return a child Resize and reposition a parent axes, and return a child
axes suitable for a colorbar:: axes suitable for a colorbar::
Expand Down Expand Up @@ -994,6 +1002,71 @@ def make_axes(parent, **kw):
return cax, kw return cax, kw




@docstring.Substitution(make_axes_kw_doc)
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))
else:
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)
else:
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)
else:
pb1, _, pbcb = pb.splitx(1 - fraction - pad, 1 - fraction)
pbcb = pbcb.shrunk(1.0, shrink).anchored('C', pbcb)

else:
if location == 'top':
pb1, _, pbcb = pb.splity(1 - fraction - pad, fraction)
else:
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)
ax.set_position(new_posn)
if panchor is not False:
ax.set_anchor(panchor)

# 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


@docstring.Substitution(make_axes_kw_doc) @docstring.Substitution(make_axes_kw_doc)
def make_axes_gridspec(parent, **kw): def make_axes_gridspec(parent, **kw):
''' '''
Expand All @@ -1018,7 +1091,7 @@ def make_axes_gridspec(parent, **kw):
Keyword arguments may include the following (with defaults): Keyword arguments may include the following (with defaults):
*orientation* *orientation*
'vertical' or 'horizontal' 'vertical' or 'horizontal'
%s %s
Expand Down
4 changes: 2 additions & 2 deletions lib/matplotlib/figure.py
Expand Up @@ -1418,7 +1418,7 @@ def savefig(self, *args, **kwargs):
ax.patch.set_edgecolor(cc[1]) ax.patch.set_edgecolor(cc[1])


@docstring.dedent_interpd @docstring.dedent_interpd
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*. Create a colorbar for a ScalarMappable instance, *mappable*.
Expand All @@ -1427,7 +1427,7 @@ def colorbar(self, mappable, cax=None, ax=None, **kw):
""" """
if ax is None: if ax is None:
ax = self.gca() ax = self.gca()
use_gridspec = kw.pop("use_gridspec", True)
if cax is None: if cax is None:
if use_gridspec and isinstance(ax, SubplotBase): if use_gridspec and isinstance(ax, SubplotBase):
cax, kw = cbar.make_axes_gridspec(ax, **kw) cax, kw = cbar.make_axes_gridspec(ax, **kw)
Expand Down
12 changes: 5 additions & 7 deletions lib/matplotlib/pyplot.py
Expand Up @@ -21,11 +21,13 @@
import warnings import warnings


import matplotlib import matplotlib
import matplotlib.colorbar
from matplotlib import _pylab_helpers, interactive from matplotlib import _pylab_helpers, interactive
from matplotlib.cbook import dedent, silent_list, is_string_like, is_numlike from matplotlib.cbook import dedent, silent_list, is_string_like, is_numlike
from matplotlib import docstring from matplotlib import docstring
from matplotlib.figure import Figure, figaspect
from matplotlib.backend_bases import FigureCanvasBase 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 imread as _imread
from matplotlib.image import imsave as _imsave from matplotlib.image import imsave as _imsave
from matplotlib import rcParams, rcParamsDefault, get_backend from matplotlib import rcParams, rcParamsDefault, get_backend
Expand Down Expand Up @@ -207,16 +209,16 @@ def rc_context(rc=None, fname=None):
return matplotlib.rc_context(rc, fname) return matplotlib.rc_context(rc, fname)





@docstring.copy_dedent(matplotlib.rcdefaults) @docstring.copy_dedent(matplotlib.rcdefaults)
def rcdefaults(): def rcdefaults():
matplotlib.rcdefaults() matplotlib.rcdefaults()
draw_if_interactive() draw_if_interactive()



# The current "image" (ScalarMappable) is retrieved or set # The current "image" (ScalarMappable) is retrieved or set
# only via the pyplot interface using the following two # only via the pyplot interface using the following two
# functions: # functions:


def gci(): def gci():
""" """
Get the current colorable artist. Specifically, returns the Get the current colorable artist. Specifically, returns the
Expand Down Expand Up @@ -246,9 +248,7 @@ def sci(im):




## Any Artist ## ## Any Artist ##

# (getp is simply imported) # (getp is simply imported)

@docstring.copy(_setp) @docstring.copy(_setp)
def setp(*args, **kwargs): def setp(*args, **kwargs):
ret = _setp(*args, **kwargs) ret = _setp(*args, **kwargs)
Expand Down Expand Up @@ -1099,7 +1099,6 @@ def subplots(nrows=1, ncols=1, sharex=False, sharey=False, squeeze=True,
return ret return ret




from gridspec import GridSpec
def subplot2grid(shape, loc, rowspan=1, colspan=1, **kwargs): def subplot2grid(shape, loc, rowspan=1, colspan=1, **kwargs):
""" """
Create a subplot in a grid. The grid is specified by *shape*, at Create a subplot in a grid. The grid is specified by *shape*, at
Expand Down Expand Up @@ -2091,7 +2090,6 @@ def pad(s, l):


## Plotting part 1: manually generated functions and wrappers ## ## Plotting part 1: manually generated functions and wrappers ##


import matplotlib.colorbar
def colorbar(mappable=None, cax=None, ax=None, **kw): def colorbar(mappable=None, cax=None, ax=None, **kw):
if mappable is None: if mappable is None:
mappable = gci() mappable = gci()
Expand Down

0 comments on commit be049b2

Please sign in to comment.