Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

📚 The CoCalc Library - books, templates and other resources

132923 views
License: OTHER
1
import numpy as np
2
import matplotlib as mpl
3
import matplotlib.pyplot as plt
4
from matplotlib.colors import ListedColormap, colorConverter, LinearSegmentedColormap
5
6
7
cm_cycle = ListedColormap(['#0000aa', '#ff5050', '#50ff50', '#9040a0', '#fff000'])
8
cm3 = ListedColormap(['#0000aa', '#ff2020', '#50ff50'])
9
cm2 = ListedColormap(['#0000aa', '#ff2020'])
10
11
# create a smooth transition from the first to to the second color of cm3
12
# similar to RdBu but with our red and blue, also not going through white,
13
# which is really bad for greyscale
14
15
cdict = {'red': [(0.0, 0.0, cm2(0)[0]),
16
(1.0, cm2(1)[0], 1.0)],
17
18
'green': [(0.0, 0.0, cm2(0)[1]),
19
(1.0, cm2(1)[1], 1.0)],
20
21
'blue': [(0.0, 0.0, cm2(0)[2]),
22
(1.0, cm2(1)[2], 1.0)]}
23
24
ReBl = LinearSegmentedColormap("ReBl", cdict)
25
26
27
def discrete_scatter(x1, x2, y=None, markers=None, s=10, ax=None,
28
labels=None, padding=.2, alpha=1, c=None, markeredgewidth=None):
29
"""Adaption of matplotlib.pyplot.scatter to plot classes or clusters.
30
31
Parameters
32
----------
33
34
x1 : nd-array
35
input data, first axis
36
37
x2 : nd-array
38
input data, second axis
39
40
y : nd-array
41
input data, discrete labels
42
43
cmap : colormap
44
Colormap to use.
45
46
markers : list of string
47
List of markers to use, or None (which defaults to 'o').
48
49
s : int or float
50
Size of the marker
51
52
padding : float
53
Fraction of the dataset range to use for padding the axes.
54
55
alpha : float
56
Alpha value for all points.
57
"""
58
if ax is None:
59
ax = plt.gca()
60
61
if y is None:
62
y = np.zeros(len(x1))
63
64
unique_y = np.unique(y)
65
66
if markers is None:
67
markers = ['o', '^', 'v', 'D', 's', '*', 'p', 'h', 'H', '8', '<', '>'] * 10
68
69
if len(markers) == 1:
70
markers = markers * len(unique_y)
71
72
if labels is None:
73
labels = unique_y
74
75
# lines in the matplotlib sense, not actual lines
76
lines = []
77
78
current_cycler = mpl.rcParams['axes.prop_cycle']
79
80
for i, (yy, cycle) in enumerate(zip(unique_y, current_cycler())):
81
mask = y == yy
82
# if c is none, use color cycle
83
if c is None:
84
color = cycle['color']
85
elif len(c) > 1:
86
color = c[i]
87
else:
88
color = c
89
# use light edge for dark markers
90
if np.mean(colorConverter.to_rgb(color)) < .4:
91
markeredgecolor = "grey"
92
else:
93
markeredgecolor = "black"
94
95
lines.append(ax.plot(x1[mask], x2[mask], markers[i], markersize=s,
96
label=labels[i], alpha=alpha, c=color,
97
markeredgewidth=markeredgewidth,
98
markeredgecolor=markeredgecolor)[0])
99
100
if padding != 0:
101
pad1 = x1.std() * padding
102
pad2 = x2.std() * padding
103
xlim = ax.get_xlim()
104
ylim = ax.get_ylim()
105
ax.set_xlim(min(x1.min() - pad1, xlim[0]), max(x1.max() + pad1, xlim[1]))
106
ax.set_ylim(min(x2.min() - pad2, ylim[0]), max(x2.max() + pad2, ylim[1]))
107
108
return lines
109
110