Exemplo n.º 1
0
def generate_polycollection(ax, x, y1, y2):
    """
    Accessory function that creates new PolyCollection class instance representing
    new correct field-of-view. We use its output to assign new *path* to the old
    one instance. Algorithm has been taken from the matplotlib' sources for the
    fill_between() function and used because there is no easy way to update polygon
    with new data

    input:
        same as for the fill_between() function

    returns:
        matplotlib.collections.PolyCollection instance
    """

    # i.e. where = outer_circle >= fov_circle
    where = y2 >= y1
    kwargs = {'facecolor': colors['fov_outer'], 'alpha': 0.25}

    # Convert the arrays so we can work with them
    x = np.ma.masked_invalid(ax.convert_xunits(x))
    y1 = np.ma.masked_invalid(ax.convert_yunits(y1))
    y2 = np.ma.masked_invalid(ax.convert_yunits(y2))

    where = where & ~functools.reduce(np.logical_or,
                                      map(np.ma.getmask, [x, y1, y2]))

    x, y1, y2 = np.broadcast_arrays(np.atleast_1d(x), y1, y2)

    polys = []
    for ind0, ind1 in contiguous_regions(where):
        xslice = x[ind0:ind1]
        y1slice = y1[ind0:ind1]
        y2slice = y2[ind0:ind1]

        if not len(xslice):
            continue

        N = len(xslice)
        X = np.zeros((2 * N + 2, 2), float)

        # the purpose of the next two lines is for when y2 is a
        # scalar like 0 and we want the fill to go all the way
        # down to 0 even if none of the y1 sample points do
        start = xslice[0], y2slice[0]
        end = xslice[-1], y2slice[-1]

        X[0] = start
        X[N + 1] = end

        X[1:N + 1, 0] = xslice
        X[1:N + 1, 1] = y1slice
        X[N + 2:, 0] = xslice[::-1]
        X[N + 2:, 1] = y2slice[::-1]

        polys.append(X)

    return mcoll.PolyCollection(polys, **kwargs)
Exemplo n.º 2
0
def test_contiguous_regions():
    a, b, c = 3, 4, 5
    # Starts and ends with True
    mask = [True]*a + [False]*b + [True]*c
    expected = [(0, a), (a+b, a+b+c)]
    assert cbook.contiguous_regions(mask) == expected
    d, e = 6, 7
    # Starts with True ends with False
    mask = mask + [False]*e
    assert cbook.contiguous_regions(mask) == expected
    # Starts with False ends with True
    mask = [False]*d + mask[:-e]
    expected = [(d, d+a), (d+a+b, d+a+b+c)]
    assert cbook.contiguous_regions(mask) == expected
    # Starts and ends with False
    mask = mask + [False]*e
    assert cbook.contiguous_regions(mask) == expected
    # No True in mask
    assert cbook.contiguous_regions([False]*5) == []
    # Empty mask
    assert cbook.contiguous_regions([]) == []
Exemplo n.º 3
0
def test_contiguous_regions():
    a, b, c = 3, 4, 5
    # Starts and ends with True
    mask = [True] * a + [False] * b + [True] * c
    expected = [(0, a), (a + b, a + b + c)]
    assert cbook.contiguous_regions(mask) == expected
    d, e = 6, 7
    # Starts with True ends with False
    mask = mask + [False] * e
    assert cbook.contiguous_regions(mask) == expected
    # Starts with False ends with True
    mask = [False] * d + mask[:-e]
    expected = [(d, d + a), (d + a + b, d + a + b + c)]
    assert cbook.contiguous_regions(mask) == expected
    # Starts and ends with False
    mask = mask + [False] * e
    assert cbook.contiguous_regions(mask) == expected
    # No True in mask
    assert cbook.contiguous_regions([False] * 5) == []
    # Empty mask
    assert cbook.contiguous_regions([]) == []
Exemplo n.º 4
0
    def fill_gradient(self,
                      canvas,
                      X,
                      percentiles,
                      color=Tango.colorsHex['mediumBlue'],
                      label=None,
                      **kwargs):
        ax = canvas
        plots = []

        if 'edgecolors' not in kwargs:
            kwargs['edgecolors'] = 'none'

        if 'facecolors' in kwargs:
            color = kwargs.pop('facecolors')

        if 'array' in kwargs:
            array = kwargs.pop('array')
        else:
            array = 1. - np.abs(np.linspace(-.97, .97, len(percentiles) - 1))

        if 'alpha' in kwargs:
            alpha = kwargs.pop('alpha')
        else:
            alpha = .8

        if 'cmap' in kwargs:
            cmap = kwargs.pop('cmap')
        else:
            cmap = LinearSegmentedColormap.from_list('WhToColor',
                                                     (color, color),
                                                     N=array.size)
        cmap._init()
        cmap._lut[:-3, -1] = alpha * array

        kwargs['facecolors'] = [cmap(i) for i in np.linspace(0, 1, cmap.N)]

        # pop where from kwargs
        where = kwargs.pop('where') if 'where' in kwargs else None
        # pop interpolate, which we actually do not do here!
        if 'interpolate' in kwargs: kwargs.pop('interpolate')

        def pairwise(iterable):
            "s -> (s0,s1), (s1,s2), (s2, s3), ..."
            from itertools import tee
            #try:
            #    from itertools import izip as zip
            #except ImportError:
            #    pass
            a, b = tee(iterable)
            next(b, None)
            return zip(a, b)

        polycol = []
        for y1, y2 in pairwise(percentiles):
            try:
                from matplotlib.cbook import contiguous_regions
            except ImportError:
                from matplotlib.mlab import contiguous_regions
            # Handle united data, such as dates
            ax._process_unit_info(xdata=X, ydata=y1)
            ax._process_unit_info(ydata=y2)
            # Convert the arrays so we can work with them
            from numpy import ma
            x = ma.masked_invalid(ax.convert_xunits(X))
            y1 = ma.masked_invalid(ax.convert_yunits(y1))
            y2 = ma.masked_invalid(ax.convert_yunits(y2))

            if y1.ndim == 0:
                y1 = np.ones_like(x) * y1
            if y2.ndim == 0:
                y2 = np.ones_like(x) * y2

            if where is None:
                where = np.ones(len(x), np.bool)
            else:
                where = np.asarray(where, np.bool)

            if not (x.shape == y1.shape == y2.shape == where.shape):
                raise ValueError("Argument dimensions are incompatible")

            from functools import reduce
            mask = reduce(ma.mask_or, [ma.getmask(a) for a in (x, y1, y2)])
            if mask is not ma.nomask:
                where &= ~mask

            polys = []
            for ind0, ind1 in contiguous_regions(where):
                xslice = x[ind0:ind1]
                y1slice = y1[ind0:ind1]
                y2slice = y2[ind0:ind1]

                if not len(xslice):
                    continue

                N = len(xslice)
                p = np.zeros((2 * N + 2, 2), np.float)

                # the purpose of the next two lines is for when y2 is a
                # scalar like 0 and we want the fill to go all the way
                # down to 0 even if none of the y1 sample points do
                start = xslice[0], y2slice[0]
                end = xslice[-1], y2slice[-1]

                p[0] = start
                p[N + 1] = end

                p[1:N + 1, 0] = xslice
                p[1:N + 1, 1] = y1slice
                p[N + 2:, 0] = xslice[::-1]
                p[N + 2:, 1] = y2slice[::-1]

                polys.append(p)
            polycol.extend(polys)
        from matplotlib.collections import PolyCollection
        if 'zorder' not in kwargs:
            kwargs['zorder'] = 0
        plots.append(PolyCollection(polycol, label=label, **kwargs))
        ax.add_collection(plots[-1], autolim=True)
        ax.autoscale_view()
        return plots