Coverage for nilearn/plotting/tests/test_img_plotting/test_plot_stat_map.py: 0%
63 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-16 12:32 +0200
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-16 12:32 +0200
1"""Tests for :func:`nilearn.plotting.plot_stat_map`."""
3# ruff: noqa: ARG001
5import matplotlib.pyplot as plt
6import numpy as np
7import pytest
8from nibabel import Nifti1Image
10from nilearn.conftest import _rng
11from nilearn.datasets import load_mni152_template
12from nilearn.image import get_data
13from nilearn.image.resampling import coord_transform
14from nilearn.plotting import plot_stat_map
15from nilearn.plotting.find_cuts import find_cut_slices
18def test_plot_stat_map_bad_input(matplotlib_pyplot, img_3d_mni, tmp_path):
19 """Test for bad input arguments (cf. #510)."""
20 filename = tmp_path / "temp.png"
22 ax = plt.subplot(111, rasterized=True)
24 plot_stat_map(
25 img_3d_mni,
26 symmetric_cbar=True,
27 output_file=filename,
28 axes=ax,
29 vmax=np.nan,
30 )
33@pytest.mark.parametrize(
34 "params", [{}, {"display_mode": "x", "cut_coords": 3}]
35)
36def test_save_plot_stat_map(matplotlib_pyplot, params, img_3d_mni, tmp_path):
37 """Test saving figure to file in different ways."""
38 filename = tmp_path / "test.png"
40 display = plot_stat_map(img_3d_mni, output_file=filename, **params)
42 assert display is None
44 display = plot_stat_map(img_3d_mni, **params)
46 display.savefig(filename)
49@pytest.mark.parametrize(
50 "display_mode,cut_coords",
51 [("ortho", (80, -120, -60)), ("y", 2), ("yx", None)],
52)
53def test_plot_stat_map_cut_coords_and_display_mode(
54 matplotlib_pyplot, display_mode, cut_coords, img_3d_mni
55):
56 """Smoke-tests for plot_stat_map.
58 Tests different combinations of parameters `cut_coords`
59 and `display_mode`.
60 """
61 plot_stat_map(
62 img_3d_mni,
63 display_mode=display_mode,
64 cut_coords=cut_coords,
65 )
68def test_plot_stat_map_with_masked_image(
69 matplotlib_pyplot, img_3d_mni, affine_mni
70):
71 """Smoke test coordinate finder with mask."""
72 masked_img = Nifti1Image(
73 np.ma.masked_equal(get_data(img_3d_mni), 0),
74 affine_mni,
75 )
77 plot_stat_map(masked_img, display_mode="x")
80@pytest.mark.parametrize(
81 "data",
82 [
83 np.zeros((91, 109, 91)),
84 _rng().standard_normal(size=(91, 109, 91)),
85 ],
86)
87def test_plot_stat_map_threshold(matplotlib_pyplot, data, affine_eye):
88 """Tests plot_stat_map with threshold (see #510)."""
89 plot_stat_map(Nifti1Image(data, affine_eye), threshold=1000, colorbar=True)
92def test_plot_stat_map_threshold_for_affine_with_rotation(
93 matplotlib_pyplot, rng
94):
95 """Tests for plot_stat_map with thresholding and resampling.
97 Threshold was not being applied when affine has a rotation.
98 See https://github.com/nilearn/nilearn/issues/599 for more details.
99 """
100 data = rng.standard_normal(size=(10, 10, 10))
101 # matrix with rotation
102 affine = np.array(
103 [
104 [-3.0, 1.0, 0.0, 1.0],
105 [-1.0, -3.0, 0.0, -2.0],
106 [0.0, 0.0, 3.0, 3.0],
107 [0.0, 0.0, 0.0, 1.0],
108 ]
109 )
110 img = Nifti1Image(data, affine)
112 display = plot_stat_map(
113 img, bg_img=None, threshold=1.0, display_mode="z", cut_coords=1
114 )
116 # Next two lines retrieve the numpy array from the plot
117 ax = next(iter(display.axes.values())).ax
118 plotted_array = ax.images[0].get_array()
119 # Given the high threshold the array should be partly masked
120 assert plotted_array.mask.any()
123@pytest.mark.parametrize(
124 "params",
125 [
126 {},
127 {"symmetric_cbar": True},
128 {"symmetric_cbar": False},
129 {"symmetric_cbar": False, "vmax": 10},
130 {"symmetric_cbar": True, "vmax": 10},
131 ],
132)
133def test_plot_stat_map_colorbar_variations(
134 matplotlib_pyplot, params, img_3d_mni, affine_mni, rng
135):
136 """Smoke test for plot_stat_map with different colorbar configurations."""
137 data_positive = get_data(img_3d_mni)
139 data_negative = -data_positive
140 img_negative = Nifti1Image(data_negative, affine_mni)
142 data_heterogeneous = data_positive * rng.standard_normal(
143 size=data_positive.shape
144 )
145 img_heterogeneous = Nifti1Image(data_heterogeneous, affine_mni)
147 for img in [img_3d_mni, img_negative, img_heterogeneous]:
148 plot_stat_map(img, cut_coords=(80, -120, -60), **params)
151@pytest.mark.parametrize(
152 "shape,direction", [((1, 6, 7), "x"), ((5, 1, 7), "y"), ((5, 6, 1), "z")]
153)
154def test_plot_stat_map_singleton_ax_dim(
155 matplotlib_pyplot, shape, direction, affine_eye
156):
157 """Tests for plot_stat_map and singleton display mode."""
158 plot_stat_map(
159 Nifti1Image(np.ones(shape), affine_eye), None, display_mode=direction
160 )
163def test_outlier_cut_coords(matplotlib_pyplot):
164 """Test to plot a subset of a large set of cuts found for a small area."""
165 bg_img = load_mni152_template(resolution=2)
166 data = np.zeros((79, 95, 79))
167 affine = np.array(
168 [
169 [-2.0, 0.0, 0.0, 78.0],
170 [0.0, 2.0, 0.0, -112.0],
171 [0.0, 0.0, 2.0, -70.0],
172 [0.0, 0.0, 0.0, 1.0],
173 ]
174 )
175 # Color a cube around a corner area:
176 x, y, z = 20, 22, 60
177 x_map, y_map, z_map = coord_transform(x, y, z, np.linalg.inv(affine))
178 data[
179 int(x_map) - 1 : int(x_map) + 1,
180 int(y_map) - 1 : int(y_map) + 1,
181 int(z_map) - 1 : int(z_map) + 1,
182 ] = 1
183 img = Nifti1Image(data, affine)
184 cuts = find_cut_slices(img, n_cuts=20, direction="z")
186 plot_stat_map(img, display_mode="z", cut_coords=cuts[-4:], bg_img=bg_img)
189def test_plotting_functions_with_dim_invalid_input(
190 matplotlib_pyplot, img_3d_mni
191):
192 """Test whether error raises with bad error to input."""
193 with pytest.raises(ValueError):
194 plot_stat_map(img_3d_mni, dim="-10")