# Buggy code
def _on_graph_change(self, event=None):
    """update the shader when the graph data changes"""

    self.graph_shader.use_fade = self.layer.use_fade
    self.graph_shader.tail_length = self.layer.tail_length
    self.graph_shader.vertex_time = self.layer.graph_times

    # if the user clears a graph after it has been created, vispy offers
    # no method to clear the data, therefore, we need to set private
    # attributes to None to prevent errors
    if self.layer._view_graph is None:
        self.node._subvisuals[2]._pos = None
        self.node._subvisuals[2]._connect = None
        self.node.update()
        return

    self.node._subvisuals[2].set_data(
        pos=self.layer._view_graph,
        connect=self.layer.graph_connex,
        width=self.layer.tail_width,
        color="white",
    )

    # Call to update order of translation values with new dims:
    self._on_scale_change()
    self._on_translate_change()


# Traceback (AttributeError)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-10-05f52b983105> in <module>
1 v = napari.Viewer()
----> 2 v.add_tracks(tracks, name='ilastik tracks')

<string> in add_tracks(self, data, properties, graph, tail_width, tail_length, name, metadata, scale, translate, opacity, blending, visible, colormap, color_by, colormaps_dict)

~/miniconda3/envs/fastai/lib/python3.7/site-packages/napari/components/add_layers_mixin.py in add_layer(self, layer)
48         layer.events.cursor_size.connect(self._update_cursor_size)
49         layer.events.data.connect(self._on_layers_change)
---> 50         self.layers.append(layer)
51         self._update_layers(layers=[layer])
52

~/miniconda3/envs/fastai/lib/python3.7/site-packages/napari/utils/list/_model.py in append(self, obj)
57     def append(self, obj):
58         TypedList.append(self, obj)
---> 59         self.events.added(item=obj, index=len(self) - 1)
60
61     def pop(self, key):

~/miniconda3/envs/fastai/lib/python3.7/site-packages/napari/utils/events/event.py in __call__(self, *args, **kwargs)
512                     continue
513
--> 514                 self._invoke_callback(cb, event)
515                 if event.blocked:
516                     break

~/miniconda3/envs/fastai/lib/python3.7/site-packages/napari/utils/events/event.py in _invoke_callback(self, cb, event)
533                 self.print_callback_errors,
534                 self,
--> 535                 cb_event=(cb, event),
536             )
537

~/miniconda3/envs/fastai/lib/python3.7/site-packages/napari/utils/events/event.py in _invoke_callback(self, cb, event)
527     def _invoke_callback(self, cb, event):
528         try:
--> 529             cb(event)
530         except Exception:
531             _handle_exception(

~/miniconda3/envs/fastai/lib/python3.7/site-packages/napari/_qt/qt_viewer.py in _add_layer(self, event)
281         layers = event.source
282         layer = event.item
--> 283         vispy_layer = create_vispy_visual(layer)
284         vispy_layer.node.parent = self.view.scene
285         vispy_layer.order = len(layers) - 1

~/miniconda3/envs/fastai/lib/python3.7/site-packages/napari/_vispy/utils.py in create_vispy_visual(layer)
32     for layer_type, visual in layer_to_visual.items():
33         if isinstance(layer, layer_type):
---> 34             return visual(layer)
35
36     raise TypeError(

~/miniconda3/envs/fastai/lib/python3.7/site-packages/napari/_vispy/vispy_tracks_layer.py in __init__(self, layer)
48         self._reset_base()
49
---> 50         self._on_data_change()
51         self._on_appearance_change()
52

~/miniconda3/envs/fastai/lib/python3.7/site-packages/napari/_vispy/vispy_tracks_layer.py in _on_data_change(self, event)
66         self.node.update()
67         # Call to update order of translation values with new dims:
---> 68         self._on_scale_change()
69         self._on_translate_change()
70

AttributeError: 'VispyTracksLayer' object has no attribute '_on_scale_change'

# Fixed code
def _on_graph_change(self, event=None):
    """update the shader when the graph data changes"""

    self.graph_shader.use_fade = self.layer.use_fade
    self.graph_shader.tail_length = self.layer.tail_length
    self.graph_shader.vertex_time = self.layer.graph_times

    # if the user clears a graph after it has been created, vispy offers
    # no method to clear the data, therefore, we need to set private
    # attributes to None to prevent errors
    if self.layer._view_graph is None:
        self.node._subvisuals[2]._pos = None
        self.node._subvisuals[2]._connect = None
        self.node.update()
        return

    self.node._subvisuals[2].set_data(
        pos=self.layer._view_graph,
        connect=self.layer.graph_connex,
        width=self.layer.tail_width,
        color="white",
    )

    # Call to update order of translation values with new dims:
    self._on_matrix_change()