From c33a09f0376b2a55d2411cdd4505b76250438ea9 Mon Sep 17 00:00:00 2001 From: Andrew Dawson Date: Wed, 14 Mar 2012 17:06:15 +0000 Subject: [PATCH] NF - control the length of colorbar extensions Added ability to control length of colorbar extensions using a new keyword argument "extendfrac". Tests and examples are also included. --- doc/api/api_changes.rst | 3 + doc/users/whats_new.rst | 31 ++++++ examples/api/colorbar_only.py | 27 +++++- lib/matplotlib/__init__.py | 3 +- lib/matplotlib/colorbar.py | 89 +++++++++++++++--- .../colorbar_extensions_proportional.png | Bin 0 -> 16578 bytes .../colorbar_extensions_uniform.png | Bin 0 -> 16860 bytes lib/matplotlib/tests/test_colorbar.py | 61 ++++++++++++ 8 files changed, 200 insertions(+), 14 deletions(-) create mode 100644 lib/matplotlib/tests/baseline_images/test_colorbar/colorbar_extensions_proportional.png create mode 100644 lib/matplotlib/tests/baseline_images/test_colorbar/colorbar_extensions_uniform.png create mode 100644 lib/matplotlib/tests/test_colorbar.py diff --git a/doc/api/api_changes.rst b/doc/api/api_changes.rst index a077f851101f..bc65dcfb2a1f 100644 --- a/doc/api/api_changes.rst +++ b/doc/api/api_changes.rst @@ -51,6 +51,9 @@ Changes in 1.2.x matplotlib axes by providing a ``_as_mpl_axes`` method. See :ref:`adding-new-scales` for more detail. +* A new keyword *extendfrac* in :meth:`~matplotlib.pyplot.colorbar` and + :class:`~matplotlib.colorbar.ColorbarBase` allows one to control the size of + the triangular minimum and maximum extensions on colorbars. Changes in 1.1.x ================ diff --git a/doc/users/whats_new.rst b/doc/users/whats_new.rst index f18fc2f1a5c5..83b707a58e68 100644 --- a/doc/users/whats_new.rst +++ b/doc/users/whats_new.rst @@ -26,6 +26,37 @@ Damon McDougall added a new plotting method for the .. plot:: mpl_examples/mplot3d/trisurf3d_demo.py +Control the lengths of colorbar extensions +------------------------------------------ + +Andrew Dawson added a new keyword argument *extendfrac* to +:meth:`~matplotlib.pyplot.colorbar` to control the length of +minimum and maximum colorbar extensions. + +.. plot:: + + import matplotlib.pyplot as plt + import numpy as np + + x = y = np.linspace(0., 2*np.pi, 100) + X, Y = np.meshgrid(x, y) + Z = np.cos(X) * np.sin(0.5*Y) + + clevs = [-.75, -.5, -.25, 0., .25, .5, .75] + cmap = plt.cm.get_cmap(name='jet', lut=8) + + ax1 = plt.subplot(211) + cs1 = plt.contourf(x, y, Z, clevs, cmap=cmap, extend='both') + cb1 = plt.colorbar(orientation='horizontal', extendfrac=None) + cb1.set_label('Default length colorbar extensions') + + ax2 = plt.subplot(212) + cs2 = plt.contourf(x, y, Z, clevs, cmap=cmap, extend='both') + cb2 = plt.colorbar(orientation='horizontal', extendfrac='auto') + cb2.set_label('Custom length colorbar extensions') + + plt.show() + .. _whats-new-1-1: new in matplotlib-1.1 diff --git a/examples/api/colorbar_only.py b/examples/api/colorbar_only.py index e071e1b4a156..0e1837e95f19 100644 --- a/examples/api/colorbar_only.py +++ b/examples/api/colorbar_only.py @@ -6,8 +6,9 @@ # Make a figure and axes with dimensions as desired. fig = pyplot.figure(figsize=(8,3)) -ax1 = fig.add_axes([0.05, 0.65, 0.9, 0.15]) -ax2 = fig.add_axes([0.05, 0.25, 0.9, 0.15]) +ax1 = fig.add_axes([0.05, 0.80, 0.9, 0.15]) +ax2 = fig.add_axes([0.05, 0.475, 0.9, 0.15]) +ax3 = fig.add_axes([0.05, 0.15, 0.9, 0.15]) # Set the colormap and norm to correspond to the data for which # the colorbar will be used. @@ -47,5 +48,27 @@ orientation='horizontal') cb2.set_label('Discrete intervals, some other units') +# The third example illustrates the use of custom length colorbar +# extensions, used on a colorbar with discrete intervals. +cmap = mpl.colors.ListedColormap([[0., .4, 1.], [0., .8, 1.], + [1., .8, 0.], [1., .4, 0.]]) +cmap.set_over((1., 0., 0.)) +cmap.set_under((0., 0., 1.)) + +bounds = [-1., -.5, 0., .5, 1.] +norm = mpl.colors.BoundaryNorm(bounds, cmap.N) +cb3 = mpl.colorbar.ColorbarBase(ax3, cmap=cmap, + norm=norm, + boundaries=[-10]+bounds+[10], + extend='both', + # Make the length of each extension + # the same as the length of the + # interior colors: + extendfrac='auto', + ticks=bounds, + spacing='uniform', + orientation='horizontal') +cb3.set_label('Custom extension lengths, some other units') + pyplot.show() diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index 0c4583f465f0..5eb9e779ced2 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -992,7 +992,8 @@ def tk_window_focus(): 'matplotlib.tests.test_text', 'matplotlib.tests.test_tightlayout', 'matplotlib.tests.test_delaunay', - 'matplotlib.tests.test_legend' + 'matplotlib.tests.test_legend', + 'matplotlib.tests.test_colorbar', ] def test(verbosity=1): diff --git a/lib/matplotlib/colorbar.py b/lib/matplotlib/colorbar.py index 5f03f568feb5..2f8a72092300 100644 --- a/lib/matplotlib/colorbar.py +++ b/lib/matplotlib/colorbar.py @@ -59,13 +59,29 @@ colormap_kw_doc = ''' - =========== ==================================================== + ============ ==================================================== Property Description - =========== ==================================================== + ============ ==================================================== *extend* [ 'neither' | 'both' | 'min' | 'max' ] If not 'neither', make pointed end(s) for out-of- range values. These are set for a given colormap using the colormap set_under and set_over methods. + *extendfrac* [ *None* | 'auto' | length | lengths ] + If set to *None*, both the minimum and maximum + triangular colorbar extensions with have a length of + 5% of the interior colorbar length (this is the + default setting). If set to 'auto', makes the + triangular colorbar extensions the same lengths as + the interior boxes (when *spacing* is set to + 'uniform') or the same lengths as the respective + adjacent interior boxes (when *spacing* is set to + 'proportional'). If a scalar, indicates the length + of both the minimum and maximum triangular colorbar + extensions as a fraction of the interior colorbar + length. A two-element sequence of fractions may also + be given, indicating the lengths of the minimum and + maximum colorbar extensions respectively as a + fraction of the interior colorbar length. *spacing* [ 'uniform' | 'proportional' ] Uniform spacing gives each discrete color the same space; proportional makes the space proportional to @@ -82,7 +98,7 @@ given instead. *drawedges* [ False | True ] If true, draw lines at color boundaries. - =========== ==================================================== + ============ ==================================================== The following will probably be useful only in the context of indexed colors (that is, when the mappable has norm=NoNorm()), @@ -221,6 +237,7 @@ def __init__(self, ax, cmap=None, format=None, drawedges=False, filled=True, + extendfrac=None, ): self.ax = ax self._patch_ax() @@ -236,6 +253,7 @@ def __init__(self, ax, cmap=None, self.orientation = orientation self.drawedges = drawedges self.filled = filled + self.extendfrac = extendfrac self.solids = None self.lines = None self.outline = None @@ -616,6 +634,35 @@ def _extended_N(self): N += 1 return N + def _get_extension_lengths(self, frac, automin, automax, default=0.05): + ''' + Get the lengths of colorbar extensions. + + A helper method for _uniform_y and _proportional_y. + ''' + # Set the default value. + extendlength = np.array([default, default]) + if isinstance(frac, str): + if frac.lower() == 'auto': + # Use the provided values when 'auto' is required. + extendlength[0] = automin + extendlength[1] = automax + else: + # Any other string is invalid. + raise ValueError('invalid value for extendfrac') + elif frac is not None: + try: + # Try to set min and max extension fractions directly. + extendlength[:] = frac + # If frac is a sequence contaning None then NaN may + # be encountered. This is an error. + if np.isnan(extendlength).any(): + raise ValueError() + except (TypeError, ValueError): + # Raise an error on encountering an invalid value for frac. + raise ValueError('invalid value for extendfrac') + return extendlength + def _uniform_y(self, N): ''' Return colorbar data coordinates for *N* uniformly @@ -624,16 +671,19 @@ def _uniform_y(self, N): if self.extend == 'neither': y = np.linspace(0, 1, N) else: + automin = automax = 1. / (N - 1.) + extendlength = self._get_extension_lengths(self.extendfrac, + automin, automax, default=0.05) if self.extend == 'both': y = np.zeros(N + 2, 'd') - y[0] = -0.05 - y[-1] = 1.05 + y[0] = 0. - extendlength[0] + y[-1] = 1. + extendlength[1] elif self.extend == 'min': y = np.zeros(N + 1, 'd') - y[0] = -0.05 + y[0] = 0. - extendlength[0] else: y = np.zeros(N + 1, 'd') - y[-1] = 1.05 + y[-1] = 1. + extendlength[1] y[self._inside] = np.linspace(0, 1, N) return y @@ -648,10 +698,27 @@ def _proportional_y(self): y = y / (self._boundaries[-1] - self._boundaries[0]) else: y = self.norm(self._boundaries.copy()) - if self._extend_lower(): - y[0] = -0.05 - if self._extend_upper(): - y[-1] = 1.05 + if self.extend == 'min': + # Exclude leftmost interval of y. + clen = y[-1] - y[1] + automin = (y[2] - y[1]) / clen + automax = (y[-1] - y[-2]) / clen + elif self.extend == 'max': + # Exclude rightmost interval in y. + clen = y[-2] - y[0] + automin = (y[1] - y[0]) / clen + automax = (y[-2] - y[-3]) / clen + else: + # Exclude leftmost and rightmost intervals in y. + clen = y[-2] - y[1] + automin = (y[2] - y[1]) / clen + automax = (y[-2] - y[-3]) / clen + extendlength = self._get_extension_lengths(self.extendfrac, + automin, automax, default=0.05) + if self.extend in ('both', 'min'): + y[0] = 0. - extendlength[0] + if self.extend in ('both', 'max'): + y[-1] = 1. + extendlength[1] yi = y[self._inside] norm = colors.Normalize(yi[0], yi[-1]) y[self._inside] = norm(yi) diff --git a/lib/matplotlib/tests/baseline_images/test_colorbar/colorbar_extensions_proportional.png b/lib/matplotlib/tests/baseline_images/test_colorbar/colorbar_extensions_proportional.png new file mode 100644 index 0000000000000000000000000000000000000000..e531db31bb1b156ced9f06f2c2dc58a80ec09824 GIT binary patch literal 16578 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 Q1DnEB6}1$~