-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathggseg_python.py
303 lines (252 loc) · 11.5 KB
/
ggseg_python.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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
__version__ = '0.1'
def _svg_parse_(path):
import re
import numpy as np
from matplotlib.path import Path
commands = {'M': Path.MOVETO,
'L': Path.LINETO,
'Q': Path.CURVE3,
'C': Path.CURVE4,
'Z': Path.CLOSEPOLY}
vertices = []
codes = []
cmd_values = re.split("([A-Za-z])", path)[1:] # Split over commands.
for cmd, values in zip(cmd_values[::2], cmd_values[1::2]):
# Numbers are separated either by commas, or by +/- signs (but not at
# the beginning of the string).
if cmd.upper() in ['M', 'L', 'Q', 'C']:
points = [e.split(',') for e in values.split(' ') if e != '']
points = [list(map(float, each)) for each in points]
else:
points = [(0., 0.)]
points = np.reshape(points, (-1, 2))
# if cmd.islower():
# points += vertices[-1][-1]
for i in range(0, len(points)):
codes.append(commands[cmd.upper()])
vertices.append(points)
return np.array(codes), np.concatenate(vertices)
def _add_colorbar_(ax, cmap, norm, ec, labelsize, ylabel):
import matplotlib
from mpl_toolkits.axes_grid1 import make_axes_locatable
divider = make_axes_locatable(ax)
cax = divider.append_axes('right', size='1%', pad=1)
cb1 = matplotlib.colorbar.ColorbarBase(cax, cmap=cmap,
norm=norm,
orientation='vertical',
ticklocation='left')
cb1.ax.tick_params(labelcolor=ec, labelsize=labelsize)
cb1.ax.set_ylabel(ylabel, color=ec, fontsize=labelsize)
def _render_data_(data, wd, cmap, norm, ax, edgecolor):
import os.path as op
import matplotlib.patches as patches
from matplotlib.path import Path
for k, v in data.items():
fp = op.join(wd, k)
if op.isfile(fp):
p = open(fp).read()
codes, verts = _svg_parse_(p)
path = Path(verts, codes)
c = cmap(norm(v))
ax.add_patch(patches.PathPatch(path, facecolor=c,
edgecolor=edgecolor, lw=1))
else:
# print('%s not found' % fp)
pass
def _create_figure_(files, figsize, background, title, fontsize, edgecolor):
import numpy as np
import matplotlib.pyplot as plt
codes, verts = _svg_parse_(' '.join(files))
xmin, ymin = verts.min(axis=0) - 1
xmax, ymax = verts.max(axis=0) + 1
yoff = 0
ymin += yoff
verts = np.array([(x, y + yoff) for x, y in verts])
fig = plt.figure(figsize=figsize, facecolor=background)
ax = fig.add_axes([0, 0, 1, 1], frameon=False, aspect=1,
xlim=(xmin, xmax), # centering
ylim=(ymax, ymin), # centering, upside down
xticks=[], yticks=[]) # no ticks
ax.set_title(title, fontsize=fontsize, y=1.03, x=0.55, color=edgecolor)
return ax
def _render_regions_(files, ax, facecolor, edgecolor):
from matplotlib.path import Path
import matplotlib.patches as patches
codes, verts = _svg_parse_(' '.join(files))
path = Path(verts, codes)
ax.add_patch(patches.PathPatch(path, facecolor=facecolor,
edgecolor=edgecolor, lw=1))
def _get_cmap_(cmap, values, vminmax=[]):
import matplotlib
cmap = matplotlib.cm.get_cmap(cmap)
if vminmax == []:
vmin, vmax = min(values), max(values)
else:
vmin, vmax = vminmax
norm = matplotlib.colors.Normalize(vmin=vmin, vmax=vmax)
return cmap, norm
def plot_dk(data, cmap='Spectral', background='k', edgecolor='w', ylabel='',
figsize=(15, 15), bordercolor='w', vminmax=[], title='',
fontsize=15):
"""Plot cortical ROI data based on a Desikan-Killiany (DK) parcellation.
Parameters
----------
data : dict
Data to be plotted. Should be passed as a dictionary where each key
refers to a region from the cortical Desikan-Killiany atlas. The
full list of applicable regions can be found in the folder
ggseg/data/dk.
cmap : matplotlib colormap, optional
The colormap for specified image.
Default='Spectral'.
vminmax : list, optional
Lower and upper bound for the colormap, passed to matplotlib.colors.Normalize
background : matplotlib color, if not provided, defaults to black
edgecolor : matplotlib color, if not provided, defaults to white
bordercolor : matplotlib color, if not provided, defaults to white
ylabel : str, optional
Label to display next to the colorbar
figsize : list, optional
Dimensions of the final figure, passed to matplotlib.pyplot.figure
title : str, optional
Title displayed above the figure, passed to matplotlib.axes.Axes.set_title
fontsize: int, optional
Relative font size for all elements (ticks, labels, title)
"""
import matplotlib.pyplot as plt
import os.path as op
from glob import glob
import ggseg
wd = op.join(op.dirname(ggseg.__file__), 'data', 'dk')
# A figure is created by the joint dimensions of the whole-brain outlines
whole_reg = ['lateral_left', 'medial_left', 'lateral_right',
'medial_right']
files = [open(op.join(wd, e)).read() for e in whole_reg]
ax = _create_figure_(files, figsize, background, title, fontsize, edgecolor)
# Each region is outlined
reg = glob(op.join(wd, '*'))
files = [open(e).read() for e in reg]
_render_regions_(files, ax, bordercolor, edgecolor)
# For every region with a provided value, we draw a patch with the color
# matching the normalized scale
cmap, norm = _get_cmap_(cmap, data.values(), vminmax=vminmax)
_render_data_(data, wd, cmap, norm, ax, edgecolor)
# DKT regions with no provided values are rendered in gray
data_regions = list(data.keys())
dkt_regions = [op.splitext(op.basename(e))[0] for e in reg]
NA = set(dkt_regions).difference(data_regions).difference(whole_reg)
files = [open(op.join(wd, e)).read() for e in NA]
_render_regions_(files, ax, 'gray', edgecolor)
# A colorbar is added
_add_colorbar_(ax, cmap, norm, edgecolor, fontsize*0.75, ylabel)
plt.show()
def plot_jhu(data, cmap='Spectral', background='k', edgecolor='w', ylabel='',
figsize=(17, 5), bordercolor='w', vminmax=[], title='',
fontsize=15):
"""Plot WM ROI data based on the Johns Hopkins University (JHU) white
matter atlas.
Parameters
----------
data : dict
Data to be plotted. Should be passed as a dictionary where each key
refers to a region from the Johns Hopkins University white Matter
atlas. The full list of applicable regions can be found in the
folder ggseg/data/jhu.
cmap : matplotlib colormap, optional
The colormap for specified image.
Default='Spectral'.
vminmax : list, optional
Lower and upper bound for the colormap, passed to matplotlib.colors.Normalize
background : matplotlib color, if not provided, defaults to black
edgecolor : matplotlib color, if not provided, defaults to white
bordercolor : matplotlib color, if not provided, defaults to white
ylabel : str, optional
Label to display next to the colorbar
figsize : list, optional
Dimensions of the final figure, passed to matplotlib.pyplot.figure
title : str, optional
Title displayed above the figure, passed to matplotlib.axes.Axes.set_title
fontsize: int, optional
Relative font size for all elements (ticks, labels, title)
"""
import matplotlib.pyplot as plt
import ggseg
import os.path as op
from glob import glob
wd = op.join(op.dirname(ggseg.__file__), 'data', 'jhu')
# A figure is created by the joint dimensions of the whole-brain outlines
whole_reg = ['NA']
files = [open(op.join(wd, e)).read() for e in whole_reg]
ax = _create_figure_(files, figsize, background, title, fontsize, edgecolor)
# Each region is outlined
reg = glob(op.join(wd, '*'))
files = [open(e).read() for e in reg]
_render_regions_(files, ax, bordercolor, edgecolor)
# For every region with a provided value, we draw a patch with the color
# matching the normalized scale
cmap, norm = _get_cmap_(cmap, data.values(), vminmax=vminmax)
_render_data_(data, wd, cmap, norm, ax, edgecolor)
# JHU regions with no provided values are rendered in gray
NA = ['CSF']
files = [open(op.join(wd, e)).read() for e in NA]
_render_regions_(files, ax, 'gray', edgecolor)
# A colorbar is added
_add_colorbar_(ax, cmap, norm, edgecolor, fontsize*0.75, ylabel)
plt.show()
def plot_aseg(data, cmap='Spectral', background='k', edgecolor='w', ylabel='',
figsize=(15, 5), bordercolor='w', vminmax=[],
title='', fontsize=15):
"""Plot subcortical ROI data based on the FreeSurfer `aseg` atlas
Parameters
----------
data : dict
Data to be plotted. Should be passed as a dictionary where each key
refers to a region from the FreeSurfer `aseg` atlas. The full list
of applicable regions can be found in the folder ggseg/data/aseg.
cmap : matplotlib colormap, optional
The colormap for specified image.
Default='Spectral'.
vminmax : list, optional
Lower and upper bound for the colormap, passed to matplotlib.colors.Normalize
background : matplotlib color, if not provided, defaults to black
edgecolor : matplotlib color, if not provided, defaults to white
bordercolor : matplotlib color, if not provided, defaults to white
ylabel : str, optional
Label to display next to the colorbar
figsize : list, optional
Dimensions of the final figure, passed to matplotlib.pyplot.figure
title : str, optional
Title displayed above the figure, passed to matplotlib.axes.Axes.set_title
fontsize: int, optional
Relative font size for all elements (ticks, labels, title)
"""
import matplotlib.pyplot as plt
import os.path as op
from glob import glob
import ggseg
wd = op.join(op.dirname(ggseg.__file__), 'data', 'aseg')
reg = [op.basename(e) for e in glob(op.join(wd, '*'))]
# Select data from known regions (prevents colorbar from going wild)
known_values = []
for k, v in data.items():
if k in reg:
known_values.append(v)
whole_reg = ['Coronal', 'Sagittal']
files = [open(op.join(wd, e)).read() for e in whole_reg]
# A figure is created by the joint dimensions of the whole-brain outlines
ax = _create_figure_(files, figsize, background, title, fontsize, edgecolor)
# Each region is outlined
reg = glob(op.join(wd, '*'))
files = [open(e).read() for e in reg]
_render_regions_(files, ax, bordercolor, edgecolor)
# For every region with a provided value, we draw a patch with the color
# matching the normalized scale
cmap, norm = _get_cmap_(cmap, known_values, vminmax=vminmax)
_render_data_(data, wd, cmap, norm, ax, edgecolor)
# The following regions are ignored/displayed in gray
# NA = ['Cerebellum-Cortex', 'Cerebellum-White-Matter', 'Brain-Stem']
# files = [open(op.join(wd, e)).read() for e in NA]
# _render_regions_(files, ax, '#111111', edgecolor)
# A colorbar is added
_add_colorbar_(ax, cmap, norm, edgecolor, fontsize*0.75, ylabel)
plt.show()