Repository: nilearn/nilearn

Issue:
Add flat maps for all fsaverage resolutions
<!--Provide a brief description what you would like changes and why.-->
It feels to me that plotting flat maps is a common thing to do in neuroscience, yet we don't really advertise this in `nilearn` even though it's already possible.

I think we could:
1. include flat maps for both hemispheres for all `fsaverage` resolutions.
We would compute them with [`mris_flatten`](https://surfer.nmr.mgh.harvard.edu/fswiki/mris_flatten) and convert outputs to gifti files
1. add an example using these surfaces

Also, currently, one has to tweak the `view` kwarg to fit the orientation of the flattened surface.
Maybe we could make sure that our maps display nicely when `view` is `lateral`, but this is a minor comment IMHO.

### Benefits to the change

Much plotting, better beautiful, fosterz package swag :tada: 

![Screenshot from 2022-03-02 17-29-41](https://user-images.githubusercontent.com/13835654/156405307-6fc1a875-08b7-49f6-a29e-6635b5190d6b.png)

![Screenshot from 2022-03-02 17-33-34](https://user-images.githubusercontent.com/13835654/156405545-434e3f20-2705-4fdf-a13f-5fa1bc259bd1.png)

Images above were generated with this snippet (I found the [`fsaverage7` flattened gifti files](https://figshare.com/articles/dataset/fsaverage_subject_for_pycortex/9916166) online):

```python
import matplotlib.pyplot as plt
import nibabel as nib
from nilearn import datasets, plotting
import numpy as np

# %%
mesh_path = "/home/alexis/singbrain/fsaverage_flat/fsaverage/surfaces/flat_lh.gii"
mesh = nib.load(mesh_path)
n_voxels = mesh.darrays[0].data.shape[0]

surf_map = np.random.rand(n_voxels)

fs7 = datasets.fetch_surf_fsaverage(mesh="fsaverage7")

# %%
plotting.plot_surf(
    mesh_path,
    surf_map,
    bg_map=fs7.sulc_left,
    bg_on_data=True,
    view="dorsal"
)
plt.show()

# %%
fig = plotting.plot_surf(
    mesh_path,
    surf_map,
    bg_map=fs7.sulc_left,
    bg_on_data=True,
    view="dorsal",
    engine="plotly"
)
_ = fig.show(renderer="nteract")
```



Discussion:
+1 for adding flat maps for plotting.
My impression was that those from pycortex were nicer (for fsaverage). Shouldn't we use those instead ?
Bzw when you plot a flat map, you really need to add a texture depicting sulco-gyral anatomy.
> My impression was that those from pycortex were nicer (for fsaverage). Shouldn't we use those instead ?

I think the one plotted in the examples above comes from pycortex.

> Bzw when you plot a flat map, you really need to add a texture depicting sulco-gyral anatomy.

Yes, that's a must-do!

Resolving patch:
diff --git a/examples/01_plotting/plot_surf_stat_map.py b/examples/01_plotting/plot_surf_stat_map.py
--- a/examples/01_plotting/plot_surf_stat_map.py
+++ b/examples/01_plotting/plot_surf_stat_map.py
@@ -43,6 +43,7 @@
 Destrieux et al, (2010). Automatic parcellation of human cortical gyri and
 sulci using standard anatomical nomenclature. NeuroImage, 53, 1.
 URL http://dx.doi.org/10.1016/j.neuroimage.2010.06.010.
+
 """
 
 ###############################################################################
@@ -72,10 +73,14 @@
 # the file locations
 print('Fsaverage5 pial surface of left hemisphere is at: '
       f"{fsaverage['pial_left']}")
+print('Fsaverage5 flatten pial surface of left hemisphere is at: '
+      f"{fsaverage['flat_left']}")
 print('Fsaverage5 inflated surface of left hemisphere is at: '
       f"{fsaverage['infl_left']}")
 print('Fsaverage5 sulcal depth map of left hemisphere is at: '
       f"{fsaverage['sulc_left']}")
+print('Fsaverage5 curvature map of left hemisphere is at: '
+      f"{fsaverage['curv_left']}")
 
 ###############################################################################
 # Extracting the seed time series
@@ -120,10 +125,35 @@
 
 from nilearn import plotting
 
-plotting.plot_surf_roi(fsaverage['pial_left'], roi_map=pcc_map,
-                       hemi='left', view='medial',
-                       bg_map=fsaverage['sulc_left'], bg_on_data=True,
-                       title='PCC Seed')
+plotting.plot_surf_roi(
+    fsaverage['pial_left'],
+    roi_map=pcc_map,
+    hemi='left',
+    view='medial',
+    bg_map=fsaverage['sulc_left'],
+    bg_on_data=True,
+    title='PCC Seed'
+)
+
+###############################################################################
+# Using a flat mesh can be useful in order to easily locate the area
+# of interest on the cortex. To make this plot easier to read,
+# we use the mesh curvature as a background map.
+
+bg_map = np.sign(surface.load_surf_data(fsaverage['curv_left']))
+# np.sign yields values in [-1, 1]. We rescale the background map
+# such that values are in [0.25, 0.75], resulting in a nicer looking plot.
+bg_map_rescaled = (bg_map + 1) / 4 + 0.25
+
+plotting.plot_surf_roi(
+    fsaverage['flat_left'],
+    roi_map=pcc_map,
+    hemi='left',
+    view='dorsal',
+    bg_map=bg_map_rescaled,
+    bg_on_data=True,
+    title='PCC Seed'
+)
 
 ###############################################################################
 # Display unthresholded stat map with a slightly dimmed background
@@ -161,3 +191,5 @@
                             output_file='plot_surf_stat_map.png')
 
 plotting.show()
+
+# sphinx_gallery_thumbnail_number = 2
diff --git a/nilearn/datasets/struct.py b/nilearn/datasets/struct.py
--- a/nilearn/datasets/struct.py
+++ b/nilearn/datasets/struct.py
@@ -764,6 +764,8 @@ def fetch_surf_fsaverage(mesh='fsaverage5', data_dir=None):
          - 'area_right': Gifti file, right hemisphere area data
          - 'curv_left': Gifti file, left hemisphere curvature data
          - 'curv_right': Gifti file, right hemisphere curvature data
+         - 'flat_left': Gifti file, left hemisphere flat surface mesh
+         - 'flat_right': Gifti file, right hemisphere flat surface mesh
          - 'pial_left': Gifti file, left hemisphere pial surface mesh
          - 'pial_right': Gifti file, right hemisphere pial surface mesh
          - 'infl_left': Gifti file, left hemisphere inflated pial surface mesh
@@ -826,7 +828,7 @@ def _fetch_surf_fsaverage5():
             data_dir / "{}_{}.gii.gz".format(part, hemi)
         )
         for part in [
-            "area", "curv", "infl", "pial",
+            "area", "curv", "flat", "infl", "pial",
             "sphere", "sulc", "thick", "white"
         ]
         for hemi in ["left", "right"]
@@ -848,17 +850,17 @@ def _fetch_surf_fsaverage(dataset_name, data_dir=None):
     opts = {'uncompress': True}
 
     url = {
-        "fsaverage3": "https://osf.io/asvjk/download",
-        "fsaverage4": "https://osf.io/x2j49/download",
-        "fsaverage6": "https://osf.io/um5ag/download",
-        "fsaverage": "https://osf.io/q7a5k/download",  # fsaverage7
+        "fsaverage3": "https://osf.io/azhdf/download",
+        "fsaverage4": "https://osf.io/28uma/download",
+        "fsaverage6": "https://osf.io/jzxyr/download",
+        "fsaverage": "https://osf.io/svf8k/download",  # fsaverage7
     }[dataset_name]
 
     # List of attributes exposed by the dataset
     dataset_attributes = [
         "{}_{}".format(part, hemi)
         for part in [
-            "area", "curv", "infl", "pial",
+            "area", "curv", "flat", "infl", "pial",
             "sphere", "sulc", "thick", "white"
         ]
         for hemi in ["left", "right"]


Test patch:
diff --git a/nilearn/datasets/tests/test_struct.py b/nilearn/datasets/tests/test_struct.py
--- a/nilearn/datasets/tests/test_struct.py
+++ b/nilearn/datasets/tests/test_struct.py
@@ -232,7 +232,7 @@ def test_fetch_surf_fsaverage(mesh, tmp_path, request_mocker):
     mesh_attributes = {
         "{}_{}".format(part, side)
         for part in [
-            "area", "curv", "infl", "pial",
+            "area", "curv", "flat", "infl", "pial",
             "sphere", "sulc", "thick", "white"
         ]
         for side in ["left", "right"]
@@ -240,10 +240,10 @@ def test_fetch_surf_fsaverage(mesh, tmp_path, request_mocker):
 
     # Mock fsaverage3, 4, 6, 7 download (with actual url)
     fs_urls = [
-        "https://osf.io/asvjk/download",
-        "https://osf.io/x2j49/download",
-        "https://osf.io/um5ag/download",
-        "https://osf.io/q7a5k/download",
+        "https://osf.io/azhdf/download",
+        "https://osf.io/28uma/download",
+        "https://osf.io/jzxyr/download",
+        "https://osf.io/svf8k/download",
     ]
     for fs_url in fs_urls:
         request_mocker.url_mapping[fs_url] = list_to_archive(