Repository: nilearn/nilearn

Issue:
plot_stat_map fails with non informative error if image is uint8
Code:

``` python
from nilearn.datasets import fetch_atlas_harvard_oxford
from nilearn.image import index_img
from nilearn.plotting import plot_stat_map


ho = fetch_atlas_harvard_oxford('cort-prob-2mm')
plot_stat_map(index_img(ho.maps, 31))
```

Error: `ValueError: minvalue must be less than or equal to maxvalue`



Discussion:
I am slightly confused. Wasn't https://github.com/nilearn/nilearn/pull/643 supposed to fix that?

Yes. But apparently, it didn't work.

Looks like this [line](https://github.com/nilearn/nilearn/blob/b38d6d4fb27e85e0b9e165fefdd74efb21bc6883/nilearn/plotting/img_plotting.py#L872-L872) is missing the 'auto' dtype. This matters for the vmin/vmax computation which is done next.

The 'auto' dtype in _plot_img_with_bg comes too late ...


Resolving patch:
diff --git a/nilearn/plotting/img_plotting.py b/nilearn/plotting/img_plotting.py
--- a/nilearn/plotting/img_plotting.py
+++ b/nilearn/plotting/img_plotting.py
@@ -869,7 +869,7 @@ def plot_stat_map(stat_map_img, bg_img=MNI152TEMPLATE, cut_coords=None,
     bg_img, black_bg, bg_vmin, bg_vmax = _load_anat(bg_img, dim=dim,
                                                     black_bg=black_bg)
 
-    stat_map_img = _utils.check_niimg_3d(stat_map_img)
+    stat_map_img = _utils.check_niimg_3d(stat_map_img, dtype='auto')
 
     cbar_vmin, cbar_vmax, vmin, vmax = _get_plot_stat_map_params(
         stat_map_img,
@@ -976,7 +976,7 @@ def plot_glass_brain(stat_map_img,
         cmap = cm.cold_hot if black_bg else cm.cold_white_hot
 
     if stat_map_img:
-        stat_map_img = _utils.check_niimg_3d(stat_map_img)
+        stat_map_img = _utils.check_niimg_3d(stat_map_img, dtype='auto')
         if plot_abs:
             cbar_vmin, cbar_vmax, vmin, vmax = \
                         _get_plot_stat_map_params(stat_map_img,


Test patch:
diff --git a/nilearn/plotting/tests/test_img_plotting.py b/nilearn/plotting/tests/test_img_plotting.py
--- a/nilearn/plotting/tests/test_img_plotting.py
+++ b/nilearn/plotting/tests/test_img_plotting.py
@@ -159,16 +159,45 @@ def test_plot_stat_map_threshold_for_uint8():
     # for uint8 data. See https://github.com/nilearn/nilearn/issues/611
     # for more details
     data = 10 * np.ones((10, 10, 10), dtype='uint8')
+    # Having a zero minimum value is important to reproduce
+    # https://github.com/nilearn/nilearn/issues/762
+    data[0, 0, 0] = 0
     affine = np.eye(4)
     img = nibabel.Nifti1Image(data, affine)
     threshold = np.array(5, dtype='uint8')
     display = plot_stat_map(img, bg_img=None, threshold=threshold,
-                            display_mode='z', cut_coords=1)
+                            display_mode='z', cut_coords=[0])
+    # Next two lines retrieve the numpy array from the plot
+    ax = list(display.axes.values())[0].ax
+    plotted_array = ax.images[0].get_array()
+    # Make sure that there is one value masked
+    assert_equal(plotted_array.mask.sum(), 1)
+    # Make sure that the value masked is in the corner. Note that the
+    # axis orientation seem to be flipped, hence (0, 0) -> (-1, 0)
+    assert_true(plotted_array.mask[-1, 0])
+
+
+def test_plot_glass_brain_threshold_for_uint8():
+    # mask was applied in [-threshold, threshold] which is problematic
+    # for uint8 data. See https://github.com/nilearn/nilearn/issues/611
+    # for more details
+    data = 10 * np.ones((10, 10, 10), dtype='uint8')
+    # Having a zero minimum value is important to reproduce
+    # https://github.com/nilearn/nilearn/issues/762
+    data[0, 0] = 0
+    affine = np.eye(4)
+    img = nibabel.Nifti1Image(data, affine)
+    threshold = np.array(5, dtype='uint8')
+    display = plot_glass_brain(img, threshold=threshold,
+                               display_mode='z', colorbar=True)
     # Next two lines retrieve the numpy array from the plot
     ax = list(display.axes.values())[0].ax
     plotted_array = ax.images[0].get_array()
-    # Make sure that no data is masked
-    assert_equal(plotted_array.mask.sum(), 0)
+    # Make sure that there is one value masked
+    assert_equal(plotted_array.mask.sum(), 1)
+    # Make sure that the value masked is in the corner. Note that the
+    # axis orientation seem to be flipped, hence (0, 0) -> (-1, 0)
+    assert_true(plotted_array.mask[-1, 0])
 
 
 def test_save_plot():