Repository: nilearn/nilearn

Issue:
[BUG] `ValueError` when loading fsaverage surface with `numpy` 1.24.x installed
### Is there an existing issue for this?

- [X] I have searched the existing issues

### Operating system

- [ ] Linux
- [ ] Mac
- [X] Windows

### Operating system version

- Windows 10


### Python version

- [ ] 3.11
- [X] 3.10
- [ ] 3.9
- [ ] 3.8
- [ ] 3.7

### nilearn version

0.10.0

### Expected behavior

Load the data without errors

### Current behavior & error messages

This is what I got:



```bash
File "c:\users\dalth\.spyder-py3\temp.py", line 8, in <module>
    brain_vertices, brain_faces = surface.load_surf_data(fsaverage['pial_left'])

  File "C:\Users\dalth\anaconda3\envs\napari-dev\lib\site-packages\nilearn\surface\surface.py", line 733, in load_surf_data
    data_part = _gifti_img_to_data(gii)

  File "C:\Users\dalth\anaconda3\envs\napari-dev\lib\site-packages\nilearn\surface\surface.py", line 684, in _gifti_img_to_data
    return np.asarray([arr.data for arr in gifti_img.darrays]).T.squeeze()

ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.
```


### Steps and code to reproduce bug

Hi, the example code to reproduce the issue:

```python
from nilearn import datasets, surface

# Fetch datasets - this will download dataset if datasets are not found
nki_dataset = datasets.fetch_surf_nki_enhanced(n_subjects=1)
fsaverage = datasets.fetch_surf_fsaverage()

# Load surface data and resting state time series from nilearn
brain_vertices, brain_faces = surface.load_surf_data(fsaverage['pial_left'])
```

Running the code above with `numpy` 1.24.x installed ends up in a `ValueError`:

```
ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.
```

While using `numpy` 1.23.x shows a `VisibleDeprecationWarning`:

```
\lib\site-packages\nilearn\surface\surface.py:684: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
  return np.asarray([arr.data for arr in gifti_img.darrays]).T.squeeze()
```

Seems like what is missing to be compatible with `numpy` 1.24.x is adding `dtype=object` to the `np.asarray` call at https://github.com/nilearn/nilearn/blob/2b69b29cbdbfce4fa94bf4f07fc15b0c44bc6985/nilearn/surface/surface.py#L684 ?


Discussion:
Thanks @dalthviz for the bug hunt report. 🐛 💥 

I can confirm that I can reproduce the bug and that your fix solves it. 

Will try to open a PR with a regression test ASAP.

Resolving patch:
diff --git a/nilearn/surface/surface.py b/nilearn/surface/surface.py
--- a/nilearn/surface/surface.py
+++ b/nilearn/surface/surface.py
@@ -680,7 +680,13 @@ def _gifti_img_to_data(gifti_img):
     """
     if not gifti_img.darrays:
         raise ValueError('Gifti must contain at least one data array')
-    return np.asarray([arr.data for arr in gifti_img.darrays]).T.squeeze()
+
+    if len(gifti_img.darrays) == 1:
+        return np.asarray([gifti_img.darrays[0].data]).T.squeeze()
+
+    return np.asarray(
+        [arr.data for arr in gifti_img.darrays],
+        dtype=object).T.squeeze()
 
 
 FREESURFER_MESH_EXTENSIONS = ("orig",


Test patch:
diff --git a/nilearn/surface/tests/test_surface.py b/nilearn/surface/tests/test_surface.py
--- a/nilearn/surface/tests/test_surface.py
+++ b/nilearn/surface/tests/test_surface.py
@@ -72,6 +72,19 @@ def data(self):
         return self._data
 
 
+def test_load_surf_data_numpy_gt_1pt23():
+    """Test loading fsaverage surface
+
+    Threw an error with numpy >=1.24.x
+    but only a deprecaton warning with numpy <1.24.x.
+
+    Regression test for
+    https://github.com/nilearn/nilearn/issues/3638
+    """
+    fsaverage = datasets.fetch_surf_fsaverage()
+    surface.load_surf_data(fsaverage['pial_left'])
+
+
 def test_load_surf_data_array():
     # test loading and squeezing data from numpy array
     data_flat = np.zeros((20, ))