Beispiel #1
0
def _parse_color_segments(segments, name, hinge=0, colormodel='RGB', N=256):
    """
    A private function to parse color segments.

    Parameters
    ----------
    segments : list
        A list of segments following the GMT structure:

        `z0 color0  z1 color1`

        Where color is either a named color from the GMT color list like
        `black` or `r g b` or `r/g/b`.

    name : str, optional
        name of the returned cmap.

    hinge : float, optional
        Zero by default.

    colormodel : str, optional
        Assumed to be ``'RGB'`` by default.

    N : int, optional
        Number of entries in the look-up-table of the colormap.

    Returns
    -------
    cmap : Colormap
        Either a LinearSegmentedColormap if sequential or
        DynamicColormap if diverging around a ``hinge`` value.
    """
    x = []
    r = []
    g = []
    b = []
    for segment in segments:
        # parse the left side of each segment
        fields = re.split(r'\s+|[/]', segment)
        x.append(float(fields[0]))
        try:
            r.append(float(fields[1]))
            g.append(float(fields[2]))
            b.append(float(fields[3]))
            xi = 4
        except ValueError:
            r_, g_, b_ = GMT_COLOR_NAMES[fields[1]]
            r.append(float(r_))
            g.append(float(g_))
            b.append(float(b_))
            xi = 2

    # parse the right side of the last segment
    x.append(float(fields[xi]))

    try:
        r.append(float(fields[xi + 1]))
        g.append(float(fields[xi + 2]))
        b.append(float(fields[xi + 3]))
    except ValueError:
        r_, g_, b_ = GMT_COLOR_NAMES[fields[-1]]
        r.append(float(r_))
        g.append(float(g_))
        b.append(float(b_))

    x = np.array(x)
    r = np.array(r)
    g = np.array(g)
    b = np.array(b)

    if colormodel == "HSV":
        for i in range(r.shape[0]):
            # convert HSV to RGB
            rr, gg, bb = hsv_to_rgb([r[i] / 360., g[i], b[i]])
            r[i] = rr
            g[i] = gg
            b[i] = bb
    elif colormodel == "RGB":
        r /= 255.
        g /= 255.
        b /= 255.
    else:
        raise ValueError('Color model `{}` not understood'.format(colormodel))

    if hinge is not None and x[0] < hinge < x[-1]:
        cmap_type = 'dynamic'
        norm = TwoSlopeNorm(vmin=x[0], vcenter=hinge, vmax=x[-1])
        hinge_index = np.abs(x - hinge).argmin()
    else:
        cmap_type = 'normal'
        hinge = None
        norm = Normalize(vmin=x[0], vmax=x[-1])

    xNorm = norm(x)
    red = []
    blue = []
    green = []
    for i in range(xNorm.size):
        # avoid interpolation across the hinge
        try:
            if i == (hinge_index):
                red.append([xNorm[i], r[i - 1], r[i]])
                green.append([xNorm[i], g[i - 1], g[i]])
                blue.append([xNorm[i], b[i - 1], b[i]])
        except UnboundLocalError:
            pass

        red.append([xNorm[i], r[i], r[i]])
        green.append([xNorm[i], g[i], g[i]])
        blue.append([xNorm[i], b[i], b[i]])

    # return colormap
    cdict = dict(red=red, green=green, blue=blue)
    cmap = LinearSegmentedColormap(name=name, segmentdata=cdict, N=N)
    cmap.values = x
    cmap.colors = list(zip(r, g, b))
    cmap.hinge = hinge
    cmap._init()

    if cmap_type == 'dynamic':
        return DynamicColormap(cmap)
    else:
        return cmap