Repository: napari/napari

Issue:
Tracks layer color_by and data setters bug
## 🐛 Bug

Napari raises a value error when updating a Tracks layer with the data setter method.

## To Reproduce

Steps to reproduce the behavior:

1. Create a Tracks layer.
2. Update the layer data through the data setter method.

```python3
import numpy as np
import napari

with napari.gui_qt():
    viewer = napari.view_image(np.ones((25, 25, 25)))

    tracks = viewer.add_tracks([[1] * 5])
    tracks.data = [[1] * 5]
```

It throws
```python3
WARNING: Traceback (most recent call last):
  File "~/miniconda3/envs/tracking/lib/python3.8/site-packages/napari/_qt/layer_controls/qt_tracks_controls.py", line 201, in change_color_by
    self.layer.color_by = value
  File "~/miniconda3/envs/tracking/lib/python3.8/site-packages/napari/layers/tracks/tracks.py", line 465, in color_by
    raise ValueError(f'{color_by} is not a valid property key')
ValueError:  is not a valid property key
Aborted (core dumped)
```

## Expected behavior

I expected the tracks to be updated without throwing an error.

## Environment

```
napari: 0.4.7
Platform: Linux-5.8.0-48-generic-x86_64-with-glibc2.10
System: Ubuntu 20.04.2 LTS
Python: 3.8.8 (default, Feb 24 2021, 21:46:12) [GCC 7.3.0]
Qt: 5.15.2
PyQt5: 5.15.4
NumPy: 1.20.2
SciPy: 1.6.2
Dask: 2021.04.0
VisPy: 0.6.6

OpenGL:
- GL version: 4.6.0 NVIDIA 460.39
- MAX_TEXTURE_SIZE: 32768

Screens:
- screen 1: resolution 3440x1440, scale 1.0

Plugins:
- console: 0.0.3
- svg: 0.1.4
```


Discussion:

Resolving patch:
diff --git a/napari/_qt/layer_controls/qt_tracks_controls.py b/napari/_qt/layer_controls/qt_tracks_controls.py
--- a/napari/_qt/layer_controls/qt_tracks_controls.py
+++ b/napari/_qt/layer_controls/qt_tracks_controls.py
@@ -4,6 +4,7 @@
 
 from ...utils.colormaps import AVAILABLE_COLORMAPS
 from ...utils.translations import trans
+from ..utils import qt_signals_blocked
 from .qt_layer_controls_base import QtLayerControls
 
 MAX_TAIL_LENGTH = 300
@@ -133,7 +134,9 @@ def _on_tail_length_change(self, event=None):
     def _on_properties_change(self, event=None):
         """Change the properties that can be used to color the tracks."""
         with self.layer.events.properties.blocker():
-            self.color_by_combobox.clear()
+
+            with qt_signals_blocked(self.color_by_combobox):
+                self.color_by_combobox.clear()
             self.color_by_combobox.addItems(self.layer.properties_to_color_by)
 
     def _on_colormap_change(self, event=None):
diff --git a/napari/layers/tracks/tracks.py b/napari/layers/tracks/tracks.py
--- a/napari/layers/tracks/tracks.py
+++ b/napari/layers/tracks/tracks.py
@@ -496,7 +496,8 @@ def _recolor_tracks(self):
         # updated before the properties are. properties should always contain
         # a track_id key
         if self.color_by not in self.properties_to_color_by:
-            self.color_by = 'track_id'
+            self._color_by = 'track_id'
+            self.events.color_by()
 
         # if we change the coloring, rebuild the vertex colors array
         vertex_properties = self._manager.vertex_properties(self.color_by)


Test patch: