Repository: napari/napari

Issue:
Error in example script surface_timeseries_.py
## 🐛 Bug
The napari example script `surface_timeseries_.py` returns an error when it is run.

## To Reproduce

Steps to reproduce the behavior:

1. Install napari, and `nilearn` into your python environment
2. Download and run the [napari example `surface_timeseries_.py` from here](https://github.com/napari/napari/blob/main/examples/surface_timeseries_.py): `python surface_timeseries_.py`
3. An error message is produced: *"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"*

<details>
<summary>Error message:</summary>

```
python surface_timeseries_.py

Dataset created in /Users/genevieb/nilearn_data/nki_enhanced_surface

Downloading data from https://www.nitrc.org/frs/download.php/8470/pheno_nki_nilearn.csv ...
 ...done. (1 seconds, 0 min)
Downloading data from https://www.nitrc.org/frs/download.php/8261/A00028185_rh_preprocessed_fsaverage5_fwhm6.gii ...
Downloaded 42377216 of 42412120 bytes (99.9%,    0.1s remaining) ...done. (100 seconds, 1 min)
Downloading data from https://www.nitrc.org/frs/download.php/8260/A00028185_lh_preprocessed_fsaverage5_fwhm6.gii ...
Downloaded 41697280 of 42402060 bytes (98.3%,    1.3s remaining) ...done. (81 seconds, 1 min)
Traceback (most recent call last):
  File "/Users/genevieb/Documents/GitHub/napari/examples/surface_timeseries_.py", line 24, in <module>
    brain_vertices, brain_faces = surface.load_surf_data(fsaverage['pial_left'])
  File "/Users/genevieb/mambaforge/envs/napari-dev/lib/python3.10/site-packages/nilearn/surface/surface.py", line 733, in load_surf_data
    data_part = _gifti_img_to_data(gii)
  File "/Users/genevieb/mambaforge/envs/napari-dev/lib/python3.10/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.
```

</details>

## Expected behavior

I expected the example script to run without an error, and to display some timeseries surface data in napari.

## Environment

 - Please copy and paste the information at napari info option in help menubar here:

napari: 0.4.13.dev917+g54c1dbf8
Platform: macOS-12.3.1-arm64-arm-64bit
System: MacOS 12.3.1
Python: 3.10.8 | packaged by conda-forge | (main, Nov 22 2022, 08:25:29) [Clang 14.0.6 ]
Qt: 5.15.6
PyQt5: 5.15.7
NumPy: 1.24.2
SciPy: 1.10.1
Dask: 2023.1.0
VisPy: 0.12.1
magicgui: 0.6.1
superqt: unknown
in-n-out: 0.1.6
app-model: 0.1.1
npe2: 0.6.2

OpenGL:
- GL version: 2.1 Metal - 76.3
- MAX_TEXTURE_SIZE: 16384

Screens:
- screen 1: resolution 1440x900, scale 2.0
- screen 2: resolution 3440x1440, scale 1.0

Settings path:
- /Users/genevieb/Library/Application Support/napari/napari-dev_8a798ce8db3962d716d33109f1c23fa2f783f2dd/settings.yaml


## Additional context

Juan and I were talking about how to colour the vertices of a mesh according to some property, and he suggested I look at this example. We were both surprised when it gave an error, and thought that was something the CI should have caught.



Discussion:
@sofroniewn, as you are the author of this example, maybe it is possible to take a look at it? 
> We were both surprised when it gave an error, and thought that was something the CI should have caught.

I assume the check at the top for `nilearn` prevents this from running on CI? It doesn't show up in the logs.

Edit: looking at the workflow and stuff further—yes. This example is skipped:
https://github.com/napari/napari/blob/3ec4be1ae8eee50ab4912ba87981261cc94c075f/napari/_tests/test_examples.py#L23-L33
Yes it's skipped on the CI, but my point is that the example fails when you do install `nilearn` and try to run it.
The examples test was moved to separate job. So maybe someone could review list of skipped examples and check if some of them could be enabled. 

@GenevieveBuckley the only solution is that some core dev will spend time to fix it. 
Hi, just in case, I checked the example and seems like the error comes from `nilearn` being incompatible with `numpy` 1.24.x. If you run the example with `numpy` 1.23.x it works:

![imagen](https://user-images.githubusercontent.com/16781833/228905025-7d1e33c2-40ab-407f-8144-6447d41b9df6.png)

Also, with `numpy` 1.23.x a `VisibleDeprecationWarning` message appears which points to the line inside `nilearn` where the error occurs when using `numpy` 1.24.x :

```python-traceback
\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()
```

So I guess either being sure to use numpy < 1.24.x or adding the `dtype=object` kwarg at the line mentioned inside `nilearn` should fix the example
If I'm parsing this correctly, this is an upstream issue in `nilearn` and not a bug in napari/the example?

Resolving patch:
diff --git a/examples/3d_kymograph_.py b/examples/3d_kymograph_.py
--- a/examples/3d_kymograph_.py
+++ b/examples/3d_kymograph_.py
@@ -10,9 +10,6 @@
 from itertools import product
 
 import numpy as np
-from tqdm import tqdm
-
-import napari
 
 try:
     from omero.gateway import BlitzGateway
@@ -22,6 +19,16 @@
     print("Please install omero-py:")
     print("https://pypi.org/project/omero-py/")
     exit(-1)
+try:
+    from tqdm import tqdm
+except ModuleNotFoundError:
+    print("Could not import tqdm which is")
+    print("required to show progress when downloading the sample datasets.")
+    print("Please install tqdm:")
+    print("https://pypi.org/project/tqdm/")
+    exit(-1)
+
+import napari
 
 
 def IDR_fetch_image(image_id: int, progressbar: bool = True) -> np.ndarray:
diff --git a/examples/surface_timeseries_.py b/examples/surface_timeseries_.py
--- a/examples/surface_timeseries_.py
+++ b/examples/surface_timeseries_.py
@@ -6,14 +6,33 @@
 
 .. tags:: experimental
 """
+try:
+    from packaging.version import parse
+except ModuleNotFoundError:
+    raise ModuleNotFoundError(
+        "You must have packaging installed to run this example. "
+        "For that you will need to run, depending on your package manager, "
+        "something like 'pip install packaging' or 'conda install packaging'"
+    ) from None
 
 try:
     from nilearn import datasets, surface
 except ModuleNotFoundError:
     raise ModuleNotFoundError(
-        "You must have nilearn installed to run this example."
+        "You must have nilearn installed to run this example. "
+        "For that you will need to run, depending on your package manager, "
+        "something like 'pip install nilearn' or 'conda install nilearn'"
     ) from None
 
+import numpy as np
+
+if parse(np.__version__) >= parse("1.24"):
+    raise RuntimeError(
+        "Incompatible numpy version. "
+        "You must have numpy less than 1.24 for nilearn 0.10.1 and below to "
+        "work and download the example data"
+    )
+
 import napari
 
 # Fetch datasets - this will download dataset if datasets are not found


Test patch:
diff --git a/.github/workflows/test_pull_requests.yml b/.github/workflows/test_pull_requests.yml
--- a/.github/workflows/test_pull_requests.yml
+++ b/.github/workflows/test_pull_requests.yml
@@ -216,4 +216,4 @@ jobs:
         with:
           run: tox -e py39-linux-pyside2-examples
         env:
-          PIP_CONSTRAINT: resources/constraints/constraints_py3.9.txt
+          PIP_CONSTRAINT: resources/constraints/constraints_py3.9_examples.txt
diff --git a/.github/workflows/upgrade_test_constraints.yml b/.github/workflows/upgrade_test_constraints.yml
--- a/.github/workflows/upgrade_test_constraints.yml
+++ b/.github/workflows/upgrade_test_constraints.yml
@@ -46,6 +46,7 @@ jobs:
 
           python3.8 -m piptools compile --upgrade -o resources/constraints/constraints_py3.8.txt setup.cfg resources/constraints/version_denylist.txt --extra pyqt5 --extra pyqt6_experimental --extra pyside2 --extra pyside6_experimental --extra testing --allow-unsafe --strip-extras --resolver=backtracking
           python3.9 -m piptools compile --upgrade -o resources/constraints/constraints_py3.9.txt setup.cfg resources/constraints/version_denylist.txt --extra pyqt5 --extra pyqt6_experimental --extra pyside2 --extra pyside6_experimental --extra testing --allow-unsafe --strip-extras --resolver=backtracking
+          python3.9 -m piptools compile --upgrade -o resources/constraints/constraints_py3.9_examples.txt setup.cfg resources/constraints/version_denylist.txt resources/constraints/version_denylist_examples.txt --extra pyqt5 --extra pyqt6_experimental --extra pyside2 --extra pyside6_experimental --extra testing --allow-unsafe --strip-extras --resolver=backtracking
           python3.10 -m piptools compile --upgrade -o resources/constraints/constraints_py3.10.txt setup.cfg resources/constraints/version_denylist.txt --extra pyqt5 --extra pyqt6_experimental --extra pyside2 --extra pyside6_experimental --extra testing --allow-unsafe --strip-extras --resolver=backtracking
 
           # Explanation of above commands 
diff --git a/napari/_tests/test_examples.py b/napari/_tests/test_examples.py
--- a/napari/_tests/test_examples.py
+++ b/napari/_tests/test_examples.py
@@ -21,11 +21,10 @@
 
 # not testing these examples
 skip = [
-    'surface_timeseries_.py',  # needs nilearn
-    '3d_kymograph_.py',  # needs tqdm
+    '3d_kymograph_.py',  # needs tqdm, omero-py and can take some time downloading data
     'live_tiffs_.py',  # requires files
     'tiled-rendering-2d_.py',  # too slow
-    'live_tiffs_generator_.py',
+    'live_tiffs_generator_.py',  # to generate files for live_tiffs_.py
     'points-over-time.py',  # too resource hungry
     'embed_ipython_.py',  # fails without monkeypatch
     'new_theme.py',  # testing theme is extremely slow on CI