📚 The CoCalc Library - books, templates and other resources
License: OTHER
import numpy as np1import matplotlib as mpl2import matplotlib.pyplot as plt3from matplotlib.colors import ListedColormap, colorConverter, LinearSegmentedColormap456cm_cycle = ListedColormap(['#0000aa', '#ff5050', '#50ff50', '#9040a0', '#fff000'])7cm3 = ListedColormap(['#0000aa', '#ff2020', '#50ff50'])8cm2 = ListedColormap(['#0000aa', '#ff2020'])910# create a smooth transition from the first to to the second color of cm311# similar to RdBu but with our red and blue, also not going through white,12# which is really bad for greyscale1314cdict = {'red': [(0.0, 0.0, cm2(0)[0]),15(1.0, cm2(1)[0], 1.0)],1617'green': [(0.0, 0.0, cm2(0)[1]),18(1.0, cm2(1)[1], 1.0)],1920'blue': [(0.0, 0.0, cm2(0)[2]),21(1.0, cm2(1)[2], 1.0)]}2223ReBl = LinearSegmentedColormap("ReBl", cdict)242526def discrete_scatter(x1, x2, y=None, markers=None, s=10, ax=None,27labels=None, padding=.2, alpha=1, c=None, markeredgewidth=None):28"""Adaption of matplotlib.pyplot.scatter to plot classes or clusters.2930Parameters31----------3233x1 : nd-array34input data, first axis3536x2 : nd-array37input data, second axis3839y : nd-array40input data, discrete labels4142cmap : colormap43Colormap to use.4445markers : list of string46List of markers to use, or None (which defaults to 'o').4748s : int or float49Size of the marker5051padding : float52Fraction of the dataset range to use for padding the axes.5354alpha : float55Alpha value for all points.56"""57if ax is None:58ax = plt.gca()5960if y is None:61y = np.zeros(len(x1))6263unique_y = np.unique(y)6465if markers is None:66markers = ['o', '^', 'v', 'D', 's', '*', 'p', 'h', 'H', '8', '<', '>'] * 106768if len(markers) == 1:69markers = markers * len(unique_y)7071if labels is None:72labels = unique_y7374# lines in the matplotlib sense, not actual lines75lines = []7677current_cycler = mpl.rcParams['axes.prop_cycle']7879for i, (yy, cycle) in enumerate(zip(unique_y, current_cycler())):80mask = y == yy81# if c is none, use color cycle82if c is None:83color = cycle['color']84elif len(c) > 1:85color = c[i]86else:87color = c88# use light edge for dark markers89if np.mean(colorConverter.to_rgb(color)) < .4:90markeredgecolor = "grey"91else:92markeredgecolor = "black"9394lines.append(ax.plot(x1[mask], x2[mask], markers[i], markersize=s,95label=labels[i], alpha=alpha, c=color,96markeredgewidth=markeredgewidth,97markeredgecolor=markeredgecolor)[0])9899if padding != 0:100pad1 = x1.std() * padding101pad2 = x2.std() * padding102xlim = ax.get_xlim()103ylim = ax.get_ylim()104ax.set_xlim(min(x1.min() - pad1, xlim[0]), max(x1.max() + pad1, xlim[1]))105ax.set_ylim(min(x2.min() - pad2, ylim[0]), max(x2.max() + pad2, ylim[1]))106107return lines108109110