def make_cmap(color, rotation=.5, white=False, transparent_zero=False): h, s, v = rgb_to_hsv(color) h = h + rotation if h > 1: h -= 1 r, g, b = color ri, gi, bi = hsv_to_rgb((h, s, v)) colors = {'direct': (ri, gi, bi), 'inverted': (r, g, b)} cdict = {} for direction, (r, g, b) in colors.items(): if white: cdict[direction] = {color: [(0.0, 0.0416, 0.0416), (0.18, c, c), (0.5, 1, 1), (0.62, 0.0, 0.0), (1.0, 0.0416, 0.0416)] for color, c in [('blue', b), ('red', r), ('green', g)]} else: cdict[direction] = {color: [(0.0, 1, 1), (0.32, c, c), (0.5, 0.0416, 0.0416), (0.5, 0.0, 0.0), (0.87, 0.0, 0.0), (1.0, 1, 1)] for color, c in [('blue', b), ('red', r), ('green', g)]} if transparent_zero: cdict[direction]['alpha']: [(0, 1, 1), (0.5, 0, 0), (1, 1, 1)] cmap = LinearSegmentedColormap('cmap', cdict['direct']) cmapi = LinearSegmentedColormap('cmap', cdict['inverted']) cmap._init() cmapi._init() cmap._lut = np.maximum(cmap._lut, cmapi._lut[::-1]) # Big hack from nilearn (WTF !?) cmap._lut[-1, -1] = 0 return cmap
def stitch_cmap(cmap1, cmap2, stitch_frac=0.5, dfrac=0.001, transparent=False): ''' Code adapted from Dr. Adrienne Stilp Stitch two color maps together: cmap1 from 0 and stitch_frac and cmap2 from stitch_frac to 1 with dfrac spacing inbetween ex: stitch black to white to white to red: stitched = stitch_cmap(cm.Greys_r, cm.Reds, stitch_frac=0.525, dfrac=0.05) ''' from matplotlib.colors import LinearSegmentedColormap def left(seg): """left color segment""" return [(i * (stitch_frac - dfrac), j, k) for i, j, k in seg] def right(seg): """right color segment""" frac = stitch_frac + dfrac return [(i * (1 - frac) + frac, j, k) for i, j, k in seg] def new_seg(color): """combine left and right segments""" seg = left(cmap1._segmentdata[color]) + \ right(cmap2._segmentdata[color]) return seg rgb = ['blue', 'red', 'green'] cname = '_'.join((cmap1.name, cmap2.name)) cdict = dict([(key, new_seg(key)) for key in rgb]) ncmap = LinearSegmentedColormap(cname, cdict, 1024) if transparent: # set the middle value to zero transparency. # it's probably better if you set alpha on the call using the # color map rather than change a single value. ncmap._init() ind = np.max( [np.argmax(ncmap._lut.T[i]) for i in range(len(ncmap._lut.T) - 1)]) ncmap._lut[ind][-1] = 0 return ncmap
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
def hist2d(ax, x, y, sigs=[1], color="k", pcolor="grey", *args, **kwargs): """ Plot a 2-D histogram of samples. """ extent = kwargs.get("extent", None) if extent is None: extent = [[x.min(), x.max()], [y.min(), y.max()]] bins = 45 linewidths = 0.8 # Instead of this, create a color map with the peak color. if pcolor != "grey": # print(pcolor) r,g,b = pcolor # print(r, g, b) # Make our custom intensity scale dict_cmap = {'red':[(0.0, r, r), (1.0, 1.0, 1.0)], 'green': [(0.0, g, g), (1.0, 1.0, 1.0)], 'blue': [(0.0, b, b), (1.0, 1.0, 1.0)]} cmap = LSC("new", dict_cmap) else: cmap = cm.get_cmap("gray") cmap._init() # The only thing he's changing here is the alpha interpolator, I think # He's saying that we will have everything be black, and change alpha from 1 to 0.0 # cmap._lut[:-3, :-1] = 0. cmap._lut[:-3, -1] = np.linspace(1, 0, cmap.N) # N is the number of levels in the colormap # Dunno what _lut is # look up table # Is he setting everything below some value to 0? X = np.linspace(extent[0][0], extent[0][1], bins + 1) # Y = np.linspace(extent[1][0], extent[1][1], bins + 1) Y = np.logspace(np.log10(extent[1][0]), np.log10(extent[1][1]), bins + 1) try: H, X, Y = np.histogram2d(x.flatten(), y.flatten(), bins=(X, Y)) except ValueError: raise ValueError("It looks like at least one of your sample columns " "have no dynamic range. You could try using the " "`extent` argument.") # V = 1.0 - np.exp(-0.5 * np.array([1.0, 2.0, 3.0]) ** 2) V = 1.0 - np.exp(-0.5 * np.array(sigs) ** 2) #V = 1.0 - np.exp(-0.5 * np.arange(0.5, 2.1, 0.5) ** 2) Hflat = H.flatten() inds = np.argsort(Hflat)[::-1] Hflat = Hflat[inds] sm = np.cumsum(Hflat) sm /= sm[-1] for i, v0 in enumerate(V): try: V[i] = Hflat[sm <= v0][-1] except: V[i] = Hflat[0] X1, Y1 = 0.5 * (X[1:] + X[:-1]), 0.5 * (Y[1:] + Y[:-1]) X, Y = X[:-1], Y[:-1] # Plot the contours ax.pcolor(X, Y, H.max() - H.T, cmap=cmap) ax.contour(X1, Y1, H.T, V, colors=color, linewidths=linewidths)