Skip to content

Commit 5cea8a7

Browse files
authored
Merge pull request #745 from effigies/fix/purge_vtk
FIX: Use nilearn plot_surf over surfplot
2 parents 5f2dc27 + 0899e6a commit 5cea8a7

File tree

5 files changed

+65
-31
lines changed

5 files changed

+65
-31
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ jobs:
104104
name: Setup git-annex, DataLad & TemplateFlow
105105
command: |
106106
apk update && apk add --no-cache coreutils
107-
conda install -y -c conda-forge datalad git wget
107+
conda install -y -c conda-forge python=*=*cpython datalad git wget
108108
python -m pip install --no-cache-dir -U datalad-osf templateflow
109109
git config --global user.name 'NiPreps Bot'
110110
git config --global user.email '[email protected]'

.github/workflows/pythonpackage.yml

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,14 @@ jobs:
114114
runs-on: ubuntu-latest
115115
strategy:
116116
matrix:
117-
python-version: [3.7, 3.8, 3.9]
117+
python-version: [3.7, 3.8, 3.9, "3.10"]
118118
install: [repo]
119119
include:
120-
- python-version: 3.9
120+
- python-version: 3
121121
install: sdist
122-
- python-version: 3.9
122+
- python-version: 3
123123
install: wheel
124-
- python-version: 3.9
124+
- python-version: 3
125125
install: editable
126126

127127
env:
@@ -196,15 +196,9 @@ jobs:
196196
runs-on: ubuntu-latest
197197
strategy:
198198
matrix:
199-
python-version: [3.7, 3.8, 3.9]
199+
python-version: [3.7, 3.8, 3.9, "3.10"]
200200
install: [repo]
201201
pip-flags: ['--pre']
202-
include:
203-
# VTK won't build official 3.10 wheels before 9.2.0
204-
# PyVista has posted dev versions, at least
205-
- python-version: '3.10'
206-
install: repo
207-
pip-flags: '--pre --find-links https://wheels.pyvista.org/'
208202

209203
env:
210204
INSTALL_TYPE: ${{ matrix.install }}

niworkflows/tests/generate_data.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ def create_geometry_map():
3939
brain_structure=name,
4040
)
4141
setattr(bm, attr, indices)
42+
if model_type == "CIFTI_MODEL_TYPE_SURFACE":
43+
# define total vertices for surface models
44+
setattr(bm, "surface_number_of_vertices", 32492)
4245
index_offset += len(data)
4346
brain_models.append(bm)
4447
timeseries = np.column_stack((timeseries, data.T))

niworkflows/viz/plots.py

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -975,7 +975,7 @@ def cifti_surfaces_plot(
975975
surface_type="inflated",
976976
clip_range=(0, None),
977977
output_file=None,
978-
**splt_kwargs,
978+
**kwargs,
979979
):
980980
"""
981981
Plots a CIFTI-2 dense timeseries onto left/right mesh surfaces.
@@ -995,8 +995,8 @@ def cifti_surfaces_plot(
995995
output_file: :obj:`str` or :obj:`None`
996996
Path where the output figure should be saved. If this is not defined,
997997
then the figure will be returned.
998-
splt_kwargs : dict
999-
Keyword arguments for :obj:`surfplot.Plot`
998+
kwargs : dict
999+
Keyword arguments for :obj:`nilearn.plotting.plot_surf`
10001000
10011001
Outputs
10021002
-------
@@ -1005,8 +1005,7 @@ def cifti_surfaces_plot(
10051005
output_file: :obj:`str`
10061006
The file where the figure is saved.
10071007
"""
1008-
import surfplot as splt
1009-
from surfplot.utils import add_fslr_medial_wall
1008+
from nilearn.plotting import plot_surf
10101009

10111010
def get_surface_meshes(density, surface_type):
10121011
import templateflow.api as tf
@@ -1036,28 +1035,67 @@ def get_surface_meshes(density, surface_type):
10361035
# as potential nonsteady states
10371036
data = img.dataobj[5:20].mean(axis=0)
10381037

1039-
cortex_data = _concat_brain_struct_data((left_cortex, right_cortex), data)
1040-
if density == "32k" and len(cortex_data) != 59412:
1038+
counts = (left_cortex.index_count, right_cortex.index_count)
1039+
if density == "32k" and counts != (29696, 29716):
10411040
raise ValueError("Cortex data is not in fsLR space")
1041+
10421042
# medial wall needs to be added back in
1043-
cortex_data = add_fslr_medial_wall(cortex_data)
1043+
lh_data = np.full(left_cortex.surface_number_of_vertices, np.nan)
1044+
rh_data = np.full(right_cortex.surface_number_of_vertices, np.nan)
1045+
lh_data[left_cortex.vertex_indices] = _concat_brain_struct_data([left_cortex], data)
1046+
rh_data[right_cortex.vertex_indices] = _concat_brain_struct_data([right_cortex], data)
1047+
10441048
if clip_range:
1045-
cortex_data = np.clip(cortex_data, clip_range[0], clip_range[1], out=cortex_data)
1049+
lh_data = np.clip(lh_data, clip_range[0], clip_range[1], out=lh_data)
1050+
rh_data = np.clip(rh_data, clip_range[0], clip_range[1], out=rh_data)
1051+
mn, mx = clip_range
1052+
else:
1053+
mn, mx = None, None
10461054

1047-
lh_data, rh_data = np.array_split(cortex_data, 2)
1055+
if mn is None:
1056+
mn = np.min(data)
1057+
if mx is None:
1058+
mx = np.max(data)
1059+
1060+
cmap = kwargs.pop('cmap', 'YlOrRd_r')
1061+
cbar_map = cm.ScalarMappable(norm=Normalize(mn, mx), cmap=cmap)
1062+
1063+
# Make background maps that rescale to a medium gray
1064+
lh_bg = np.zeros(lh_data.shape, 'int8')
1065+
rh_bg = np.zeros(rh_data.shape, 'int8')
1066+
lh_bg[:2] = [3, -2]
1067+
rh_bg[:2] = [3, -2]
10481068

1049-
# Build the figure
10501069
lh_mesh, rh_mesh = get_surface_meshes(density, surface_type)
1051-
p = splt.Plot(
1052-
surf_lh=lh_mesh, surf_rh=rh_mesh, layout=splt_kwargs.pop("layout", "row"), **splt_kwargs
1053-
)
1054-
p.add_layer({'left': lh_data, 'right': rh_data}, cmap='YlOrRd_r')
1055-
figure = p.build() # figsize - leave default?
1070+
lh_kwargs = dict(surf_mesh=lh_mesh, surf_map=lh_data, bg_map=lh_bg)
1071+
rh_kwargs = dict(surf_mesh=rh_mesh, surf_map=rh_data, bg_map=rh_bg)
1072+
1073+
# Build the figure
1074+
figure = plt.figure(figsize=plt.figaspect(0.25), constrained_layout=True)
1075+
for i, view in enumerate(('lateral', 'medial')):
1076+
for j, hemi in enumerate(('left', 'right')):
1077+
title = f'{hemi.title()} - {view.title()}'
1078+
ax = figure.add_subplot(1, 4, i * 2 + j + 1, projection='3d', rasterized=True)
1079+
hemi_kwargs = (lh_kwargs, rh_kwargs)[j]
1080+
plot_surf(
1081+
hemi=hemi,
1082+
view=view,
1083+
title=title,
1084+
cmap=cmap,
1085+
vmin=mn,
1086+
vmax=mx,
1087+
axes=ax,
1088+
**hemi_kwargs,
1089+
**kwargs
1090+
)
1091+
# plot_surf sets this to 8, which seems a little far out, but 6 starts clipping
1092+
ax.dist = 7
1093+
1094+
figure.colorbar(cbar_map, shrink=0.2, ax=figure.axes, location='bottom')
10561095

10571096
if output_file is not None:
1058-
figure.savefig(output_file, bbox_inches="tight")
1097+
figure.savefig(output_file, bbox_inches="tight", dpi=400)
10591098
plt.close(figure)
1060-
figure = None
10611099
return output_file
10621100

10631101
return figure

setup.cfg

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ install_requires =
4343
scikit-image
4444
scipy
4545
seaborn
46-
surfplot
4746
svgutils >= 0.3.4
4847
transforms3d
4948
templateflow >= 0.7.2

0 commit comments

Comments
 (0)