-
Notifications
You must be signed in to change notification settings - Fork 0
/
plot.py
143 lines (123 loc) · 5.24 KB
/
plot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# -----------------------------------------------------------------------------
# VSOM (Voronoidal Self Organized Map)
# Copyright (c) 2019 Nicolas P. Rougier
#
# Distributed under the terms of the BSD License.
# -----------------------------------------------------------------------------
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.patheffects as path_effects
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
from matplotlib.collections import LineCollection, PolyCollection
def network(ax, som):
"""
Plot network topology in neural space
"""
P,V,E = som.positions, som.voronoi, som.edges
size = 50 * 1000/len(P)
ax.scatter(P[:,0], P[:,1], s=size, ec="k", fc="w", lw=.75)
segments = np.zeros((len(E), 2, 2))
for i in range(len(E)):
segments[i] = P[E[i,0]], P[E[i,1]]
collection = LineCollection(segments, color="k", zorder=-10, lw=1)
ax.add_collection(collection)
collection = LineCollection(V, color="k", linewidth=1.0,
zorder=-20, alpha=0.25)
ax.add_collection(collection)
ax.set_xlim(0,1), ax.set_ylim(0,1)
ax.set_xticks([]), ax.set_yticks([])
def letter(ax, letter):
"""
Plot a single large letter on the bottom left of the axes
"""
text = ax.text(0.05, 0.05, letter, zorder=1000,
fontsize=32, fontweight="bold", transform=ax.transAxes)
text.set_path_effects(
[path_effects.Stroke(linewidth=2, foreground='white'),
path_effects.Normal()])
def activation(ax, som, sample, cmap='plasma', zoom=1.5, vmin=None, vmax=None):
"""
Plot network activation relative to given sample
"""
P, V, E = som.positions, som.voronoi, som.edges
codebook = som.codebook["X"]
D = -np.sqrt(((codebook - sample.ravel())**2).sum(axis=-1))
cmap = matplotlib.cm.get_cmap(cmap)
vvmin = vmin or D.min()
vvmax = vmax or D.max()
norm = matplotlib.colors.Normalize(vmin=vmin, vmax=vmax)
collection = PolyCollection(V, linewidth=1.0,
edgecolors=cmap(norm(D)),
facecolors=cmap(norm(D)))
ax.add_collection(collection)
from scipy.interpolate import griddata
X, Y = np.linspace(0, 1, 512), np.linspace(0, 1, 512)
Z = griddata(P, D, (X[None,:], Y[:,None]), method='nearest')
ax.contour(X, Y, Z, 8, linewidths=0.5, colors='k', alpha=0.75)
if len(sample.shape) == 2:
rows,cols = sample.shape
image = np.zeros((rows,cols,4))
image[:,:,0] = image[:,:,1] = image[:,:,2] = 0
image[:,:,3] = sample
image = OffsetImage(image, zoom=zoom, zorder=20,
interpolation="nearest")
box = AnnotationBbox(image, (0.9,0.9), frameon=True)
ax.add_artist(box)
ax.set_xlim(0,1), ax.set_ylim(0,1)
ax.set_xticks([]), ax.set_yticks([])
def weights_1D(ax, som, cmap='gray'):
P, V, E = som.positions, som.voronoi, som.edges
codebook = som.codebook["X"].ravel()
cmap = matplotlib.cm.get_cmap(cmap)
norm = matplotlib.colors.Normalize(vmin=0, vmax=1)
facecolors = edgecolors = cmap(norm(codebook))
collection = PolyCollection(
V, linewidth=1.0, edgecolors = edgecolors, facecolors = facecolors)
ax.add_collection(collection)
ax.set_xlim(0,1), ax.set_ylim(0,1)
ax.set_xticks([]), ax.set_yticks([])
def weights_2D(ax, som, X):
P = som.codebook["X"].reshape(len(som.codebook),2)
E = som.edges
size = 50 * 1000/len(P)
ax.scatter(P[:,0], P[:,1], s=size, ec="k", fc="w", lw=.75, zorder=50)
ax.scatter(X[:,0], X[:,1], s=5, ec="b", fc="b", alpha=.1, zorder=-50)
segments = np.zeros((len(E), 2, 2))
for i in range(len(E)): segments[i] = P[E[i,0]], P[E[i,1]]
collection = LineCollection(segments, color="k", zorder=-10, lw=1)
ax.add_collection(collection)
ax.set_xlim(0,1), ax.set_ylim(0,1)
ax.set_xticks([]), ax.set_yticks([])
def weights_3D(ax, som):
P, V = som.positions, som.voronoi
codebook = som.codebook["X"]
facecolors = edgecolors = codebook
collection = PolyCollection(
V, linewidth=1.0, edgecolors = edgecolors, facecolors = facecolors)
ax.add_collection(collection)
ax.set_xlim(0,1), ax.set_ylim(0,1)
ax.set_xticks([]), ax.set_yticks([])
def weights_img(ax, som, shape, inverse=False, zoom=0.5, cmap=None):
P, V, E = som.positions, som.voronoi, som.edges
codebook = som.codebook["X"]
if cmap:
labels = np.argmax(som.codebook["Y"], axis=-1)
norm = matplotlib.colors.Normalize(vmin=0,vmax=9)
facecolors = cmap(norm(labels))
else:
faceolors = "w"
if inverse: codebook = 1-codebook
rows, cols = shape
collection = PolyCollection(V, linewidth=0.25, alpha=1.0,
edgecolors="k", facecolors=facecolors)
ax.add_collection(collection)
for position, data in zip(P, codebook):
image = np.zeros((rows,cols,4))
image[:,:,3] = data.reshape(rows,cols)
image = OffsetImage(image,
zoom=zoom, zorder=20, interpolation="nearest")
box = AnnotationBbox(image, position, frameon=False)
ax.add_artist(box)
ax.set_xlim(0,1), ax.set_ylim(0,1)
ax.set_xticks([]), ax.set_yticks([])