Repository: nilearn/nilearn

Issue:
plot_prob_atlas: Different view_types tell very different stories
![contours](https://cloud.githubusercontent.com/assets/634068/13518308/9161d8bc-e1cc-11e5-946a-98a062539589.png)
![filled_contours](https://cloud.githubusercontent.com/assets/634068/13518311/94a8de3a-e1cc-11e5-9fb3-c30504044aff.png)
![continuous](https://cloud.githubusercontent.com/assets/634068/13518313/97cccb30-e1cc-11e5-8d57-d9a020924f84.png)

Ideally, the top 2 plots should be contours of the the bottom-most one, but it looks like the implementations we have use completely different heuristics (disclaimer: i haven't yet looked at the code).



Discussion:
This is on purpose, there is a thresolding by défaut.

Is this "purpose" made explicit anywhere ? This looks ugly.

Its easy for me to _test_ whats going wrong if you provide your atlas and code. Could you provide ?

> Is this "purpose" made explicit anywhere ? This looks ugly.

Finding default that work well on all inputs is hard. You can always
override defaults. But we tuned them on many maps, as you can see here:
http://nilearn.github.io/auto_examples/01_plotting/plot_prob_atlas.html#sphx-glr-auto-examples-01-plotting-plot-prob-atlas-py

The challenge is to have a good behavior that looks OK for most input,
and not that looks great for one input! Remember that you can give an
explicit value for "threshold", and hence control the visualization you
achieve finely.

The code is:

``` python
    if threshold is None:
        # it will use default percentage,
        # strategy is to avoid maximum overlaps as possible
        if view_type == 'contours':
            correction_factor = 1
        elif view_type == 'filled_contours':
            correction_factor = .8
        else:
            correction_factor = .5
        threshold = "%f%%" % (100 * (1 - .2 * correction_factor / n_maps))
```

> You can always override defaults.

No, you cannot here. Thresholding cannot be deactivated unless you give something like `np.neginf`.

> Remember that you can give an explicit value for "threshold", and hence control the visualization you achieve finely.

Yes, you have choice to provide list of `threshold`s for each map if you want `contours` and `filled_contours` as your view_type.

> Yes, you have choice to provide list of thresholds for each map if you want contours and filled_contours as your view_type.

I find that the docstring describes this quite well. Can it be improved?

> I find that the docstring describes this quite well. Can it be improved?

Describe the heuristics in the docstring. Set threshold as `auto` by default and allow deactivation by using `None` (for the moment, `None` = `auto`).

Personnaly, well, I don't use this function but a very similar one that has no thresholding.

> I find that the docstring describes this quite well. Can it be improved?

I think yes it should be improved. I will try to take care of this doc improvement.

> Describe the heuristics in the docstring.

As long as the description is not longer than the code. Sometime, reading
the source is a good option.

> Set threshold as auto by default and allow deactivation by using None
> (for the moment, None = auto).

Maybe (see below).

> Personnaly, well, I don't use this function but a very similar one that has no
> thresholding.

What does not thresholding means for filled_contours, or contours?

> What does not thresholding means for filled_contours, or contours?

Well, it means that I don't apply thresholding other than to remove numerical noise.

> Personnaly, well, I don't use this function but a very similar one that has no thresholding.

This concept works for continuous display I believe. But, I really don't know how to control levels without giving threshold (more or less acts like choosing levels) for contours and filled.

Well, the regions are usually surrounded by a background value that is 0 or some numerical noise.

No. Only for sparse models, which is not what most people run in the wider community. 

Sent from my phone. Please forgive brevity and mis spelling

On Mar 4, 2016, 10:58, at 10:58, Alexandre Abraham notifications@github.com wrote:

> Well, the regions are usually surrounded by a background value that is
> 0 or some numerical noise.
> 
> ---
> 
> Reply to this email directly or view it on GitHub:
> https://github.com/nilearn/nilearn/issues/1047#issuecomment-192215028

> No. Only for sparse models, which is not what most people run in the wider community.

I don't say that we should use that by default, I just answer the question about how to plot contours with no thresholding.


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
@@ -655,7 +655,7 @@ def plot_roi(roi_img, bg_img=MNI152TEMPLATE, cut_coords=None,
 
 
 def plot_prob_atlas(maps_img, anat_img=MNI152TEMPLATE, view_type='auto',
-                    threshold=None, linewidths=2.5, cut_coords=None,
+                    threshold='auto', linewidths=2.5, cut_coords=None,
                     output_file=None, display_mode='ortho',
                     figure=None, axes=None, title=None, annotate=True,
                     draw_cross=True, black_bg='auto', dim=False,
@@ -675,26 +675,33 @@ def plot_prob_atlas(maps_img, anat_img=MNI152TEMPLATE, view_type='auto',
             If nothing is specified, the MNI152 template will be used.
             To turn off background image, just pass "anat_img=False".
         view_type : {'auto', 'contours', 'filled_contours', 'continuous'}, optional
-            By default view_type == 'auto', which means maps are overlayed as
-            contours if number of maps to display are more or
-            overlayed as continuous colors if number of maps are less.
+            By default view_type == 'auto', means maps will be displayed
+            automatically using any one of the three view types. The automatic
+            selection of view type depends on the total number of maps.
             If view_type == 'contours', maps are overlayed as contours
             If view_type == 'filled_contours', maps are overlayed as contours
             along with color fillings inside the contours.
             If view_type == 'continuous', maps are overlayed as continous
             colors irrespective of the number maps.
-        threshold : None, a str or a number, list of either str or number, optional
-            If threshold is a string it must finish with a percent sign,
-            e.g. "25.3%", and it is a percentile. Or if it is a number,
-            it should be a real number, in which case it is the value
-            to threshold at.
-            This option is served for two purposes, for contours and contour
-            fillings threshold serves to select the level of the maps
-            to display and same threshold is applied for color fillings.
-            For continuous overlays this threshold value serves to select
-            the maps which are greater than a given value or list of given
-            values. If None is given, the maps are thresholded with default
-            value.
+        threshold : a str or a number, list of str or numbers, None
+            This parameter is optional and is used to threshold the maps image
+            using the given value or automatically selected value. The values
+            in the image above the threshold level will be visualized.
+            The default strategy, computes a threshold level that seeks to
+            minimize (yet not eliminate completely) the overlap between several
+            maps for a better visualization.
+            The threshold can also be expressed as a percentile over the values
+            of the whole atlas. In that case, the value must be specified as
+            string finishing with a percent sign, e.g., "25.3%".
+            If a single string is provided, the same percentile will be applied
+            over the whole atlas. Otherwise, if a list of percentiles is
+            provided, each 3D map is thresholded with certain percentile
+            sequentially. Length of percentiles given should match the number
+            of 3D map in time (4th) dimension.
+            If a number or a list of numbers, the given value will be used
+            directly to threshold the maps without any percentile calculation.
+            If None, a very small threshold is applied to remove numerical
+            noise from the maps background.
         linewidths : float, optional
             This option can be used to set the boundary thickness of the
             contours.
@@ -785,6 +792,8 @@ def plot_prob_atlas(maps_img, anat_img=MNI152TEMPLATE, view_type='auto',
             view_type = 'continuous'
 
     if threshold is None:
+        threshold = 1e-6
+    elif threshold == 'auto':
         # it will use default percentage,
         # strategy is to avoid maximum overlaps as possible
         if view_type == 'contours':
@@ -814,6 +823,7 @@ def plot_prob_atlas(maps_img, anat_img=MNI152TEMPLATE, view_type='auto',
                               name='threshold')
         # Get rid of background values in all cases
         thr = max(thr, 1e-6)
+
         if view_type == 'continuous':
             display.add_overlay(map_img, threshold=thr,
                                 cmap=cm.alpha_cmap(color))


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
@@ -86,7 +86,7 @@ def test_plot_anat():
         ortho_slicer.savefig(filename)
     finally:
         os.remove(filename)
-    
+
     # Save execution time and memory
     plt.close()
 
@@ -560,6 +560,9 @@ def test_plot_prob_atlas():
     # Testing the 4D plot prob atlas with colormap
     plot_prob_atlas(img, view_type='filled_contours', colorbar=True)
     plt.close()
+    # threshold=None
+    plot_prob_atlas(img, threshold=None)
+    plt.close()
 
 
 def test_get_colorbar_and_data_ranges_with_vmin():