Skip to content

Commit c8d944b

Browse files
Add threshold and vmin/vmax to plot_brain_overlay (#211)
* Add threshold and vmin/vmax to plot_brain_overlay * Update __init__.py
1 parent dbfcb95 commit c8d944b

File tree

2 files changed

+47
-36
lines changed

2 files changed

+47
-36
lines changed

naplib/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,5 @@ def set_logging(level: Union[int, str]):
5656
from .data import Data, join_fields, concat
5757
import naplib.naplab
5858

59-
__version__ = "2.3.0"
59+
__version__ = "2.4.0"
6060

naplib/visualization/brain_plots.py

Lines changed: 46 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,18 @@ def _view(hemi, mode: str = "lateral", backend: str = "mpl"):
6969
center = dict(x=0, y=0, z=0)
7070
return eye, center
7171
else:
72-
return (20, 160) if hemi == "lh" else (40, 20)
72+
return (10, 170) if hemi == "lh" else (10, 10)
7373

7474
raise ValueError(f"Unknown `mode`: {mode}.")
7575

7676

77-
def _plot_hemi(hemi, cmap="coolwarm", ax=None, view="best", thresh=None, vmin=None, vmax=None):
77+
def _plot_hemi(hemi, cmap="coolwarm", ax=None, view="best", threshold=None, vmin=None, vmax=None):
7878
surfdist_viz(
7979
*hemi.surf,
8080
hemi.overlay,
8181
*_view(hemi.hemi, mode=view),
8282
cmap=cmap,
83-
threshold=thresh,
83+
threshold=threshold,
8484
alpha=hemi.alpha,
8585
bg_map=hemi.sulc,
8686
bg_on_stat=True,
@@ -93,7 +93,7 @@ def _plot_hemi(hemi, cmap="coolwarm", ax=None, view="best", thresh=None, vmin=No
9393

9494

9595
def plot_brain_overlay(
96-
brain, cmap="coolwarm", ax=None, hemi='both', denorm=False, view="best", cmap_quantile=1.0, **kwargs
96+
brain, cmap="coolwarm", ax=None, hemi='both', view="best", vmin=None, vmax=None, cmap_quantile=1.0, threshold=None, **kwargs
9797
):
9898
"""
9999
Plot brain overlay on the 3D cortical surface using matplotlib.
@@ -111,16 +111,21 @@ def plot_brain_overlay(
111111
hemi : {'both', 'lh', 'rh'}, default='both'
112112
Hemisphere(s) to plot. If 'both', then 2 subplots are created, one for each hemisphere.
113113
Otherwise only one hemisphere is displayed with its overlay.
114-
denorm : bool, default=False
115-
Whether to center the overlay labels around 0 or not before sending to the colormap.
116114
view : {'lateral','medial','frontal','top','best'}, default='best'
117-
Which view to plot for each hemisphere.
115+
Which view to plot for each hemisphere.
116+
vmin : float, optional
117+
Minimum value for colormap. If not given, will use cmap_quantile or range or overlay values.
118+
vmax : float, optional
119+
Maximum value for colormap. If not given, will use cmap_quantile or range or overlay values.
118120
cmap_quantile : float | tuple of floats (optional), default=1.0
119121
If a single float less than 1, will only use the central ``cmap_quantile`` portion of the range
120122
of values to create the vmin and vmax for the colormap. For example, if set to 0.95,
121123
then only the middle 95% of the values will be used to set the range of the colormap. If a tuple,
122124
then it should specify 2 quantiles, one for the vmin and one for the vmax, such as (0.025, 0.975),
123125
which would be equivalent to passing a single value of 0.95.
126+
threshold : positive float, optional
127+
If given, then only values on the overlay which are less -threshold or greater than threshold will
128+
be shown.
124129
**kwargs : kwargs
125130
Any other kwargs to pass to matplotlib.pyplot.figure (such as figsize)
126131
@@ -146,45 +151,51 @@ def plot_brain_overlay(
146151
if hemi in ['both', 'b']:
147152
assert len(ax) == 2
148153

149-
150-
if cmap_quantile is not None:
151-
if isinstance(cmap_quantile, float):
152-
assert cmap_quantile <= 1 and cmap_quantile > 0
153-
cmap_diff = (1.0 - cmap_quantile) / 2.
154-
vmin_l = np.quantile(brain.lh.overlay[brain.lh.overlay!=0], cmap_diff)
155-
vmax_l = np.quantile(brain.lh.overlay[brain.lh.overlay!=0], 1.0 - cmap_diff)
156-
vmin_r = np.quantile(brain.rh.overlay[brain.rh.overlay!=0], cmap_diff)
157-
vmax_r = np.quantile(brain.rh.overlay[brain.rh.overlay!=0], 1.0 - cmap_diff)
158-
elif isinstance(cmap_quantile, tuple):
159-
vmin_l = np.quantile(brain.lh.overlay[brain.lh.overlay!=0], cmap_quantile[0])
160-
vmax_l = np.quantile(brain.lh.overlay[brain.lh.overlay!=0], cmap_quantile[1])
161-
vmin_r = np.quantile(brain.rh.overlay[brain.rh.overlay!=0], cmap_quantile[0])
162-
vmax_r = np.quantile(brain.rh.overlay[brain.rh.overlay!=0], cmap_quantile[1])
154+
if vmin is None or vmax is None:
155+
if cmap_quantile is not None:
156+
if isinstance(cmap_quantile, float):
157+
assert cmap_quantile <= 1 and cmap_quantile > 0
158+
cmap_diff = (1.0 - cmap_quantile) / 2.
159+
vmin_l = np.quantile(brain.lh.overlay[brain.lh.overlay!=0], cmap_diff)
160+
vmax_l = np.quantile(brain.lh.overlay[brain.lh.overlay!=0], 1.0 - cmap_diff)
161+
vmin_r = np.quantile(brain.rh.overlay[brain.rh.overlay!=0], cmap_diff)
162+
vmax_r = np.quantile(brain.rh.overlay[brain.rh.overlay!=0], 1.0 - cmap_diff)
163+
elif isinstance(cmap_quantile, tuple):
164+
vmin_l = np.quantile(brain.lh.overlay[brain.lh.overlay!=0], cmap_quantile[0])
165+
vmax_l = np.quantile(brain.lh.overlay[brain.lh.overlay!=0], cmap_quantile[1])
166+
vmin_r = np.quantile(brain.rh.overlay[brain.rh.overlay!=0], cmap_quantile[0])
167+
vmax_r = np.quantile(brain.rh.overlay[brain.rh.overlay!=0], cmap_quantile[1])
168+
else:
169+
raise ValueError('cmap_quantile must be either a float or a tuple')
163170
else:
164-
raise ValueError('cmap_quantile must be either a float or a tuple')
165-
else:
166-
vmin_l = brain.lh.overlay[brain.lh.overlay!=0].min()
167-
vmax_l = brain.lh.overlay[brain.lh.overlay!=0].max()
168-
vmin_r = brain.rh.overlay[brain.rh.overlay!=0].min()
169-
vmax_r = brain.rh.overlay[brain.rh.overlay!=0].max()
171+
vmin_l = brain.lh.overlay[brain.lh.overlay!=0].min()
172+
vmax_l = brain.lh.overlay[brain.lh.overlay!=0].max()
173+
vmin_r = brain.rh.overlay[brain.rh.overlay!=0].min()
174+
vmax_r = brain.rh.overlay[brain.rh.overlay!=0].max()
170175

171176

172177
# determine vmin and vmax
173178
if hemi in ['both', 'b']:
174-
vmin = min([vmin_l, vmin_r])
175-
vmax = max([vmax_l, vmax_r])
179+
if vmin is None:
180+
vmin = min([vmin_l, vmin_r])
181+
if vmax is None:
182+
vmax = max([vmax_l, vmax_r])
176183
elif hemi in ['left','lh']:
177-
vmin = vmin_l
178-
vmax = vmax_l
184+
if vmin is None:
185+
vmin = vmin_l
186+
if vmax is None:
187+
vmax = vmax_l
179188
elif hemi in ['right','rh']:
180-
vmin = vmin_r
181-
vmax = vmax_r
189+
if vmin is None:
190+
vmin = vmin_r
191+
if vmax is None:
192+
vmax = vmax_r
182193

183194

184195
if ax[0] is not None:
185-
_plot_hemi(brain.lh, cmap, ax[0], view=view, vmin=vmin, vmax=vmax)
196+
_plot_hemi(brain.lh, cmap, ax[0], view=view, vmin=vmin, vmax=vmax, threshold=threshold)
186197
if ax[1] is not None:
187-
_plot_hemi(brain.rh, cmap, ax[1], view=view, vmin=vmin, vmax=vmax)
198+
_plot_hemi(brain.rh, cmap, ax[1], view=view, vmin=vmin, vmax=vmax, threshold=threshold)
188199

189200
return fig, ax
190201

0 commit comments

Comments
 (0)