Skip to content

Commit f410408

Browse files
abukajccluri
authored andcommitted
Error propagation maps (#102)
* 'Fixed `gauss_2d_large()`. `kcsd.validation.csd_profile.gauss_2d_large(seed=63)` does not return NaN anymore. `repeatUntilValid()` decorator has been defined for that purpose. A simple test for the fix provided in the `__main__` section of the module. Note: The issue has not been solved by fixing distribution of the `zs` variable in order to provide backward-compatibility. * 2**32 - 1 included as possible alternative seed in the `kcsd.validation.csd_profile.repeatUntilValid()` decorator. * Protection of `repeatUntilValid()` decorator against (extremely unlikely) neverending loop of seeds. * `repeatUntilValid()` decorator reffactored Seed sequence generation moved to `seedSequence()` generator function. * `seedSequence()` generator function simplified (the generated sequence has changed though). * Remove unnecessary imports According to https://docs.python.org/3/library/builtins.html imports from `builtsin` are unnecessary. As `builtsin` is Python 3 only, their removal increases beckward-compatibility of the package. Fixes #77 * Error Propagation Maps figure I have included code which generates figure with EPMs (Fig. 7 at the moment). Also, `colorblind_friendly` module with definition of colorblind friendly colors is provided, which my code depends on. * Error propagation maps dependencies reduced The code of the `colorblind_friendly` module embedded in (copied into) the script generating error propagation maps. * Saving of figure of error propagation maps The figure is saved as "error_propagation.pdf". * Shabang provided
1 parent ee322b9 commit f410408

2 files changed

Lines changed: 301 additions & 0 deletions

File tree

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Based on
2+
# Color Universal Design (CUD)
3+
# - How to make figures and presentations that are friendly to Colorblind people
4+
#
5+
#
6+
# Masataka Okabe
7+
# Jikei Medial School (Japan)
8+
#
9+
# Kei Ito
10+
# University of Tokyo, Institute for Molecular and Cellular Biosciences (Japan)
11+
# (both are strong protanopes)
12+
# 11.20.2002 (modified on 2.15.2008, 9.24.2008)
13+
# http://jfly.iam.u-tokyo.ac.jp/color/#pallet
14+
15+
import collections
16+
from matplotlib import colors
17+
18+
19+
_Color = collections.namedtuple('_Color', ['red', 'green', 'blue'])
20+
21+
def _html(r, g, b):
22+
return "#{:02X}{:02X}{:02X}".format(r, g, b)
23+
24+
25+
_BLACK = _Color( 0, 0, 0)
26+
_ORANGE = _Color(230, 159, 0)
27+
_SKY_BLUE = _Color( 86, 180, 233)
28+
_GREEN = _Color( 0, 158, 115)
29+
_YELLOW = _Color(240, 228, 66)
30+
_BLUE = _Color( 0, 114, 178)
31+
_VERMILION = _Color(213, 94, 0)
32+
_PURPLE = _Color(204, 121, 167)
33+
34+
BLACK = _html(*_BLACK)
35+
ORANGE = _html(*_ORANGE)
36+
SKY_BLUE = _html(*_SKY_BLUE)
37+
GREEN = _html(*_GREEN)
38+
YELLOW = _html(*_YELLOW)
39+
BLUE = _html(*_BLUE)
40+
VERMILION = _html(*_VERMILION)
41+
PURPLE = _html(*_PURPLE)
42+
43+
def _BipolarColormap(name, negative, positive):
44+
return colors.LinearSegmentedColormap(
45+
name,
46+
{k: [(0.0,) + (getattr(negative, k) / 255.,) * 2,
47+
(0.5, 1.0, 1.0),
48+
(1.0,) + (getattr(positive, k) / 255.,) * 2,]
49+
for k in ['red', 'green', 'blue']})
50+
51+
bwr = _BipolarColormap('cbf.bwr', _BLUE, _VERMILION)
52+
PRGn = _BipolarColormap('cbf.PRGn', _PURPLE, _GREEN)
Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
#!/usr/bin/python3
2+
### BEGIN colorblind_friendly.py ###
3+
# Based on
4+
# Color Universal Design (CUD)
5+
# - How to make figures and presentations that are friendly to Colorblind people
6+
#
7+
#
8+
# Masataka Okabe
9+
# Jikei Medial School (Japan)
10+
#
11+
# Kei Ito
12+
# University of Tokyo, Institute for Molecular and Cellular Biosciences (Japan)
13+
# (both are strong protanopes)
14+
# 11.20.2002 (modified on 2.15.2008, 9.24.2008)
15+
# http://jfly.iam.u-tokyo.ac.jp/color/#pallet
16+
17+
import collections
18+
from matplotlib import colors
19+
20+
21+
_Color = collections.namedtuple('_Color', ['red', 'green', 'blue'])
22+
23+
def _html(r, g, b):
24+
return "#{:02X}{:02X}{:02X}".format(r, g, b)
25+
26+
27+
_BLACK = _Color( 0, 0, 0)
28+
_ORANGE = _Color(230, 159, 0)
29+
_SKY_BLUE = _Color( 86, 180, 233)
30+
_GREEN = _Color( 0, 158, 115)
31+
_YELLOW = _Color(240, 228, 66)
32+
_BLUE = _Color( 0, 114, 178)
33+
_VERMILION = _Color(213, 94, 0)
34+
_PURPLE = _Color(204, 121, 167)
35+
36+
BLACK = _html(*_BLACK)
37+
ORANGE = _html(*_ORANGE)
38+
SKY_BLUE = _html(*_SKY_BLUE)
39+
GREEN = _html(*_GREEN)
40+
YELLOW = _html(*_YELLOW)
41+
BLUE = _html(*_BLUE)
42+
VERMILION = _html(*_VERMILION)
43+
PURPLE = _html(*_PURPLE)
44+
45+
def _BipolarColormap(name, negative, positive):
46+
return colors.LinearSegmentedColormap(
47+
name,
48+
{k: [(0.0,) + (getattr(negative, k) / 255.,) * 2,
49+
(0.5, 1.0, 1.0),
50+
(1.0,) + (getattr(positive, k) / 255.,) * 2,]
51+
for k in ['red', 'green', 'blue']})
52+
53+
bwr = _BipolarColormap('cbf.bwr', _BLUE, _VERMILION)
54+
PRGn = _BipolarColormap('cbf.PRGn', _PURPLE, _GREEN)
55+
### END colorblind_friendly.py ###
56+
57+
import matplotlib.pyplot as plt
58+
from matplotlib.cm import Greys, bwr
59+
from matplotlib import gridspec
60+
61+
import numpy as np
62+
from kcsd import KCSD2D
63+
64+
import figure_properties
65+
66+
plt.rcParams.update({
67+
'xtick.minor.size': 10 - 6.18,
68+
'ytick.minor.size': 10 - 6.18,
69+
})
70+
71+
72+
xmin = 0.0
73+
xmax = 1.0
74+
ymin = 0.0
75+
ymax = 1.0
76+
n_src_init = 1000
77+
R_init = 1.
78+
ext_x = 0.0
79+
ext_y = 0.0
80+
h = 50. # distance between the electrode plane and the CSD plane
81+
conductivity = 1.0 # S/m
82+
83+
csd_at = np.mgrid[0.:1.:100j,
84+
0.:1.:100j]
85+
csd_x, csd_y = csd_at
86+
87+
D = 2 - 1.618
88+
ele_x, ele_y = np.mgrid[0.5 - D: 0.5 + D: 3j,
89+
0.5 - D: 0.5 + D: 3j]
90+
ele_pos = np.vstack((ele_x.flatten(), ele_y.flatten())).T
91+
92+
pots = np.eye(9)
93+
94+
kcsd = KCSD2D(ele_pos, pots, h=h, sigma=conductivity,
95+
xmin=xmin, xmax=xmax,
96+
ymin=ymin, ymax=ymax,
97+
n_src_init=n_src_init,
98+
src_type='gauss',
99+
R_init=R_init)
100+
101+
csd = kcsd.values('CSD')
102+
103+
E = np.array([csd[:, :, i].flatten()
104+
for i in range(csd.shape[-1])])
105+
VAR = np.dot(E.T, E)[np.eye(E.shape[1], dtype=bool)].reshape(int(np.sqrt(E.shape[1])), -1)
106+
107+
108+
109+
FIG_WIDTH = 17.0
110+
FIG_HEIGHT = 6.0
111+
FIG_WSPACE = 5.0
112+
FIG_TOP = 0.9
113+
FIG_BOTTOM = 0.15
114+
FIG_LEFT = 0.05
115+
FIG_RIGHT = 0.95
116+
117+
118+
def maxabs(values):
119+
t_max = np.abs(values).max()
120+
if t_max == 0:
121+
return np.finfo(type(t_max)).eps
122+
123+
return t_max
124+
125+
126+
fig = plt.figure(figsize=(FIG_WIDTH, FIG_HEIGHT),
127+
constrained_layout=False)
128+
129+
gs_fig = gridspec.GridSpec(1, 2,
130+
figure=fig,
131+
wspace=2 * FIG_WSPACE / ((FIG_RIGHT - FIG_LEFT) * FIG_WIDTH - FIG_WSPACE),
132+
left=FIG_LEFT,
133+
right=FIG_RIGHT,
134+
top=FIG_TOP,
135+
bottom=FIG_BOTTOM)
136+
gs1 = gridspec.GridSpecFromSubplotSpec(3, 4,
137+
subplot_spec=gs_fig[0],
138+
width_ratios=[1, 1, 1, 0.2],
139+
**{#'left': 0.1,
140+
#'right': 0.85,
141+
#'top': FIG_TOP,
142+
#'bottom': FIG_BOTTOM,
143+
'wspace': 0.2,
144+
'hspace': 0.2})
145+
146+
gs2 = gridspec.GridSpecFromSubplotSpec(3, 4,
147+
subplot_spec=gs_fig[1],
148+
width_ratios=[1, 1, 1, 0.2],
149+
**{#'left': 0.1,
150+
#'right': 0.85,
151+
#'top': FIG_TOP,
152+
#'bottom': FIG_BOTTOM,
153+
'wspace': 0.2,
154+
'hspace': 0.2})
155+
156+
t_max = maxabs(csd)
157+
levels = np.linspace(-t_max, t_max, 256)
158+
colorbar_ticks = np.linspace(-t_max, t_max, 3, endpoint=True)
159+
ticks = np.linspace(0, 1, 5)
160+
ticklabels = ['{:g}'.format(x) if i % 2 == 0 else ''
161+
for i, x in enumerate(ticks)]
162+
ticks_minor = [x for x in np.linspace(0, 1, 21) if x not in ticks]
163+
164+
X = list(ele_x.flatten())
165+
Y = list(ele_y.flatten())
166+
for y in range(3):
167+
for x in range(3):
168+
ax = fig.add_subplot(gs1[2-y, x])
169+
i = y + x * 3
170+
CSD = csd[:, :, i]
171+
ax.set_aspect('equal')
172+
ax.set_xticks(ticks)
173+
ax.set_xticklabels(ticklabels)
174+
ax.set_xticks(ticks_minor, minor=True)
175+
ax.set_yticks(ticks)
176+
ax.set_yticklabels(ticklabels)
177+
ax.set_yticks(ticks_minor, minor=True)
178+
im = ax.contourf(csd_x, csd_y, CSD, levels=levels, cmap=bwr)
179+
ax.scatter(X[:i] + X[i + 1:],
180+
Y[:i] + Y[i + 1:],
181+
color='k',
182+
marker='x')
183+
ax.plot(X[i:i+1], Y[i:i+1],
184+
markeredgecolor='k',
185+
markerfacecolor='none',
186+
marker='o')
187+
188+
if x == 0:
189+
ax.set_ylabel('Y (mm)')
190+
if y == 2:
191+
ax.text(-0.05,
192+
1.15,
193+
'A',
194+
fontsize=20,
195+
weight='bold',
196+
transform=ax.transAxes)
197+
198+
else:
199+
for tk in ax.get_yticklabels():
200+
tk.set_visible(False)
201+
202+
if y == 0:
203+
ax.set_xlabel('X (mm)')
204+
205+
else:
206+
for tk in ax.get_xticklabels():
207+
tk.set_visible(False)
208+
209+
210+
fig.colorbar(im,
211+
cax=fig.add_subplot(gs1[:, 3]),
212+
orientation='vertical',
213+
format='%.2g',
214+
ticks=colorbar_ticks)
215+
216+
217+
218+
t_max = maxabs(VAR)
219+
220+
levels = np.linspace(0, t_max, 256)
221+
colorbar_ticks = np.linspace(0, t_max, 2, endpoint=True)
222+
ticklabels = ['{:g}'.format(x) for i, x in enumerate(ticks)]
223+
ax = fig.add_subplot(gs2[:3, :3])
224+
225+
ax.set_aspect('equal')
226+
ax.set_xticks(ticks)
227+
ax.set_xticks(ticks_minor, minor=True)
228+
ax.set_yticks(ticks)
229+
ax.set_yticks(ticks_minor, minor=True)
230+
ax.set_ylabel('Y (mm)')
231+
ax.set_xlabel('X (mm)')
232+
im = ax.contourf(csd_x, csd_y, VAR, levels=levels, cmap=Greys)
233+
ax.scatter(X,
234+
Y,
235+
color=VERMILION, #'#{:02X}{:02X}{:02X}'.format(213, 94, 0),
236+
marker='x')
237+
ax.text(-0.05,
238+
1.05,
239+
'B',
240+
fontsize=20,
241+
weight='bold',
242+
transform=ax.transAxes)
243+
fig.colorbar(im,
244+
cax=fig.add_subplot(gs2[:, 3]),
245+
orientation='vertical',
246+
#format='%.2g',
247+
ticks=colorbar_ticks)
248+
249+
fig.savefig('error_propagation.pdf')

0 commit comments

Comments
 (0)