Skip to content

Commit 7bec3a9

Browse files
committed
fix(cmap): add transparency to the color range around zero
1 parent 5f7654a commit 7bec3a9

File tree

3 files changed

+84
-63
lines changed

3 files changed

+84
-63
lines changed

sdcflows/interfaces/reportlets.py

Lines changed: 4 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from nipype.interfaces.base import File, isdefined
88
from nipype.interfaces.mixins import reporting
99

10+
from ..viz.utils import plot_registration, coolwarm_transparent
11+
1012

1113
class FieldmapReportletInputSpec(reporting.ReportCapableInputSpec):
1214
reference = File(exists=True, mandatory=True, desc='input reference')
@@ -33,7 +35,6 @@ def _run_interface(self, runtime):
3335

3436
def _generate_report(self):
3537
"""Generate a reportlet."""
36-
import numpy as np
3738
NIWORKFLOWS_LOG.info('Generating visual report')
3839

3940
refnii = load_img(self.inputs.reference)
@@ -43,7 +44,6 @@ def _generate_report(self):
4344
cuts = cuts_from_bbox(contour_nii or mask_nii, cuts=self._n_cuts)
4445
fmapdata = fmapnii.get_fdata()
4546
vmax = max(fmapdata.max(), abs(fmapdata.min()))
46-
thres = np.percentile(fmapdata[fmapdata > 0], 5)
4747

4848
# Call composer
4949
compose_view(
@@ -59,67 +59,8 @@ def _generate_report(self):
5959
label='fieldmap (Hz)',
6060
contour=contour_nii,
6161
compress=False,
62-
plot_params={'cmap': 'coolwarm',
63-
'vmax': vmax,
62+
plot_params={'cmap': coolwarm_transparent(),
63+
'vmax': vmax,
6464
'vmin': -vmax}),
6565
out_file=self._out_report
6666
)
67-
68-
def plot_registration(anat_nii, div_id, plot_params=None,
69-
order=('z', 'x', 'y'), cuts=None,
70-
estimate_brightness=False, label=None, contour=None,
71-
compress='auto'):
72-
"""
73-
Plots the foreground and background views
74-
Default order is: axial, coronal, sagittal
75-
"""
76-
from uuid import uuid4
77-
78-
from lxml import etree
79-
from nilearn.plotting import plot_anat
80-
from svgutils.transform import SVGFigure
81-
from niworkflows.viz.utils import robust_set_limits, extract_svg, SVGNS
82-
83-
plot_params = plot_params or {}
84-
85-
# Use default MNI cuts if none defined
86-
if cuts is None:
87-
raise NotImplementedError # TODO
88-
89-
out_files = []
90-
if estimate_brightness:
91-
plot_params = robust_set_limits(anat_nii.get_data().reshape(-1),
92-
plot_params)
93-
94-
# Plot each cut axis
95-
for i, mode in enumerate(list(order)):
96-
plot_params['display_mode'] = mode
97-
plot_params['cut_coords'] = cuts[mode]
98-
if i == 0:
99-
plot_params['title'] = label
100-
else:
101-
plot_params['title'] = None
102-
103-
# Generate nilearn figure
104-
display = plot_anat(anat_nii, **plot_params)
105-
if contour is not None:
106-
display.add_contours(contour, colors='g', levels=[0.5],
107-
linewidths=0.5)
108-
109-
svg = extract_svg(display, compress=compress)
110-
display.close()
111-
112-
# Find and replace the figure_1 id.
113-
try:
114-
xml_data = etree.fromstring(svg)
115-
except etree.XMLSyntaxError as e:
116-
NIWORKFLOWS_LOG.info(e)
117-
return
118-
find_text = etree.ETXPath("//{%s}g[@id='figure_1']" % SVGNS)
119-
find_text(xml_data)[0].set('id', '%s-%s-%s' % (div_id, mode, uuid4()))
120-
121-
svg_fig = SVGFigure()
122-
svg_fig.root = xml_data
123-
out_files.append(svg_fig)
124-
125-
return out_files

sdcflows/viz/__init__.py

Whitespace-only changes.

sdcflows/viz/utils.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
2+
# vi: set ft=python sts=4 ts=4 sw=4 et:
3+
"""Visualization tooling."""
4+
5+
6+
def plot_registration(anat_nii, div_id, plot_params=None,
7+
order=('z', 'x', 'y'), cuts=None,
8+
estimate_brightness=False, label=None, contour=None,
9+
compress='auto'):
10+
"""
11+
Plot the foreground and background views.
12+
13+
Default order is: axial, coronal, sagittal
14+
"""
15+
from uuid import uuid4
16+
17+
from lxml import etree
18+
from nilearn.plotting import plot_anat
19+
from svgutils.transform import SVGFigure
20+
from niworkflows.viz.utils import robust_set_limits, extract_svg, SVGNS
21+
22+
plot_params = plot_params or {}
23+
24+
# Use default MNI cuts if none defined
25+
if cuts is None:
26+
raise NotImplementedError # TODO
27+
28+
out_files = []
29+
if estimate_brightness:
30+
plot_params = robust_set_limits(anat_nii.get_data().reshape(-1),
31+
plot_params)
32+
33+
# Plot each cut axis
34+
for i, mode in enumerate(list(order)):
35+
plot_params['display_mode'] = mode
36+
plot_params['cut_coords'] = cuts[mode]
37+
if i == 0:
38+
plot_params['title'] = label
39+
else:
40+
plot_params['title'] = None
41+
42+
# Generate nilearn figure
43+
display = plot_anat(anat_nii, **plot_params)
44+
if contour is not None:
45+
display.add_contours(contour, colors='g', levels=[0.5],
46+
linewidths=0.5)
47+
48+
svg = extract_svg(display, compress=compress)
49+
display.close()
50+
51+
# Find and replace the figure_1 id.
52+
xml_data = etree.fromstring(svg)
53+
find_text = etree.ETXPath("//{%s}g[@id='figure_1']" % SVGNS)
54+
find_text(xml_data)[0].set('id', '%s-%s-%s' % (div_id, mode, uuid4()))
55+
56+
svg_fig = SVGFigure()
57+
svg_fig.root = xml_data
58+
out_files.append(svg_fig)
59+
60+
return out_files
61+
62+
63+
def coolwarm_transparent():
64+
"""Modify the coolwarm color scale to have full transparency around the middle."""
65+
import numpy as np
66+
import matplotlib.pylab as pl
67+
from matplotlib.colors import ListedColormap
68+
69+
# Choose colormap
70+
cmap = pl.cm.coolwarm
71+
72+
# Get the colormap colors
73+
my_cmap = cmap(np.arange(cmap.N))
74+
75+
# Set alpha
76+
alpha = np.ones(cmap.N)
77+
alpha[128:160] = np.linspace(0, 1, len(alpha[128:160]))
78+
alpha[96:128] = np.linspace(1, 0, len(alpha[96:128]))
79+
my_cmap[:, -1] = alpha
80+
return ListedColormap(my_cmap)

0 commit comments

Comments
 (0)