Coverage for nilearn/plotting/surface/surf_plotting.py: 0%

93 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-16 12:32 +0200

1"""Functions for surface visualization.""" 

2 

3from warnings import warn 

4 

5import numpy as np 

6import pandas as pd 

7 

8from nilearn import DEFAULT_DIVERGING_CMAP 

9from nilearn._utils import fill_doc 

10from nilearn._utils.logger import find_stack_level 

11from nilearn._utils.niimg_conversions import check_niimg_3d 

12from nilearn._utils.param_validation import check_params 

13from nilearn.image import get_data 

14from nilearn.plotting._utils import ( 

15 DEFAULT_ENGINE, 

16 check_threshold_not_negative, 

17 create_colormap_from_lut, 

18) 

19from nilearn.plotting.surface._utils import ( 

20 DEFAULT_HEMI, 

21 check_hemispheres, 

22 check_surface_plotting_inputs, 

23 check_views, 

24 get_surface_backend, 

25) 

26from nilearn.surface import load_surf_data, load_surf_mesh, vol_to_surf 

27from nilearn.surface.surface import ( 

28 FREESURFER_DATA_EXTENSIONS, 

29 check_extensions, 

30 check_mesh_is_fsaverage, 

31) 

32 

33# subset of data format extensions supported 

34DATA_EXTENSIONS = ( 

35 "gii", 

36 "gii.gz", 

37 "mgz", 

38) 

39 

40 

41@fill_doc 

42def plot_surf( 

43 surf_mesh=None, 

44 surf_map=None, 

45 bg_map=None, 

46 hemi=DEFAULT_HEMI, 

47 view=None, 

48 engine=DEFAULT_ENGINE, 

49 cmap=None, 

50 symmetric_cmap=None, 

51 colorbar=True, 

52 avg_method=None, 

53 threshold=None, 

54 alpha=None, 

55 bg_on_data=False, 

56 darkness=0.7, 

57 vmin=None, 

58 vmax=None, 

59 cbar_vmin=None, 

60 cbar_vmax=None, 

61 cbar_tick_format="auto", 

62 title=None, 

63 title_font_size=None, 

64 output_file=None, 

65 axes=None, 

66 figure=None, 

67): 

68 """Plot surfaces with optional background and data. 

69 

70 .. versionadded:: 0.3 

71 

72 Parameters 

73 ---------- 

74 %(surf_mesh)s 

75 If `None` is passed, then ``surf_map`` must be a 

76 :obj:`~nilearn.surface.SurfaceImage` instance and the mesh from that 

77 :obj:`~nilearn.surface.SurfaceImage` instance will be used. 

78 

79 surf_map : :obj:`str` or :class:`numpy.ndarray` or \ 

80 :obj:`~nilearn.surface.SurfaceImage` or None, default=None 

81 Data to be displayed on the surface :term:`mesh`. 

82 Can be a file (valid formats are .gii, .mgz, .nii, .nii.gz, or 

83 Freesurfer specific files such as .thickness, .area, .curv, .sulc, 

84 .annot, .label) or a Numpy array with a value for each :term:`vertex` 

85 of the `surf_mesh`, or a :obj:`~nilearn.surface.SurfaceImage` 

86 instance. 

87 If `None` is passed for ``surf_mesh``, then ``surf_map`` must be a 

88 :obj:`~nilearn.surface.SurfaceImage` instance and its mesh will be 

89 used for plotting. 

90 

91 When specified `surf_map` is of type :class:`numpy.ndarray`, to have a 

92 correct view, `hemi` should have a value corresponding to `surf_map` 

93 data. 

94 

95 %(bg_map)s 

96 

97 %(hemi)s 

98 

99 %(view)s 

100 

101 engine : {'matplotlib', 'plotly'}, default='matplotlib' 

102 

103 .. versionadded:: 0.9.0 

104 

105 Selects which plotting engine will be used by ``plot_surf``. 

106 Currently, only ``matplotlib`` and ``plotly`` are supported. 

107 

108 .. note:: 

109 To use the ``plotly`` engine, you need to have ``plotly`` 

110 installed. 

111 

112 .. note:: 

113 To be able to save figures to disk with the ``plotly`` engine, you 

114 need to have ``kaleido`` installed. 

115 

116 .. warning:: 

117 The ``plotly`` engine is new and experimental. Please report bugs 

118 that you may encounter. 

119 

120 %(cmap)s 

121 If `None`, ``matplotlib`` default will be chosen. 

122 

123 symmetric_cmap : :obj:`bool`, default=None 

124 Whether to use a symmetric colormap or not. 

125 

126 .. note:: 

127 This option is currently only implemented for the ``plotly`` 

128 engine. 

129 

130 When using ``plotly`` as engine, ``symmetric_cmap`` will default to 

131 `False` if `None` is passed. 

132 

133 .. versionadded:: 0.9.0 

134 

135 %(colorbar)s 

136 Default=True. 

137 

138 %(avg_method)s 

139 

140 .. note:: 

141 This option is currently only implemented for the ``matplotlib`` 

142 engine. 

143 

144 When using ``matplotlib`` as engine, ``avg_method`` will default to 

145 ``"mean"`` if `None` is passed. 

146 

147 %(threshold)s 

148 Default=None 

149 

150 alpha : :obj:`float` or None, default=None 

151 Alpha level of the :term:`mesh` (not surf_data). 

152 

153 If `'auto'` is chosen, ``alpha`` will default to `0.5` when no 

154 ``bg_map`` is passed and to `1` if a ``bg_map`` is passed. 

155 

156 .. note:: 

157 This option is currently only implemented for the ``matplotlib`` 

158 engine. 

159 

160 When using ``matplotlib`` as engine, ``alpha`` will default to `"auto"` 

161 if `None` is passed. 

162 

163 %(bg_on_data)s 

164 

165 %(darkness)s 

166 Default=1. 

167 

168 %(vmin)s 

169 

170 %(vmax)s 

171 

172 cbar_vmin : :obj:`float` or None, default=None 

173 Lower bound for the colorbar. 

174 If `None`, the value will be set from the data. 

175 

176 .. note:: 

177 This option is currently only implemented for the ``matplotlib`` 

178 engine. 

179 

180 cbar_vmax : :obj:`float` or None, default=None 

181 Upper bound for the colorbar. 

182 If `None`, the value will be set from the data. 

183 

184 .. note:: 

185 This option is currently only implemented for the ``matplotlib`` 

186 engine. 

187 

188 %(cbar_tick_format)s 

189 Default="auto" which will select: 

190 

191 - `'%%.2g'` (scientific notation) with ``matplotlib`` engine. 

192 - `'.1f'` (rounded floats) with ``plotly`` engine. 

193 

194 .. versionadded:: 0.7.1 

195 

196 %(title)s 

197 

198 title_font_size : :obj:`int`, default=None 

199 Size of the title font 

200 

201 .. note:: 

202 This option is currently only implemented for the ``plotly`` 

203 engine. 

204 

205 When using ``plotly`` as engine, ``title_font_size`` will default to 

206 `18` if `None` is passed. 

207 

208 .. versionadded:: 0.9.0 

209 

210 %(output_file)s 

211 

212 axes : instance of matplotlib axes or None, default=None 

213 The axes instance to plot to. The projection must be `"3d"` (e.g., 

214 `figure, axes = plt.subplots(subplot_kw={'projection': "3d"})`, 

215 where axes should be passed.). 

216 If `None`, a new axes is created. 

217 

218 .. note:: 

219 This option is currently only implemented for the ``matplotlib`` 

220 engine. 

221 

222 %(figure)s 

223 

224 .. note:: 

225 This option is currently only implemented for the ``matplotlib`` 

226 engine. 

227 

228 Returns 

229 ------- 

230 fig : :class:`~matplotlib.figure.Figure` or 

231 :class:`~nilearn.plotting.displays.PlotlySurfaceFigure` 

232 The surface figure. If ``engine='matplotlib'`` then a 

233 :class:`~matplotlib.figure.Figure` is returned. 

234 If ``engine='plotly'``, then a 

235 :class:`~nilearn.plotting.displays.PlotlySurfaceFigure` 

236 is returned 

237 

238 See Also 

239 -------- 

240 nilearn.datasets.fetch_surf_fsaverage : For surface data object to be 

241 used as background map for this plotting function. 

242 

243 nilearn.plotting.plot_surf_roi : For plotting statistical maps on brain 

244 surfaces. 

245 

246 nilearn.plotting.plot_surf_stat_map : for plotting statistical maps on 

247 brain surfaces. 

248 

249 nilearn.surface.vol_to_surf : For info on the generation of surfaces. 

250 """ 

251 check_params(locals()) 

252 check_threshold_not_negative(threshold) 

253 surf_map, surf_mesh, bg_map = check_surface_plotting_inputs( 

254 surf_map, surf_mesh, hemi, bg_map 

255 ) 

256 check_extensions(surf_map, DATA_EXTENSIONS, FREESURFER_DATA_EXTENSIONS) 

257 

258 backend = get_surface_backend(engine) 

259 fig = backend._plot_surf( 

260 surf_mesh, 

261 surf_map=surf_map, 

262 bg_map=bg_map, 

263 hemi=hemi, 

264 view=view, 

265 cmap=cmap, 

266 symmetric_cmap=symmetric_cmap, 

267 colorbar=colorbar, 

268 avg_method=avg_method, 

269 threshold=threshold, 

270 alpha=alpha, 

271 bg_on_data=bg_on_data, 

272 darkness=darkness, 

273 vmin=vmin, 

274 vmax=vmax, 

275 cbar_vmin=cbar_vmin, 

276 cbar_vmax=cbar_vmax, 

277 cbar_tick_format=cbar_tick_format, 

278 title=title, 

279 title_font_size=title_font_size, 

280 output_file=output_file, 

281 axes=axes, 

282 figure=figure, 

283 ) 

284 

285 return fig 

286 

287 

288@fill_doc 

289def plot_surf_contours( 

290 surf_mesh=None, 

291 roi_map=None, 

292 hemi=DEFAULT_HEMI, 

293 levels=None, 

294 labels=None, 

295 colors=None, 

296 legend=False, 

297 cmap="tab20", 

298 title=None, 

299 output_file=None, 

300 axes=None, 

301 figure=None, 

302 **kwargs, 

303): 

304 """Plot contours of ROIs on a surface, optionally over a statistical map. 

305 

306 Parameters 

307 ---------- 

308 %(surf_mesh)s 

309 If None is passed, then ``roi_map`` must be a 

310 :obj:`~nilearn.surface.SurfaceImage` instance and the mesh from that 

311 :obj:`~nilearn.surface.SurfaceImage` instance will be used. 

312 

313 roi_map : :obj:`str` or :class:`numpy.ndarray` or \ 

314 :obj:`~nilearn.surface.SurfaceImage` or None, default=None 

315 ROI map to be displayed on the surface mesh, can be a file (valid 

316 formats are .gii, .mgz, or Freesurfer specific files such as 

317 .thickness, .area, .curv, .sulc, .annot, .label) or a Numpy array with 

318 a value for each :term:`vertex` of the `surf_mesh`. 

319 The value at each :term:`vertex` one inside the ROI and zero inside 

320 ROI, or an integer giving the label number for atlases. 

321 If None is passed for ``surf_mesh`` then ``roi_map`` must be a 

322 :obj:`~nilearn.surface.SurfaceImage` instance and its the mesh will be 

323 used for plotting. 

324 

325 When specified `roi_map` is of type :class:`numpy.ndarray`, to have a 

326 correct view, `hemi` should have a value corresponding to `roi_map` 

327 data. 

328 

329 %(hemi)s 

330 It is only used if ``roi_map`` is :obj:`~nilearn.surface.SurfaceImage` 

331 and / or ``surf_mesh`` is :obj:`~nilearn.surface.PolyMesh`. 

332 Otherwise a warning will be displayed. 

333 

334 .. versionadded:: 0.11.0 

335 

336 levels : :obj:`list` of :obj:`int`, or None, default=None 

337 A list of indices of the regions that are to be outlined. 

338 Every index needs to correspond to one index in ``roi_map``. 

339 If `None`, all regions in ``roi_map`` are used. 

340 

341 labels : :obj:`list` of :obj:`str` or None, or None, default=None 

342 A list of labels for the individual regions of interest. 

343 Provide `None` as list entry to skip showing the label of that region. 

344 If `None`, no labels are used. 

345 

346 colors : :obj:`list` of matplotlib color names or RGBA values, or None, 

347 default=None 

348 Colors to be used. 

349 

350 legend : :obj:`bool`, default=False 

351 Whether to plot a legend of region's labels. 

352 

353 %(cmap)s 

354 Default='tab20'. 

355 

356 %(title)s 

357 

358 %(output_file)s 

359 

360 axes : instance of matplotlib axes or None, default=None 

361 The axes instance to plot to. The projection must be `"3d"` (e.g., 

362 `figure, axes = plt.subplots(subplot_kw={'projection': "3d"})`, 

363 where axes should be passed.). 

364 If `None`, uses axes from figure if available, else creates new axes. 

365 

366 %(figure)s 

367 

368 kwargs : extra keyword arguments, optional 

369 Extra keyword arguments passed to :func:`~nilearn.plotting.plot_surf`. 

370 

371 See Also 

372 -------- 

373 nilearn.datasets.fetch_surf_fsaverage : For surface data object to be 

374 used as background map for this plotting function. 

375 

376 nilearn.plotting.plot_surf_stat_map : for plotting statistical maps on 

377 brain surfaces. 

378 

379 nilearn.surface.vol_to_surf : For info on the generation of surfaces. 

380 """ 

381 roi_map, surf_mesh, _ = check_surface_plotting_inputs( 

382 roi_map, surf_mesh, hemi, map_var_name="roi_map" 

383 ) 

384 check_extensions(roi_map, DATA_EXTENSIONS, FREESURFER_DATA_EXTENSIONS) 

385 

386 backend = get_surface_backend(DEFAULT_ENGINE) 

387 fig = backend._plot_surf_contours( 

388 surf_mesh=surf_mesh, 

389 roi_map=roi_map, 

390 hemi=hemi, 

391 levels=levels, 

392 labels=labels, 

393 colors=colors, 

394 legend=legend, 

395 cmap=cmap, 

396 title=title, 

397 output_file=output_file, 

398 axes=axes, 

399 figure=figure, 

400 **kwargs, 

401 ) 

402 return fig 

403 

404 

405@fill_doc 

406def plot_surf_stat_map( 

407 surf_mesh=None, 

408 stat_map=None, 

409 bg_map=None, 

410 hemi=DEFAULT_HEMI, 

411 view=None, 

412 engine=DEFAULT_ENGINE, 

413 cmap=DEFAULT_DIVERGING_CMAP, 

414 symmetric_cmap=None, 

415 colorbar=True, 

416 avg_method=None, 

417 threshold=None, 

418 alpha=None, 

419 bg_on_data=False, 

420 darkness=0.7, 

421 vmin=None, 

422 vmax=None, 

423 symmetric_cbar="auto", 

424 cbar_tick_format="auto", 

425 title=None, 

426 title_font_size=None, 

427 output_file=None, 

428 axes=None, 

429 figure=None, 

430 **kwargs, 

431): 

432 """Plot a stats map on a surface :term:`mesh` with optional background. 

433 

434 .. versionadded:: 0.3 

435 

436 Parameters 

437 ---------- 

438 %(surf_mesh)s 

439 If None is passed, then ``stat_map`` must be a 

440 :obj:`~nilearn.surface.SurfaceImage` instance and the mesh from 

441 that :obj:`~nilearn.surface.SurfaceImage` instance will be used. 

442 

443 stat_map : :obj:`str` or :class:`numpy.ndarray` or None, default=None 

444 Statistical map to be displayed on the surface :term:`mesh`, 

445 can be a file 

446 (valid formats are .gii, .mgz, or 

447 Freesurfer specific files such as 

448 .thickness, .area, .curv, .sulc, .annot, .label) or 

449 a Numpy array with a value for each :term:`vertex` of the `surf_mesh`. 

450 If None is passed for ``surf_mesh`` 

451 then ``stat_map`` 

452 must be a :obj:`~nilearn.surface.SurfaceImage` instance 

453 and its the mesh will be used for plotting. 

454 

455 When specified `surf_map` is of type :class:`numpy.ndarray`, to have a 

456 correct view, `hemi` should have a value corresponding to `surf_map` 

457 data. 

458 

459 %(bg_map)s 

460 

461 %(hemi)s 

462 

463 %(view)s 

464 

465 engine : {'matplotlib', 'plotly'}, default='matplotlib' 

466 

467 .. versionadded:: 0.9.0 

468 

469 Selects which plotting engine will be used by ``plot_surf_stat_map``. 

470 Currently, only ``matplotlib`` and ``plotly`` are supported. 

471 

472 .. note:: 

473 To use the ``plotly`` engine you need to 

474 have ``plotly`` installed. 

475 

476 .. note:: 

477 To be able to save figures to disk with the ``plotly`` 

478 engine you need to have ``kaleido`` installed. 

479 

480 .. warning:: 

481 The ``plotly`` engine is new and experimental. 

482 Please report bugs that you may encounter. 

483 

484 

485 %(cmap)s 

486 default="RdBu_r" 

487 

488 symmetric_cmap : :obj:`bool`, default=None 

489 Whether to use a symmetric colormap or not. 

490 

491 .. note:: 

492 This option is currently only implemented for the ``plotly`` 

493 engine. 

494 

495 When using ``plotly`` as engine, ``symmetric_cmap`` will default to 

496 `False` if `None` is passed. 

497 

498 .. versionadded:: 0.12.0 

499 

500 %(colorbar)s 

501 

502 .. note:: 

503 This function uses a symmetric colorbar for the statistical map. 

504 

505 Default=True. 

506 

507 %(avg_method)s 

508 

509 .. note:: 

510 This option is currently only implemented for the 

511 ``matplotlib`` engine. 

512 

513 When using matplotlib as engine, 

514 `avg_method` will default to ``"mean"`` if ``None`` is passed. 

515 

516 .. versionadded:: 0.10.3dev 

517 

518 %(threshold)s 

519 Default=None 

520 

521 alpha : :obj:`float` or 'auto' or None, default=None 

522 Alpha level of the :term:`mesh` (not the stat_map). 

523 Will default to ``"auto"`` if ``None`` is passed. 

524 If 'auto' is chosen, alpha will default to .5 when no bg_map is 

525 passed and to 1 if a bg_map is passed. 

526 

527 .. note:: 

528 This option is currently only implemented for the 

529 ``matplotlib`` engine. 

530 

531 %(bg_on_data)s 

532 

533 %(darkness)s 

534 Default=1. 

535 

536 .. note:: 

537 This option is currently only implemented for the 

538 ``matplotlib`` engine. 

539 

540 %(vmin)s 

541 

542 %(vmax)s 

543 

544 %(symmetric_cbar)s 

545 

546 %(cbar_tick_format)s 

547 Default="auto" which will select: 

548 

549 - '%%.2g' (scientific notation) with ``matplotlib`` engine. 

550 - '.1f' (rounded floats) with ``plotly`` engine. 

551 

552 .. versionadded:: 0.7.1 

553 

554 %(title)s 

555 

556 title_font_size : :obj:`int`, default=None 

557 Size of the title font (only implemented for the plotly engine). 

558 

559 .. versionadded:: 0.9.0 

560 

561 %(output_file)s 

562 

563 axes : instance of matplotlib axes or None, default=None 

564 The axes instance to plot to. The projection must be '3d' (e.g., 

565 `figure, axes = plt.subplots(subplot_kw={'projection': '3d'})`, 

566 where axes should be passed.). 

567 If None, a new axes is created. 

568 

569 .. note:: 

570 This option is currently only implemented for the 

571 ``matplotlib`` engine. 

572 

573 %(figure)s 

574 

575 .. note:: 

576 This option is currently only implemented for the 

577 ``matplotlib`` engine. 

578 

579 kwargs : :obj:`dict`, optional 

580 Keyword arguments passed to :func:`nilearn.plotting.plot_surf`. 

581 

582 See Also 

583 -------- 

584 nilearn.datasets.fetch_surf_fsaverage: For surface data object to be 

585 used as background map for this plotting function. 

586 

587 nilearn.plotting.plot_surf: For brain surface visualization. 

588 

589 nilearn.surface.vol_to_surf : For info on the generation of surfaces. 

590 """ 

591 check_params(locals()) 

592 check_threshold_not_negative(threshold) 

593 

594 stat_map, surf_mesh, bg_map = check_surface_plotting_inputs( 

595 stat_map, surf_mesh, hemi, bg_map, map_var_name="stat_map" 

596 ) 

597 check_extensions(stat_map, DATA_EXTENSIONS, FREESURFER_DATA_EXTENSIONS) 

598 loaded_stat_map = load_surf_data(stat_map) 

599 

600 backend = get_surface_backend(engine) 

601 # derive symmetric vmin, vmax and colorbar limits depending on 

602 # symmetric_cbar settings 

603 cbar_vmin, cbar_vmax, vmin, vmax = ( 

604 backend._adjust_colorbar_and_data_ranges( 

605 loaded_stat_map, 

606 vmin=vmin, 

607 vmax=vmax, 

608 symmetric_cbar=symmetric_cbar, 

609 ) 

610 ) 

611 

612 fig = plot_surf( 

613 surf_mesh, 

614 surf_map=loaded_stat_map, 

615 bg_map=bg_map, 

616 hemi=hemi, 

617 view=view, 

618 engine=engine, 

619 cmap=cmap, 

620 symmetric_cmap=symmetric_cmap, 

621 colorbar=colorbar, 

622 avg_method=avg_method, 

623 threshold=threshold, 

624 alpha=alpha, 

625 bg_on_data=bg_on_data, 

626 darkness=darkness, 

627 vmin=vmin, 

628 vmax=vmax, 

629 cbar_vmin=cbar_vmin, 

630 cbar_vmax=cbar_vmax, 

631 cbar_tick_format=cbar_tick_format, 

632 title=title, 

633 title_font_size=title_font_size, 

634 output_file=output_file, 

635 axes=axes, 

636 figure=figure, 

637 **kwargs, 

638 ) 

639 return fig 

640 

641 

642@fill_doc 

643def plot_img_on_surf( 

644 stat_map, 

645 surf_mesh="fsaverage5", 

646 mask_img=None, 

647 hemispheres=None, 

648 views=None, 

649 cmap=DEFAULT_DIVERGING_CMAP, 

650 colorbar=True, 

651 threshold=None, 

652 bg_on_data=False, 

653 inflate=False, 

654 vmin=None, 

655 vmax=None, 

656 symmetric_cbar="auto", 

657 cbar_tick_format="%i", 

658 title=None, 

659 output_file=None, 

660 **kwargs, 

661): 

662 """Plot multiple views of plot_surf_stat_map \ 

663 in a single figure. 

664 

665 It projects stat_map into meshes and plots views of 

666 left and right hemispheres. The *views* argument defines the views 

667 that are shown. This function returns the fig, axes elements from 

668 matplotlib unless kwargs sets and output_file, in which case nothing 

669 is returned. 

670 

671 Parameters 

672 ---------- 

673 stat_map : :obj:`str` or :class:`pathlib.Path` or 3D Niimg-like object 

674 See :ref:`extracting_data`. 

675 

676 surf_mesh : :obj:`str`, :obj:`dict`, or None, default='fsaverage5' 

677 If str, either one of the two: 

678 'fsaverage5': the low-resolution fsaverage5 :term:`mesh` (10242 nodes) 

679 'fsaverage': the high-resolution fsaverage :term:`mesh` (163842 nodes) 

680 If dict, a dictionary with keys: ['infl_left', 'infl_right', 

681 'pial_left', 'pial_right', 'sulc_left', 'sulc_right'], where 

682 values are surface :term:`mesh` geometries as accepted 

683 by plot_surf_stat_map. 

684 

685 mask_img : Niimg-like object or None, default=None 

686 The mask is passed to vol_to_surf. 

687 Samples falling out of this mask or out of the image are ignored 

688 during projection of the volume to the surface. 

689 If ``None``, don't apply any mask. 

690 

691 hemispheres : :obj:`list` of :obj:`str`, default=None 

692 Hemispheres to display. 

693 Will default to ``['left', 'right']`` if ``None`` or "both" is passed. 

694 

695 views : :obj:`list` of :obj:`str`, default=None 

696 A list containing all views to display. 

697 The montage will contain as many rows as views specified by 

698 display mode. Order is preserved, and left and right hemispheres 

699 are shown on the left and right sides of the figure. 

700 Will default to ``['lateral', 'medial']`` if ``None`` is passed. 

701 

702 %(cmap)s 

703 Default="RdBu_r". 

704 

705 %(colorbar)s 

706 

707 .. note:: 

708 This function uses a symmetric colorbar for the statistical map. 

709 

710 Default=True. 

711 

712 %(threshold)s 

713 Default=None 

714 

715 %(bg_on_data)s 

716 

717 inflate : :obj:`bool`, default=False 

718 If True, display images in inflated brain. 

719 If False, display images in pial surface. 

720 

721 %(vmin)s 

722 

723 %(vmax)s 

724 

725 %(symmetric_cbar)s 

726 

727 %(cbar_tick_format)s 

728 

729 %(title)s 

730 

731 %(output_file)s 

732 

733 kwargs : :obj:`dict`, optional 

734 keyword arguments passed to plot_surf_stat_map. 

735 

736 .. note:: 

737 Parameters "figure", "axes", and "engine" which are valid for 

738 ``plot_surf_stat_map`` are not valid for ``plot_img_on_surf``. 

739 

740 See Also 

741 -------- 

742 nilearn.datasets.fetch_surf_fsaverage : For surface data object to be 

743 used as the default background map for this plotting function. 

744 

745 nilearn.surface.vol_to_surf : For info on the generation of surfaces. 

746 

747 nilearn.plotting.plot_surf_stat_map : For info on kwargs options 

748 accepted by plot_img_on_surf. 

749 

750 """ 

751 check_params(locals()) 

752 check_threshold_not_negative(threshold) 

753 

754 for arg in ("figure", "axes", "engine"): 

755 if arg in kwargs: 

756 raise ValueError( 

757 f"plot_img_on_surf does not accept {arg} as an argument" 

758 ) 

759 

760 if hemispheres in (None, "both", ["both"]): 

761 hemispheres = ["left", "right"] 

762 if not isinstance(hemispheres, list): 

763 hemispheres = [hemispheres] 

764 hemis = check_hemispheres(hemispheres) 

765 

766 if views is None: 

767 views = ["lateral", "medial"] 

768 modes = check_views(views) 

769 

770 stat_map = check_niimg_3d(stat_map, dtype="auto") 

771 surf_mesh = check_mesh_is_fsaverage(surf_mesh) 

772 

773 mesh_prefix = "infl" if inflate else "pial" 

774 surf = { 

775 "left": surf_mesh[f"{mesh_prefix}_left"], 

776 "right": surf_mesh[f"{mesh_prefix}_right"], 

777 } 

778 texture = { 

779 "left": vol_to_surf( 

780 stat_map, surf_mesh["pial_left"], mask_img=mask_img 

781 ), 

782 "right": vol_to_surf( 

783 stat_map, surf_mesh["pial_right"], mask_img=mask_img 

784 ), 

785 } 

786 

787 backend = get_surface_backend(DEFAULT_ENGINE) 

788 # get vmin and vmax for entire data (all hemis) 

789 _, _, vmin, vmax = backend._adjust_colorbar_and_data_ranges( 

790 get_data(stat_map), 

791 vmin=vmin, 

792 vmax=vmax, 

793 symmetric_cbar=symmetric_cbar, 

794 ) 

795 

796 fig = backend._plot_img_on_surf( 

797 surf, 

798 surf_mesh=surf_mesh, 

799 stat_map=stat_map, 

800 texture=texture, 

801 hemis=hemis, 

802 modes=modes, 

803 bg_on_data=bg_on_data, 

804 inflate=inflate, 

805 output_file=output_file, 

806 title=title, 

807 colorbar=colorbar, 

808 vmin=vmin, 

809 vmax=vmax, 

810 threshold=threshold, 

811 symmetric_cbar=symmetric_cbar, 

812 cmap=cmap, 

813 cbar_tick_format=cbar_tick_format, 

814 **kwargs, 

815 ) 

816 return fig 

817 

818 

819@fill_doc 

820def plot_surf_roi( 

821 surf_mesh=None, 

822 roi_map=None, 

823 bg_map=None, 

824 hemi=DEFAULT_HEMI, 

825 view=None, 

826 engine=DEFAULT_ENGINE, 

827 cmap="gist_ncar", 

828 colorbar=True, 

829 avg_method=None, 

830 threshold=None, 

831 alpha=None, 

832 bg_on_data=False, 

833 darkness=0.7, 

834 vmin=None, 

835 vmax=None, 

836 cbar_tick_format="auto", 

837 title=None, 

838 title_font_size=None, 

839 output_file=None, 

840 axes=None, 

841 figure=None, 

842 **kwargs, 

843): 

844 """Plot ROI on a surface :term:`mesh` with optional background. 

845 

846 .. versionadded:: 0.3 

847 

848 Parameters 

849 ---------- 

850 %(surf_mesh)s 

851 If None is passed, then ``roi_map`` must be a 

852 :obj:`~nilearn.surface.SurfaceImage` instance and the mesh from that 

853 :obj:`~nilearn.surface.SurfaceImage` instance will be used. 

854 

855 roi_map : :obj:`str` or :class:`numpy.ndarray` or \ 

856 :obj:`list` of :class:`numpy.ndarray` or \ 

857 :obj:`~nilearn.surface.SurfaceImage` or None, \ 

858 default=None 

859 ROI map to be displayed on the surface :term:`mesh`, 

860 can be a file 

861 (valid formats are .gii, .mgz, or 

862 Freesurfer specific files such as 

863 .thickness, .area, .curv, .sulc, .annot, .label) or 

864 a Numpy array with a value for each :term:`vertex` of the `surf_mesh` 

865 or a :obj:`~nilearn.surface.SurfaceImage` instance. 

866 The value at each vertex one inside the ROI and zero inside ROI, or an 

867 integer giving the label number for atlases. 

868 If None is passed for ``surf_mesh`` 

869 then ``roi_map`` 

870 must be a :obj:`~nilearn.surface.SurfaceImage` instance 

871 and its the mesh will be used for plotting. 

872 

873 When specified `roi_map` is of type :class:`numpy.ndarray`, to have a 

874 correct view, `hemi` should have a value corresponding to `roi_map` 

875 data. 

876 

877 %(bg_map)s 

878 

879 %(hemi)s 

880 

881 %(view)s 

882 

883 engine : {'matplotlib', 'plotly'}, default='matplotlib' 

884 

885 .. versionadded:: 0.9.0 

886 

887 Selects which plotting engine will be used by ``plot_surf_roi``. 

888 Currently, only ``matplotlib`` and ``plotly`` are supported. 

889 

890 .. note:: 

891 To use the ``plotly`` engine you need to have 

892 ``plotly`` installed. 

893 

894 .. note:: 

895 To be able to save figures to disk with ``plotly`` engine 

896 you need to have ``kaleido`` installed. 

897 

898 .. warning:: 

899 The ``plotly`` engine is new and experimental. 

900 Please report bugs that you may encounter. 

901 

902 %(cmap_lut)s 

903 Default='gist_ncar'. 

904 

905 %(colorbar)s 

906 Default=True 

907 

908 %(avg_method)s 

909 

910 .. note:: 

911 This option is currently only implemented for the 

912 ``matplotlib`` engine. 

913 

914 When using matplotlib as engine, 

915 `avg_method` will default to ``"median"`` if ``None`` is passed. 

916 

917 %(threshold)s 

918 Default=None 

919 

920 .. note:: 

921 By default, the regions that are labeled 0 are not thresholded. 

922 Threshold should be set to a very small number, ex. 1e-14 to 

923 threshold the those 0 labeled regions. 

924 

925 alpha : :obj:`float` or 'auto' or None, default=None 

926 Alpha level of the :term:`mesh` (not surf_data). 

927 When using matplotlib as engine, 

928 `alpha` will default to ``"auto"`` if ``None`` is passed. 

929 If 'auto' is chosen, alpha will default to 0.5 when no bg_map 

930 is passed and to 1 if a bg_map is passed. 

931 

932 .. note:: 

933 This option is currently only implemented for the 

934 ``matplotlib`` engine. 

935 

936 %(bg_on_data)s 

937 

938 %(darkness)s 

939 Default=1. 

940 

941 .. note:: 

942 This option is currently only implemented for the 

943 ``matplotlib`` engine. 

944 

945 %(vmin)s 

946 

947 %(vmax)s 

948 

949 %(cbar_tick_format)s 

950 Default="auto" which defaults to integers format: 

951 

952 - "%%i" for ``matplotlib`` engine. 

953 - "." for ``plotly`` engine. 

954 

955 .. versionadded:: 0.7.1 

956 

957 %(title)s 

958 

959 title_font_size : :obj:`int`, default=None 

960 Size of the title font (only implemented for the plotly engine). 

961 

962 .. versionadded:: 0.9.0 

963 

964 %(output_file)s 

965 

966 axes : Axes instance or None, default=None 

967 The axes instance to plot to. The projection must be '3d' (e.g., 

968 `plt.subplots(subplot_kw={'projection': '3d'})`). 

969 If None, a new axes is created. 

970 

971 .. note:: 

972 This option is currently only implemented for the 

973 ``matplotlib`` engine. 

974 

975 %(figure)s 

976 

977 .. note:: 

978 This option is currently only implemented for the 

979 ``matplotlib`` engine. 

980 

981 kwargs : :obj:`dict`, optional 

982 Keyword arguments passed to :func:`nilearn.plotting.plot_surf`. 

983 

984 See Also 

985 -------- 

986 nilearn.datasets.fetch_surf_fsaverage: For surface data object to be 

987 used as background map for this plotting function. 

988 

989 nilearn.plotting.plot_surf: For brain surface visualization. 

990 

991 nilearn.surface.vol_to_surf : For info on the generation of surfaces. 

992 """ 

993 check_params(locals()) 

994 check_threshold_not_negative(threshold) 

995 roi_map, surf_mesh, bg_map = check_surface_plotting_inputs( 

996 roi_map, surf_mesh, hemi, bg_map 

997 ) 

998 check_extensions(roi_map, DATA_EXTENSIONS, FREESURFER_DATA_EXTENSIONS) 

999 

1000 # preload roi and mesh to determine vmin, vmax and give more useful 

1001 # error messages in case of wrong inputs 

1002 roi = load_surf_data(roi_map) 

1003 

1004 if roi.ndim != 1: 

1005 raise ValueError( 

1006 "roi_map can only have one dimension but has " 

1007 f"{roi.ndim} dimensions" 

1008 ) 

1009 if (roi < 0).any(): 

1010 # TODO raise ValueError in release 0.13 

1011 warn( 

1012 ( 

1013 "Negative values in roi_map will no longer be allowed in" 

1014 " Nilearn version 0.13" 

1015 ), 

1016 DeprecationWarning, 

1017 stacklevel=find_stack_level(), 

1018 ) 

1019 

1020 mesh = load_surf_mesh(surf_mesh) 

1021 if roi.shape[0] != mesh.n_vertices: 

1022 raise ValueError( 

1023 "roi_map does not have the same number of vertices " 

1024 "as the mesh. If you have a list of indices for the " 

1025 "ROI you can convert them into a ROI map like this:\n" 

1026 "roi_map = np.zeros(n_vertices)\n" 

1027 "roi_map[roi_idx] = 1" 

1028 ) 

1029 

1030 idx_not_na = ~np.isnan(roi) 

1031 if vmin is None: 

1032 vmin = float(np.nanmin(roi)) 

1033 if vmax is None: 

1034 vmax = float(1 + np.nanmax(roi)) 

1035 

1036 if not np.array_equal(roi[idx_not_na], roi[idx_not_na].astype(int)): 

1037 # TODO raise ValueError in release 0.13 

1038 warn( 

1039 ( 

1040 "Non-integer values in roi_map will no longer be allowed " 

1041 "in Nilearn version 0.13" 

1042 ), 

1043 DeprecationWarning, 

1044 stacklevel=find_stack_level(), 

1045 ) 

1046 if isinstance(cmap, pd.DataFrame): 

1047 cmap = create_colormap_from_lut(cmap) 

1048 

1049 params = { 

1050 "avg_method": avg_method, 

1051 "cbar_tick_format": cbar_tick_format, 

1052 } 

1053 

1054 backend = get_surface_backend(engine) 

1055 backend._adjust_plot_roi_params(params) 

1056 

1057 fig = backend._plot_surf( 

1058 mesh, 

1059 surf_map=roi, 

1060 bg_map=bg_map, 

1061 hemi=hemi, 

1062 view=view, 

1063 cmap=cmap, 

1064 colorbar=colorbar, 

1065 avg_method=params["avg_method"], 

1066 threshold=threshold, 

1067 alpha=alpha, 

1068 bg_on_data=bg_on_data, 

1069 darkness=darkness, 

1070 vmin=vmin, 

1071 vmax=vmax, 

1072 cbar_tick_format=params["cbar_tick_format"], 

1073 title=title, 

1074 title_font_size=title_font_size, 

1075 output_file=output_file, 

1076 axes=axes, 

1077 figure=figure, 

1078 **kwargs, 

1079 ) 

1080 return fig