Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ENH] Add avg_method to plot_surf_stat_map #4298

Merged
merged 7 commits into from
Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/changes/latest.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@ Fixes
Enhancements
------------

- :bdg-success:`API` Add an ``avg_method`` parameter to :func:`nilearn.plotting.plot_surf_stat_map` (:gh:`4298` by `Rémi Gau`_).

Changes
-------

- :bdg-dark:`Code` Throw warnings when passing parameters to surface plotting functions that are not used by the plolty engine (:gh:`4298` by `Rémi Gau`_).
- :bdg-primary:`Doc` Render examples of GLM and masker reports as part of the documentation (:gh:`4267` and :gh:`4295` by `Rémi Gau`_).
- :bdg-dark:`Code` Improve colorbar size and labels in mosaic display (:gh:`4284` by `Rémi Gau`_).
- :bdg-primary:`Doc` Render the description of the templates, atlases and datasets of the :mod:`nilearn.datasets` as part of the documentation (:gh:`4232` by `Rémi Gau`_).
Expand Down
3 changes: 2 additions & 1 deletion nilearn/_utils/docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
docdict[
"avg_method"
] = """
avg_method : {"mean", "median", "min", "max", custom function}, default="mean"
avg_method : {"mean", "median", "min", "max", custom function, None}, \
default=None
How to average vertex values to derive the face value:

- `mean`: results in smooth boundaries
Expand Down
71 changes: 58 additions & 13 deletions nilearn/plotting/surf_plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@
def plot_surf(surf_mesh, surf_map=None, bg_map=None,
hemi='left', view='lateral', engine='matplotlib',
cmap=None, symmetric_cmap=False, colorbar=False,
avg_method='mean', threshold=None, alpha='auto',
avg_method=None, threshold=None, alpha=None,
bg_on_data=False, darkness=.7, vmin=None, vmax=None,
cbar_vmin=None, cbar_vmax=None, cbar_tick_format="auto",
title=None, title_font_size=18, output_file=None, axes=None,
Expand Down Expand Up @@ -724,6 +724,7 @@

alpha : float or 'auto', default='auto'
Alpha level of the :term:`mesh` (not surf_data).
Will default to ``"auto"`` of ``None`` is passed.
If 'auto' is chosen, alpha will default to 0.5 when no bg_map
is passed and to 1 if a bg_map is passed.

Expand Down Expand Up @@ -802,6 +803,30 @@
nilearn.surface.vol_to_surf : For info on the generation of surfaces.

"""
parameters_not_implemented_in_plotly = {

Check warning on line 806 in nilearn/plotting/surf_plotting.py

View check run for this annotation

Codecov / codecov/patch

nilearn/plotting/surf_plotting.py#L806

Added line #L806 was not covered by tests
"avg_method": avg_method,
"figure": figure,
"axes": axes,
"cbar_vmin": cbar_vmin,
"cbar_vmax": cbar_vmax,
"alpha": alpha
}
if engine == 'plotly':
for parameter, value in parameters_not_implemented_in_plotly.items():
if value is not None:
warn(

Check warning on line 817 in nilearn/plotting/surf_plotting.py

View check run for this annotation

Codecov / codecov/patch

nilearn/plotting/surf_plotting.py#L817

Added line #L817 was not covered by tests
(f"'{parameter}' is not implemented "
"for the plotly engine.\n"
f"Got '{parameter} = {value}'.\n"
f"Use '{parameter} = None' to silence this warning."))

# setting defaults
if avg_method is None:
avg_method = 'mean'

Check warning on line 825 in nilearn/plotting/surf_plotting.py

View check run for this annotation

Codecov / codecov/patch

nilearn/plotting/surf_plotting.py#L825

Added line #L825 was not covered by tests

if alpha is None:
alpha = 'auto'

Check warning on line 828 in nilearn/plotting/surf_plotting.py

View check run for this annotation

Codecov / codecov/patch

nilearn/plotting/surf_plotting.py#L828

Added line #L828 was not covered by tests

coords, faces = load_surf_mesh(surf_mesh)
if engine == 'matplotlib':
if cbar_tick_format == "auto":
Expand Down Expand Up @@ -1005,11 +1030,11 @@
@fill_doc
def plot_surf_stat_map(surf_mesh, stat_map, bg_map=None,
hemi='left', view='lateral', engine='matplotlib',
threshold=None, alpha='auto', vmin=None, vmax=None,
threshold=None, alpha=None, vmin=None, vmax=None,
cmap='cold_hot', colorbar=True, symmetric_cbar="auto",
cbar_tick_format="auto", bg_on_data=False, darkness=.7,
title=None, title_font_size=18, output_file=None,
axes=None, figure=None, **kwargs):
axes=None, figure=None, avg_method=None, **kwargs):
"""Plot a stats map on a surface :term:`mesh` with optional background.

.. versionadded:: 0.3
Expand Down Expand Up @@ -1084,8 +1109,9 @@

Default=True.

alpha : float or 'auto', default='auto'
alpha : float or 'auto' or None, default=None
Alpha level of the :term:`mesh` (not the stat_map).
Will default to ``"auto"`` of ``None`` is passed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, why not keeping auto as a default ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me specify this to say this will happen only when using the matplotlib engine.

Remi-Gau marked this conversation as resolved.
Show resolved Hide resolved
If 'auto' is chosen, alpha will default to .5 when no bg_map is
passed and to 1 if a bg_map is passed.

Expand Down Expand Up @@ -1128,6 +1154,17 @@
This option is currently only implemented for the
``matplotlib`` engine.

%(avg_method)s

.. note::
This option is currently only implemented for the
``matplotlib`` engine.

Default=None.
Will default to ``"mean"`` if ``None`` is passed.

.. versionadded:: 0.10.3dev

kwargs : dict, optional
Keyword arguments passed to :func:`nilearn.plotting.plot_surf`.

Expand All @@ -1151,11 +1188,16 @@
vmax=vmax,
symmetric_cbar=symmetric_cbar,
)
# Set to None the values that are not used by plotly
# to avoid warnings thrown by plot_surf
if engine == "plotly":
cbar_vmin = None
cbar_vmax = None

Check warning on line 1195 in nilearn/plotting/surf_plotting.py

View check run for this annotation

Codecov / codecov/patch

nilearn/plotting/surf_plotting.py#L1194-L1195

Added lines #L1194 - L1195 were not covered by tests

display = plot_surf(
surf_mesh, surf_map=loaded_stat_map,
bg_map=bg_map, hemi=hemi,
view=view, engine=engine, avg_method='mean', threshold=threshold,
view=view, engine=engine, avg_method=avg_method, threshold=threshold,
cmap=cmap, symmetric_cmap=True, colorbar=colorbar,
cbar_tick_format=cbar_tick_format, alpha=alpha,
bg_on_data=bg_on_data, darkness=darkness,
Expand Down Expand Up @@ -1497,9 +1539,9 @@
hemi='left',
view='lateral',
engine='matplotlib',
avg_method='median',
avg_method=None,
threshold=1e-14,
alpha='auto',
alpha=None,
vmin=None,
vmax=None,
cmap='gist_ncar',
Expand Down Expand Up @@ -1566,14 +1608,13 @@
The ``plotly`` engine is new and experimental.
Please report bugs that you may encounter.


%(avg_method)s

.. note::
This option is currently only implemented for the
``matplotlib`` engine.

Default='median'.
Will default to ``"median"`` if None is passed.

threshold : a number or None, default=1e-14
Threshold regions that are labelled 0.
Expand All @@ -1588,10 +1629,11 @@

.. versionadded:: 0.7.1

alpha : float or 'auto', default='auto'
Alpha level of the :term:`mesh` (not the stat_map).
If default, alpha will default to 0.5 when no bg_map is passed
and to 1 if a bg_map is passed.
alpha : float or 'auto' or None, default=None
Alpha level of the :term:`mesh` (not surf_data).
Will default to ``"auto"`` of ``None`` is passed.
Remi-Gau marked this conversation as resolved.
Show resolved Hide resolved
If 'auto' is chosen, alpha will default to 0.5 when no bg_map
is passed and to 1 if a bg_map is passed.

.. note::
This option is currently only implemented for the
Expand Down Expand Up @@ -1641,6 +1683,9 @@
nilearn.surface.vol_to_surf : For info on the generation of surfaces.

"""
if engine == "matplotlib" and avg_method is None:
avg_method = "median"

Check warning on line 1687 in nilearn/plotting/surf_plotting.py

View check run for this annotation

Codecov / codecov/patch

nilearn/plotting/surf_plotting.py#L1687

Added line #L1687 was not covered by tests

# preload roi and mesh to determine vmin, vmax and give more useful error
# messages in case of wrong inputs

Expand Down
40 changes: 36 additions & 4 deletions nilearn/plotting/tests/test_surf_plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,13 +412,22 @@ def test_plot_surf(engine, tmp_path, rng):
mesh = generate_surf()
bg = rng.standard_normal(size=mesh[0].shape[0])

# to avoid extra warnings
alpha = None
cbar_vmin = None
cbar_vmax = None
if engine == "matplotlib":
alpha = 0.5
cbar_vmin = 0
cbar_vmax = 150

# Plot mesh only
plot_surf(mesh, engine=engine)

# Plot mesh with background
plot_surf(mesh, bg_map=bg, engine=engine)
plot_surf(mesh, bg_map=bg, darkness=0.5, engine=engine)
plot_surf(mesh, bg_map=bg, alpha=0.5,
plot_surf(mesh, bg_map=bg, alpha=alpha,
output_file=tmp_path / 'tmp.png', engine=engine)

# Plot different views
Expand All @@ -428,8 +437,8 @@ def test_plot_surf(engine, tmp_path, rng):

# Plot with colorbar
plot_surf(mesh, bg_map=bg, colorbar=True, engine=engine)
plot_surf(mesh, bg_map=bg, colorbar=True, cbar_vmin=0,
cbar_vmax=150, cbar_tick_format="%i", engine=engine)
plot_surf(mesh, bg_map=bg, colorbar=True, cbar_vmin=cbar_vmin,
cbar_vmax=cbar_vmax, cbar_tick_format="%i", engine=engine)
# Save execution time and memory
plt.close()

Expand Down Expand Up @@ -525,6 +534,19 @@ def test_plot_surf_error(engine, rng):
)


@pytest.mark.parametrize("kwargs", [{"avg_method": "mean"}, {"alpha": "auto"}])
def test_plot_surf_warnings_not_implemented_in_plotly(rng, kwargs):
if not is_plotly_installed():
pytest.skip('Plotly is not installed; required for this test.')
mesh = generate_surf()
with pytest.warns(UserWarning,
match='is not implemented for the plotly engine'):
plot_surf(mesh,
surf_map=rng.standard_normal(size=mesh[0].shape[0]),
engine='plotly',
**kwargs)


def test_plot_surf_avg_method_errors(rng):
mesh = generate_surf()
with pytest.raises(
Expand Down Expand Up @@ -596,10 +618,15 @@ def test_plot_surf_stat_map(engine, rng):
bg = rng.standard_normal(size=mesh[0].shape[0])
data = 10 * rng.standard_normal(size=mesh[0].shape[0])

# to avoid extra warnings
alpha = None
if engine == "matplotlib":
alpha = 1

# Plot mesh with stat map
plot_surf_stat_map(mesh, stat_map=data, engine=engine)
plot_surf_stat_map(mesh, stat_map=data, colorbar=True, engine=engine)
plot_surf_stat_map(mesh, stat_map=data, alpha=1, engine=engine)
plot_surf_stat_map(mesh, stat_map=data, alpha=alpha, engine=engine)

# Plot mesh with background and stat map
plot_surf_stat_map(mesh, stat_map=data, bg_map=bg, engine=engine)
Expand Down Expand Up @@ -1166,6 +1193,11 @@ def test_compute_facecolors_matplotlib():
def test_plot_surf_roi_default_arguments(engine, symmetric_cmap, avg_method):
"""Regression test for https://github.com/nilearn/nilearn/issues/3941."""
mesh, roi_map, _ = _generate_data_test_surf_roi()

# To avoid extra warnings
if engine == "plotly":
avg_method = None

plot_surf_roi(mesh, roi_map=roi_map,
engine=engine,
symmetric_cmap=symmetric_cmap,
Expand Down