Repository: nilearn/nilearn

Issue:
[BUG] unhepful error message when passing invalid `view` to surface plotting
### Is there an existing issue for this?

- [X] I have searched the existing issues

### Operating system

- [X] Linux
- [ ] Mac
- [ ] Windows

### Operating system version

For example one of the following:
- Linux Ubuntu 22.04


### Python version

- [ ] 3.12
- [X] 3.11
- [ ] 3.10
- [ ] 3.9
- [ ] 3.8

### nilearn version

dev

### Expected behavior

when passing is view of a type that is does not match what's in the doc string that is not a string (e.g `"lateral"`, `"medial"`...) or a pair of floats (elevation, azimuth) I would expect an informative error.

### Current behavior & error messages

This is what I got:

```bash
Exception in Tkinter callback
Traceback (most recent call last):
  File "/home/remi/miniconda3/lib/python3.11/tkinter/__init__.py", line 1948, in __call__
    return self.func(*args)
           ^^^^^^^^^^^^^^^^
  File "/home/remi/miniconda3/lib/python3.11/tkinter/__init__.py", line 861, in callit
    func(*args)
  File "/home/remi/miniconda3/lib/python3.11/site-packages/matplotlib/backends/_backend_tk.py", line 274, in idle_draw
    self.draw()
  File "/home/remi/miniconda3/lib/python3.11/site-packages/matplotlib/backends/backend_tkagg.py", line 10, in draw
    super().draw()
  File "/home/remi/miniconda3/lib/python3.11/site-packages/matplotlib/backends/backend_agg.py", line 388, in draw
    self.figure.draw(self.renderer)
  File "/home/remi/miniconda3/lib/python3.11/site-packages/matplotlib/artist.py", line 95, in draw_wrapper
    result = draw(artist, renderer, *args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/remi/miniconda3/lib/python3.11/site-packages/matplotlib/artist.py", line 72, in draw_wrapper
    return draw(artist, renderer)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/remi/miniconda3/lib/python3.11/site-packages/matplotlib/figure.py", line 3154, in draw
    mimage._draw_list_compositing_images(
  File "/home/remi/miniconda3/lib/python3.11/site-packages/matplotlib/image.py", line 132, in _draw_list_compositing_images
    a.draw(renderer)
  File "/home/remi/miniconda3/lib/python3.11/site-packages/matplotlib/artist.py", line 72, in draw_wrapper
    return draw(artist, renderer)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/remi/miniconda3/lib/python3.11/site-packages/mpl_toolkits/mplot3d/axes3d.py", line 458, in draw
    self.M = self.get_proj()
             ^^^^^^^^^^^^^^^
  File "/home/remi/miniconda3/lib/python3.11/site-packages/mpl_toolkits/mplot3d/axes3d.py", line 916, in get_proj
    elev_rad = np.deg2rad(self.elev)
               ^^^^^^^^^^^^^^^^^^^^^
TypeError: ufunc 'deg2rad' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
```


### Steps and code to reproduce bug

```python
from nilearn import datasets
from nilearn import plotting

destrieux_atlas = datasets.fetch_atlas_surf_destrieux()

parcellation = destrieux_atlas["map_left"]

fsaverage = datasets.fetch_surf_fsaverage()

plotting.plot_surf_roi(
    fsaverage["pial_left"],
    roi_map=parcellation,
    hemi="left",
    view=["lateral", "medial"],  # <- invalid view
    bg_map=fsaverage["sulc_left"],
    bg_on_data=True,
    darkness=0.5,
)
plotting.show()
```



Discussion:

Resolving patch:
diff --git a/nilearn/_utils/docs.py b/nilearn/_utils/docs.py
--- a/nilearn/_utils/docs.py
+++ b/nilearn/_utils/docs.py
@@ -990,12 +990,12 @@ def custom_function(vertices):
 docdict[
     "view"
 ] = """
-view : :obj:`str` or a pair of :obj:`float`, default="lateral"
-    If a string, must be in {"lateral", "medial", "dorsal", "ventral",\
-"anterior", "posterior"}.
-    If a sequence, must be a pair (elev, azim) of float
+view : :obj:`str`, or a pair of :obj:`float` or :obj:`int`, default="lateral"
+    If a string, must be in \
+    {"lateral", "medial", "dorsal", "ventral", "anterior", "posterior"}.
+    If a sequence, must be a pair (elev, azim) of :obj:`float` or :obj:`int`
     angles in degrees that will manually set a custom view.
-    E.g., view=[270.0, 90.0] or view=(0.0, -180.0).
+    E.g., view=[270.0, 90] or view=(0, -180.0).
     View of the surface that is rendered.
 """
 
diff --git a/nilearn/plotting/surf_plotting.py b/nilearn/plotting/surf_plotting.py
--- a/nilearn/plotting/surf_plotting.py
+++ b/nilearn/plotting/surf_plotting.py
@@ -1205,7 +1205,11 @@ def _check_view_is_valid(view) -> bool:
     """
     if isinstance(view, str) and (view in VALID_VIEWS):
         return True
-    if isinstance(view, Sequence) and len(view) == 2:
+    if (
+        isinstance(view, Sequence)
+        and len(view) == 2
+        and all(isinstance(x, (int, float)) for x in view)
+    ):
         return True
     return False
 


Test patch:
diff --git a/nilearn/plotting/tests/test_surf_plotting.py b/nilearn/plotting/tests/test_surf_plotting.py
--- a/nilearn/plotting/tests/test_surf_plotting.py
+++ b/nilearn/plotting/tests/test_surf_plotting.py
@@ -322,7 +322,10 @@ def test_instantiation_error_plotly_surface_figure(input_obj):
         ("medial", True),
         ("latreal", False),
         ((100, 100), True),
+        ([100.0, 100.0], True),
         ((100, 100, 1), False),
+        (("lateral", "medial"), False),
+        ([100, "bar"], False),
     ]
 )
 def test_check_view_is_valid(view, is_valid):