Repository: napari/napari

Issue:
Napari viewer closes unexpectetly when pressing the 3D button
## 🐛 Bug

Hi guys,

I use the following code to automatically display a 3D stack with 2 Channels and 10 Timepoints in Napari. This works fine and the viewer opens up just fine.
When I then press the 3D button the viewer is gone and I get a long error stack: See below:
Any help is welcome.

Sebi

![image](https://user-images.githubusercontent.com/3833249/68606163-216f8a00-04ae-11ea-906c-726f3195e4fe.png)

```
def show_napari(array, metadata, verbose=True):

    import napari

    with napari.gui_qt():

        # create scalefcator with all ones
        scalefactors = [1] * len(array.shape)
        
        # initialize the napari viewer
        viewer = napari.Viewer()
            
        if metadata['ImageType'] == 'czi':

            # find position of dimensions
            posZ = metadata['Axes'].find('Z')
            posC = metadata['Axes'].find('C')
            posT = metadata['Axes'].find('T')

            # get the scalefactors from the metadata
            scalef = get_scalefactor(metadata)
            scalefactors[posZ] = scalef['zx']

            if verbose:
                print('Dim PosT : ', posT)
                print('Dim PosZ : ', posZ)
                print('Dim PosC : ', posC)
                print('Scale Factors XYZ: ', scalefactors)
            
            # add all channels as layers
            for ch in range(metadata['SizeC']):
                chname = metadata['Channels'][ch]

                # cut out channel
                channel = array.take(ch, axis=posC)
                print(channel.shape)

                # actually show the image array
                print('Adding Channel: ', chname)
                viewer.add_image(channel, name=chname, scale=scalefactors)
```
Error message:

```
(1, 10, 2, 15, 256, 256, 1)
BTCZYX0
(1, 10, 2, 15, 256, 256)
Dim PosT :  1
Dim PosZ :  3
Dim PosC :  2
Scale Factors XYZ:  [1, 1, 1, 3.516, 1, 1]
(1, 10, 15, 256, 256)
Adding Channel:  AF555
(1, 10, 15, 256, 256)
Adding Channel:  AF488
WARNING: Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\_qt\qt_viewer_buttons.py", line 173, in <lambda>
    lambda state=self: self.change_ndisplay(state)
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\_qt\qt_viewer_buttons.py", line 178, in change_ndisplay
    self.viewer.dims.ndisplay = 3
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\components\dims.py", line 205, in ndisplay
    self.events.ndisplay()
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\util\event.py", line 508, in __call__
    self._invoke_callback(cb, event)
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\util\event.py", line 529, in _invoke_callback
    cb_event=(cb, event),
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\util\event.py", line 523, in _invoke_callback
    cb(event)
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\components\viewer_model.py", line 89, in <lambda>
    self.dims.events.ndisplay.connect(lambda e: self._update_layers())
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\components\viewer_model.py", line 1018, in _update_layers
    layer.dims.ndisplay = self.dims.ndisplay
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\components\dims.py", line 205, in ndisplay
    self.events.ndisplay()
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\util\event.py", line 508, in __call__
    self._invoke_callback(cb, event)
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\util\event.py", line 529, in _invoke_callback
    cb_event=(cb, event),
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\util\event.py", line 523, in _invoke_callback
    cb(event)
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\layers\base\base.py", line 174, in <lambda>
    self.dims.events.ndisplay.connect(lambda e: self._update_dims())
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\layers\base\base.py", line 372, in _update_dims
    self._set_view_slice()
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\layers\image\image.py", line 502, in _set_view_slice
    self.events.set_data()
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\util\event.py", line 508, in __call__
    self._invoke_callback(cb, event)
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\util\event.py", line 529, in _invoke_callback
    cb_event=(cb, event),
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\util\event.py", line 523, in _invoke_callback
    cb(event)
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\_vispy\vispy_base_layer.py", line 46, in <lambda>
    self.layer.events.set_data.connect(lambda e: self._on_data_change())
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\_vispy\vispy_image_layer.py", line 59, in _on_data_change
    self._on_display_change()
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\_vispy\vispy_image_layer.py", line 48, in _on_display_change
    self.reset()
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\_vispy\vispy_image_layer.py", line 216, in reset
    self._reset_base()
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\_vispy\vispy_base_layer.py", line 165, in _reset_base
    self._on_scale_change()
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\_vispy\vispy_image_layer.py", line 123, in _on_scale_change
    self.layer.position = self._transform_position(self._position)
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\_vispy\vispy_base_layer.py", line 153, in _transform_position
    transform.map(list(position))[: len(self.layer.dims.displayed)]
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\vispy\visuals\transforms\chain.py", line 148, in map
    coords = tr.map(coords)
  File "<decorator-gen-4>", line 2, in imap
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\vispy\visuals\transforms\_util.py", line 111, in arg_to_vec4
    arg = as_vec4(arg)
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\vispy\visuals\transforms\_util.py", line 81, in as_vec4
    % obj.shape)
TypeError: not all arguments converted during string formatting
WARNING:vispy:Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\_qt\qt_viewer_buttons.py", line 173, in <lambda>
    lambda state=self: self.change_ndisplay(state)
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\_qt\qt_viewer_buttons.py", line 178, in change_ndisplay
    self.viewer.dims.ndisplay = 3
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\components\dims.py", line 205, in ndisplay
    self.events.ndisplay()
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\util\event.py", line 508, in __call__
    self._invoke_callback(cb, event)
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\util\event.py", line 529, in _invoke_callback
    cb_event=(cb, event),
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\util\event.py", line 523, in _invoke_callback
    cb(event)
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\components\viewer_model.py", line 89, in <lambda>
    self.dims.events.ndisplay.connect(lambda e: self._update_layers())
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\components\viewer_model.py", line 1018, in _update_layers
    layer.dims.ndisplay = self.dims.ndisplay
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\components\dims.py", line 205, in ndisplay
    self.events.ndisplay()
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\util\event.py", line 508, in __call__
    self._invoke_callback(cb, event)
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\util\event.py", line 529, in _invoke_callback
    cb_event=(cb, event),
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\util\event.py", line 523, in _invoke_callback
    cb(event)
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\layers\base\base.py", line 174, in <lambda>
    self.dims.events.ndisplay.connect(lambda e: self._update_dims())
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\layers\base\base.py", line 372, in _update_dims
    self._set_view_slice()
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\layers\image\image.py", line 502, in _set_view_slice
    self.events.set_data()
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\util\event.py", line 508, in __call__
    self._invoke_callback(cb, event)
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\util\event.py", line 529, in _invoke_callback
    cb_event=(cb, event),
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\util\event.py", line 523, in _invoke_callback
    cb(event)
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\_vispy\vispy_base_layer.py", line 46, in <lambda>
    self.layer.events.set_data.connect(lambda e: self._on_data_change())
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\_vispy\vispy_image_layer.py", line 59, in _on_data_change
    self._on_display_change()
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\_vispy\vispy_image_layer.py", line 48, in _on_display_change
    self.reset()
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\_vispy\vispy_image_layer.py", line 216, in reset
    self._reset_base()
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\_vispy\vispy_base_layer.py", line 165, in _reset_base
    self._on_scale_change()
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\_vispy\vispy_image_layer.py", line 123, in _on_scale_change
    self.layer.position = self._transform_position(self._position)
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\napari\_vispy\vispy_base_layer.py", line 153, in _transform_position
    transform.map(list(position))[: len(self.layer.dims.displayed)]
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\vispy\visuals\transforms\chain.py", line 148, in map
    coords = tr.map(coords)
  File "<decorator-gen-4>", line 2, in imap
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\vispy\visuals\transforms\_util.py", line 111, in arg_to_vec4
    arg = as_vec4(arg)
  File "C:\ProgramData\Anaconda3\envs\imageanalysis\lib\site-packages\vispy\visuals\transforms\_util.py", line 81, in as_vec4
    % obj.shape)
TypeError: not all arguments converted during string formatting
```



Discussion:

Resolving patch:
diff --git a/napari/_vispy/vispy_base_layer.py b/napari/_vispy/vispy_base_layer.py
--- a/napari/_vispy/vispy_base_layer.py
+++ b/napari/_vispy/vispy_base_layer.py
@@ -39,7 +39,7 @@ def __init__(self, layer, node):
 
         self.layer = layer
         self.node = node
-        self._position = (0,) * self.layer.ndim
+        self._position = (0,) * self.layer.dims.ndisplay
         self.camera = None
 
         self.layer.events.refresh.connect(lambda e: self.node.update())


Test patch:
diff --git a/napari/tests/test_advanced.py b/napari/tests/test_advanced.py
--- a/napari/tests/test_advanced.py
+++ b/napari/tests/test_advanced.py
@@ -36,6 +36,34 @@ def test_4D_5D_images(qtbot):
     viewer.window.close()
 
 
+def test_5D_image_3D_rendering(qtbot):
+    """Test 3D rendering of a 5D image."""
+    np.random.seed(0)
+    viewer = Viewer()
+    view = viewer.window.qt_viewer
+    qtbot.addWidget(view)
+
+    # add 4D image data
+    data = np.random.random((2, 10, 12, 13, 14))
+    viewer.add_image(data)
+    assert np.all(viewer.layers[0].data == data)
+    assert len(viewer.layers) == 1
+    assert viewer.dims.ndim == 5
+    assert viewer.dims.ndisplay == 2
+    assert viewer.layers[0]._data_view.ndim == 2
+    assert view.dims.nsliders == viewer.dims.ndim
+    assert np.sum(view.dims._displayed_sliders) == 3
+
+    # switch to 3D rendering
+    viewer.dims.ndisplay = 3
+    assert viewer.dims.ndisplay == 3
+    assert viewer.layers[0]._data_view.ndim == 3
+    assert np.sum(view.dims._displayed_sliders) == 2
+
+    # Close the viewer
+    viewer.window.close()
+
+
 def test_change_image_dims(qtbot):
     """Test changing the dims and shape of an image layer in place and checking
     the numbers of sliders and their ranges changes appropriately.