"""Convenience functions for matplotlib plotting and image viewing."""
import collections
import numpy as np
from matplotlib import pyplot as plt, cm


def show(image, block=False, title='', **kwargs):
    """Show *image*. If *block* is False the call is nonblocking. *title* is the image title.
    *kwargs* are passed to matplotlib's ``imshow`` function. This command always creates a new
    figure. Returns matplotlib's ``AxesImage``.
    *image* can have physical units in which case it must contain attribute *magnitude* and *units*.
    If it does, image is stripped off units and passed to matplotlib and units are shown as x label.
    """
    xlabel = ''
    if hasattr(image, 'magnitude'):
        xlabel = str(image.units)
        image = image.magnitude

    plt.figure()
    mpl_image = plt.imshow(image, **kwargs)
    mpl_image.axes.format_coord = _FormatCoord(image)
    mn = image.min()
    mx = image.max()
    if mx - mn > np.finfo(np.float).eps:
        plt.colorbar(ticks=np.linspace(mn, mx, 8))
    plt.title(title)
    plt.xlabel(xlabel)
    plt.show(block)

    return mpl_image


def plot(*args, **kwargs):
    """Plot using matplotlib's ``plot`` function. Pass it *args* and *kwargs*.  *kwargs* are
    infected with *block* and if False or not specified, the call is nonblocking. *title* is alowed
    to be in *kwargs* which sets the figure title. *grid* can be in kwargs which is a boolean
    turning the grid on or off. *xlabel* and *ylabel* define the x and y axes labels if specified in
    *kwargs*. This command always creates a new figure. Returns a list of ``Line2D`` instances.
    """
    block = kwargs.pop('block', False)
    title = kwargs.pop('title', '')
    xlabel = kwargs.pop('xlabel', '')
    ylabel = kwargs.pop('ylabel', '')
    grid = kwargs.pop('grid', True)

    plt.figure()
    lines = plt.plot(*args, **kwargs)
    plt.title(title)
    plt.xlabel(xlabel)
    plt.ylabel(ylabel)
    plt.grid(grid)
    plt.show(block)

    return lines


class _FormatCoord(object):
    """Coordinates formatter."""
    def __init__(self, image):
        self.image = image
        self.shape = self.image.shape
        self.value_fmt = determine_intensity_format(self.image[0, 0])

    def __call__(self, x, y):
        """Overrides matplotlib's default behavior on mouse motion,
        *x* and *y* are planar coordinates.
        """
        col = int(x + 0.5)
        row = int(y + 0.5)

        if (col >= 0 and col < self.image.shape[1] and
                row >= 0 and row < self.image.shape[0]):
            # The formatting doesn't like np.float32
            if self.image.ndim == 2:
                value = (float(self.image[row, col]),)
            else:
                value = self.image[row, col]
            value_str = self.value_fmt.format(*value)
            return 'x={:<12.2f}y={:<12.2f}{}'.format(x, y, value_str)
        else:
            return 'x={:<12.2f}y={:<12.2f}'.format(x, y)


def determine_intensity_format(number):
    """Get format string based on *number*'s data type."""
    if isinstance(number, collections.Iterable):
        fmt = 'RGB={:>03},{:>03},{:>03}'
    elif isinstance(number, (float, np.float, np.float16, np.float32,
                             np.float64, np.float128)):
        fmt = 'I={:<12.5f}'
    else:
        fmt = 'I={:<12}'

    return fmt

@@ -142,12 +142,8 @@
  plt
-, cm
 %0A%0A%0Ad
@@ -638,129 +638,1013 @@
     
-%22%22%22%0A    xlabel = ''%0A    if hasattr(image, 'magnitude'):%0A        xlabel = str(image.units)%0A        image = image.magnitude
+You can specify a keyword argument *clim* which can be either 'auto', a number or a tuple. If it%0A    is 'auto' then the first and last 0.1 percent of the values are trimmed from the displayed%0A    image, which is useful when the object of interest has narrow dynamic range in comparison to the%0A    overall image. If it is a number you specify the percentile yourself. It it is a tuple it means%0A    you specify the minimum and maximum yourself.%0A    %22%22%22%0A    xlabel = ''%0A    if hasattr(image, 'magnitude'):%0A        xlabel = str(image.units)%0A        image = image.magnitude%0A    clim = kwargs.pop('clim', None)%0A    if not (clim is None or isinstance(clim, tuple)):%0A        # Use 0.1 %25 for *auto* mode%0A        percentile = clim if clim != 'auto' else .1%0A        hist, bins = np.histogram(image, bins=256)%0A        cumsum = np.cumsum(hist) / float(np.sum(hist)) * 100%0A        valid = bins%5Bnp.where((cumsum %3E percentile) & (cumsum %3C 100 - percentile))%5D%0A        clim = (valid%5B0%5D, valid%5B-1%5D)%0A    kwargs%5B'clim'%5D = clim
 %0A%0A  

Add percentile-based clim