Repository: scipp/plopp

Issue:
3d scatter plot raises for scalar inputs
To reproduce, load a Nexus file, then:
```python
sc.neutron.instrument_view(data['spectrum', 5])
```
or
```python
sc.neutron.instrument_view(data.attrs['monitor1'].value)
```
if there a monitors in the file.

```python
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-13-f81767f7209a> in <module>
----> 1 sc.neutron.instrument_view(base['spectrum',5])

~/software/scipp/scipp/neutron/instrument_view.py in instrument_view(scipp_obj, positions, pixel_size, **kwargs)
     35                 positions=positions,
     36                 pixel_size=pixel_size,
---> 37                 **kwargs)

~/software/scipp/scipp/plot/__init__.py in plot(*args, **kwargs)
    202         interactive_on = True
    203 
--> 204     output = _plot(*args, **kwargs)
    205 
    206     if output is not None:

~/software/scipp/scipp/plot/plot.py in plot(scipp_obj, projection, axes, color, marker, linestyle, linewidth, bins, **kwargs)
    176                                mpl_line_params=val["mpl_line_params"],
    177                                bins=bins,
--> 178                                **kwargs)
    179 
    180     if len(output) > 1:

~/software/scipp/scipp/plot/dispatch.py in dispatch(scipp_obj_dict, ndim, name, bins, projection, mpl_line_params, **kwargs)
     38     elif projection == "3d":
     39         from .plot3d import plot3d
---> 40         return plot3d(scipp_obj_dict, **kwargs)
     41     else:
     42         raise RuntimeError("Wrong projection type. Expected either '1d', "

~/software/scipp/scipp/plot/plot3d.py in plot3d(filename, *args, **kwargs)
     41             pass
     42 
---> 43     sp = SciPlot3d(*args, **kwargs)
     44     if filename is not None:
     45         sp.savefig(filename)

~/software/scipp/scipp/plot/plot3d.py in __init__(self, scipp_obj_dict, positions, axes, figsize, aspect, masks, cmap, norm, scale, vmin, vmax, color, background, pixel_size, tick_size, show_outline, xlabel, ylabel, zlabel)
     93                          masks=masks,
     94                          positions=positions,
---> 95                          view_ndims=view_ndims)
     96 
     97         # The model which takes care of all heavy calculations

~/software/scipp/scipp/plot/sciplot.py in __init__(self, scipp_obj_dict, axes, errorbars, cmap, norm, vmin, vmax, color, masks, positions, view_ndims)
     71                                       axes=axes,
     72                                       view_ndims=view_ndims,
---> 73                                       positions=positions)
     74 
     75         # Set cmap extend state: if we have sliders, then we need to extend.

~/software/scipp/scipp/plot/sciplot.py in _process_axes_dimensions(self, array, axes, view_ndims, positions)
    227             if positions is not None:
    228                 if (dim == positions) or (dim
--> 229                                           == array.meta[positions].dims[-1]):
    230                     key = "x"
    231                 else:

IndexError: list index out of range
```

Discussion:

Patch:
diff --git a/src/plopp/functions/scatter3d.py b/src/plopp/functions/scatter3d.py
index dd8ee8f..aa7da7d 100644
--- a/src/plopp/functions/scatter3d.py
+++ b/src/plopp/functions/scatter3d.py
@@ -89,7 +89,7 @@ def scatter3d(da: sc.DataArray,
         coords = {k: da.meta[k] for k in (x, y, z)}
 
     to_plot = sc.DataArray(data=da.data, masks=da.masks, coords=coords)
-    if to_plot.ndim > 1:
+    if to_plot.ndim != 1:
         to_plot = to_plot.flatten(to=uuid.uuid4().hex)
     fig = figure3d(input_node(to_plot),
                    x=x,


Test patch:
diff --git a/tests/functions/scatter3d_test.py b/tests/functions/scatter3d_test.py
index 9c1c6b3..f4a7403 100644
--- a/tests/functions/scatter3d_test.py
+++ b/tests/functions/scatter3d_test.py
@@ -43,6 +43,13 @@ def test_scatter3d_dimensions_are_flattened():
     assert list(p[0].artists.values())[0].data.ndim == 1
 
 
+def test_scatter3d_can_plot_scalar_data():
+    da = sc.DataArray(data=sc.scalar(1.2),
+                      coords={'position': sc.vector(value=[1, 2, 3])})
+    p = pp.scatter3d(da, pos='position')
+    assert list(p.children[0].artists.values())[0].data.ndim == 1
+
+
 def test_raises_ValueError_when_given_binned_data():
     nx = 10
     da = sc.data.table_xyz(100).bin(x=nx)