Repository: plotly/plotly.py
Pull request #1554 (2019-05-06 22:05:23)

Support **kwargs in update_traces and update_{subplot} methods
Add support for specifying property updates as `**kwargs` in the `update_traces` and `update_*` subplot methods of Figure.  E.g.

```
fig.update_traces(marker_color='red', row=1)
```


Patch:
diff --git a/codegen/figure.py b/codegen/figure.py
index 7e5d32af1..d60f2c7b7 100644
--- a/codegen/figure.py
+++ b/codegen/figure.py
@@ -218,7 +218,8 @@ class {fig_classname}({base_classname}):\n""")
 
         return self
 
-    def update_{plural_name}(self, patch, selector=None, row=None, col=None):
+    def update_{plural_name}(
+            self, patch=None, selector=None, row=None, col=None, **kwargs):
         \"\"\"
         Perform a property update operation on all {singular_name} objects
         that satisfy the specified selection criteria
@@ -239,7 +240,11 @@ class {fig_classname}({base_classname}):\n""")
             To select {singular_name} objects by row and column, the Figure
             must have been created using plotly.subplots.make_subplots.
             If None (the default), all {singular_name} objects are selected.
-        
+        **kwargs
+            Additional property updates to apply to each selected
+            {singular_name} object. If a property is specified in
+            both patch and in **kwargs then the one in **kwargs
+            takes precedence.
         Returns
         -------
         self
@@ -247,7 +252,7 @@ class {fig_classname}({base_classname}):\n""")
         \"\"\"
         for obj in self.select_{plural_name}(
                 selector=selector, row=row, col=col):
-            obj.update(patch)
+            obj.update(patch, **kwargs)
 
         return self""")
 
diff --git a/plotly/basedatatypes.py b/plotly/basedatatypes.py
index 6bab9c79a..cd8cd7ea9 100644
--- a/plotly/basedatatypes.py
+++ b/plotly/basedatatypes.py
@@ -759,14 +759,15 @@ class BaseFigure(object):
 
         return self
 
-    def update_traces(self, patch, selector=None, row=None, col=None):
+    def update_traces(
+            self, patch=None, selector=None, row=None, col=None, **kwargs):
         """
         Perform a property update operation on all traces that satisfy the
         specified selection criteria
 
         Parameters
         ----------
-        patch: dict
+        patch: dict or None (default None)
             Dictionary of property updates to be applied to all traces that
             satisfy the selection criteria.
         selector: dict or None (default None)
@@ -780,6 +781,10 @@ class BaseFigure(object):
             To select traces by row and column, the Figure must have been
             created using plotly.subplots.make_subplots.  If None
             (the default), all traces are selected.
+        **kwargs
+            Additional property updates to apply to each selected trace. If
+            a property is specified in both patch and in **kwargs then the
+            one in **kwargs takes precedence.
 
         Returns
         -------
@@ -787,7 +792,7 @@ class BaseFigure(object):
             Returns the Figure object that the method was called on
         """
         for trace in self.select_traces(selector=selector, row=row, col=col):
-            trace.update(patch)
+            trace.update(patch, **kwargs)
         return self
 
     def _select_layout_subplots_by_prefix(
diff --git a/plotly/graph_objs/_figure.py b/plotly/graph_objs/_figure.py
index 3ac55bc02..8cc8ef262 100644
--- a/plotly/graph_objs/_figure.py
+++ b/plotly/graph_objs/_figure.py
@@ -12366,7 +12366,9 @@ class Figure(BaseFigure):
 
         return self
 
-    def update_geos(self, patch, selector=None, row=None, col=None):
+    def update_geos(
+        self, patch=None, selector=None, row=None, col=None, **kwargs
+    ):
         """
         Perform a property update operation on all geo objects
         that satisfy the specified selection criteria
@@ -12387,14 +12389,18 @@ class Figure(BaseFigure):
             To select geo objects by row and column, the Figure
             must have been created using plotly.subplots.make_subplots.
             If None (the default), all geo objects are selected.
-        
+        **kwargs
+            Additional property updates to apply to each selected
+            geo object. If a property is specified in
+            both patch and in **kwargs then the one in **kwargs
+            takes precedence.
         Returns
         -------
         self
             Returns the Figure object that the method was called on
         """
         for obj in self.select_geos(selector=selector, row=row, col=col):
-            obj.update(patch)
+            obj.update(patch, **kwargs)
 
         return self
 
@@ -12462,7 +12468,9 @@ class Figure(BaseFigure):
 
         return self
 
-    def update_mapboxes(self, patch, selector=None, row=None, col=None):
+    def update_mapboxes(
+        self, patch=None, selector=None, row=None, col=None, **kwargs
+    ):
         """
         Perform a property update operation on all mapbox objects
         that satisfy the specified selection criteria
@@ -12483,14 +12491,18 @@ class Figure(BaseFigure):
             To select mapbox objects by row and column, the Figure
             must have been created using plotly.subplots.make_subplots.
             If None (the default), all mapbox objects are selected.
-        
+        **kwargs
+            Additional property updates to apply to each selected
+            mapbox object. If a property is specified in
+            both patch and in **kwargs then the one in **kwargs
+            takes precedence.
         Returns
         -------
         self
             Returns the Figure object that the method was called on
         """
         for obj in self.select_mapboxes(selector=selector, row=row, col=col):
-            obj.update(patch)
+            obj.update(patch, **kwargs)
 
         return self
 
@@ -12558,7 +12570,9 @@ class Figure(BaseFigure):
 
         return self
 
-    def update_polars(self, patch, selector=None, row=None, col=None):
+    def update_polars(
+        self, patch=None, selector=None, row=None, col=None, **kwargs
+    ):
         """
         Perform a property update operation on all polar objects
         that satisfy the specified selection criteria
@@ -12579,14 +12593,18 @@ class Figure(BaseFigure):
             To select polar objects by row and column, the Figure
             must have been created using plotly.subplots.make_subplots.
             If None (the default), all polar objects are selected.
-        
+        **kwargs
+            Additional property updates to apply to each selected
+            polar object. If a property is specified in
+            both patch and in **kwargs then the one in **kwargs
+            takes precedence.
         Returns
         -------
         self
             Returns the Figure object that the method was called on
         """
         for obj in self.select_polars(selector=selector, row=row, col=col):
-            obj.update(patch)
+            obj.update(patch, **kwargs)
 
         return self
 
@@ -12654,7 +12672,9 @@ class Figure(BaseFigure):
 
         return self
 
-    def update_scenes(self, patch, selector=None, row=None, col=None):
+    def update_scenes(
+        self, patch=None, selector=None, row=None, col=None, **kwargs
+    ):
         """
         Perform a property update operation on all scene objects
         that satisfy the specified selection criteria
@@ -12675,14 +12695,18 @@ class Figure(BaseFigure):
             To select scene objects by row and column, the Figure
             must have been created using plotly.subplots.make_subplots.
             If None (the default), all scene objects are selected.
-        
+        **kwargs
+            Additional property updates to apply to each selected
+            scene object. If a property is specified in
+            both patch and in **kwargs then the one in **kwargs
+            takes precedence.
         Returns
         -------
         self
             Returns the Figure object that the method was called on
         """
         for obj in self.select_scenes(selector=selector, row=row, col=col):
-            obj.update(patch)
+            obj.update(patch, **kwargs)
 
         return self
 
@@ -12750,7 +12774,9 @@ class Figure(BaseFigure):
 
         return self
 
-    def update_ternaries(self, patch, selector=None, row=None, col=None):
+    def update_ternaries(
+        self, patch=None, selector=None, row=None, col=None, **kwargs
+    ):
         """
         Perform a property update operation on all ternary objects
         that satisfy the specified selection criteria
@@ -12771,14 +12797,18 @@ class Figure(BaseFigure):
             To select ternary objects by row and column, the Figure
             must have been created using plotly.subplots.make_subplots.
             If None (the default), all ternary objects are selected.
-        
+        **kwargs
+            Additional property updates to apply to each selected
+            ternary object. If a property is specified in
+            both patch and in **kwargs then the one in **kwargs
+            takes precedence.
         Returns
         -------
         self
             Returns the Figure object that the method was called on
         """
         for obj in self.select_ternaries(selector=selector, row=row, col=col):
-            obj.update(patch)
+            obj.update(patch, **kwargs)
 
         return self
 
@@ -12846,7 +12876,9 @@ class Figure(BaseFigure):
 
         return self
 
-    def update_xaxes(self, patch, selector=None, row=None, col=None):
+    def update_xaxes(
+        self, patch=None, selector=None, row=None, col=None, **kwargs
+    ):
         """
         Perform a property update operation on all xaxis objects
         that satisfy the specified selection criteria
@@ -12867,14 +12899,18 @@ class Figure(BaseFigure):
             To select xaxis objects by row and column, the Figure
             must have been created using plotly.subplots.make_subplots.
             If None (the default), all xaxis objects are selected.
-        
+        **kwargs
+            Additional property updates to apply to each selected
+            xaxis object. If a property is specified in
+            both patch and in **kwargs then the one in **kwargs
+            takes precedence.
         Returns
         -------
         self
             Returns the Figure object that the method was called on
         """
         for obj in self.select_xaxes(selector=selector, row=row, col=col):
-            obj.update(patch)
+            obj.update(patch, **kwargs)
 
         return self
 
@@ -12942,7 +12978,9 @@ class Figure(BaseFigure):
 
         return self
 
-    def update_yaxes(self, patch, selector=None, row=None, col=None):
+    def update_yaxes(
+        self, patch=None, selector=None, row=None, col=None, **kwargs
+    ):
         """
         Perform a property update operation on all yaxis objects
         that satisfy the specified selection criteria
@@ -12963,13 +13001,17 @@ class Figure(BaseFigure):
             To select yaxis objects by row and column, the Figure
             must have been created using plotly.subplots.make_subplots.
             If None (the default), all yaxis objects are selected.
-        
+        **kwargs
+            Additional property updates to apply to each selected
+            yaxis object. If a property is specified in
+            both patch and in **kwargs then the one in **kwargs
+            takes precedence.
         Returns
         -------
         self
             Returns the Figure object that the method was called on
         """
         for obj in self.select_yaxes(selector=selector, row=row, col=col):
-            obj.update(patch)
+            obj.update(patch, **kwargs)
 
         return self
diff --git a/plotly/graph_objs/_figurewidget.py b/plotly/graph_objs/_figurewidget.py
index 1b6831c41..71698ae07 100644
--- a/plotly/graph_objs/_figurewidget.py
+++ b/plotly/graph_objs/_figurewidget.py
@@ -12366,7 +12366,9 @@ class FigureWidget(BaseFigureWidget):
 
         return self
 
-    def update_geos(self, patch, selector=None, row=None, col=None):
+    def update_geos(
+        self, patch=None, selector=None, row=None, col=None, **kwargs
+    ):
         """
         Perform a property update operation on all geo objects
         that satisfy the specified selection criteria
@@ -12387,14 +12389,18 @@ class FigureWidget(BaseFigureWidget):
             To select geo objects by row and column, the Figure
             must have been created using plotly.subplots.make_subplots.
             If None (the default), all geo objects are selected.
-        
+        **kwargs
+            Additional property updates to apply to each selected
+            geo object. If a property is specified in
+            both patch and in **kwargs then the one in **kwargs
+            takes precedence.
         Returns
         -------
         self
             Returns the Figure object that the method was called on
         """
         for obj in self.select_geos(selector=selector, row=row, col=col):
-            obj.update(patch)
+            obj.update(patch, **kwargs)
 
         return self
 
@@ -12462,7 +12468,9 @@ class FigureWidget(BaseFigureWidget):
 
         return self
 
-    def update_mapboxes(self, patch, selector=None, row=None, col=None):
+    def update_mapboxes(
+        self, patch=None, selector=None, row=None, col=None, **kwargs
+    ):
         """
         Perform a property update operation on all mapbox objects
         that satisfy the specified selection criteria
@@ -12483,14 +12491,18 @@ class FigureWidget(BaseFigureWidget):
             To select mapbox objects by row and column, the Figure
             must have been created using plotly.subplots.make_subplots.
             If None (the default), all mapbox objects are selected.
-        
+        **kwargs
+            Additional property updates to apply to each selected
+            mapbox object. If a property is specified in
+            both patch and in **kwargs then the one in **kwargs
+            takes precedence.
         Returns
         -------
         self
             Returns the Figure object that the method was called on
         """
         for obj in self.select_mapboxes(selector=selector, row=row, col=col):
-            obj.update(patch)
+            obj.update(patch, **kwargs)
 
         return self
 
@@ -12558,7 +12570,9 @@ class FigureWidget(BaseFigureWidget):
 
         return self
 
-    def update_polars(self, patch, selector=None, row=None, col=None):
+    def update_polars(
+        self, patch=None, selector=None, row=None, col=None, **kwargs
+    ):
         """
         Perform a property update operation on all polar objects
         that satisfy the specified selection criteria
@@ -12579,14 +12593,18 @@ class FigureWidget(BaseFigureWidget):
             To select polar objects by row and column, the Figure
             must have been created using plotly.subplots.make_subplots.
             If None (the default), all polar objects are selected.
-        
+        **kwargs
+            Additional property updates to apply to each selected
+            polar object. If a property is specified in
+            both patch and in **kwargs then the one in **kwargs
+            takes precedence.
         Returns
         -------
         self
             Returns the Figure object that the method was called on
         """
         for obj in self.select_polars(selector=selector, row=row, col=col):
-            obj.update(patch)
+            obj.update(patch, **kwargs)
 
         return self
 
@@ -12654,7 +12672,9 @@ class FigureWidget(BaseFigureWidget):
 
         return self
 
-    def update_scenes(self, patch, selector=None, row=None, col=None):
+    def update_scenes(
+        self, patch=None, selector=None, row=None, col=None, **kwargs
+    ):
         """
         Perform a property update operation on all scene objects
         that satisfy the specified selection criteria
@@ -12675,14 +12695,18 @@ class FigureWidget(BaseFigureWidget):
             To select scene objects by row and column, the Figure
             must have been created using plotly.subplots.make_subplots.
             If None (the default), all scene objects are selected.
-        
+        **kwargs
+            Additional property updates to apply to each selected
+            scene object. If a property is specified in
+            both patch and in **kwargs then the one in **kwargs
+            takes precedence.
         Returns
         -------
         self
             Returns the Figure object that the method was called on
         """
         for obj in self.select_scenes(selector=selector, row=row, col=col):
-            obj.update(patch)
+            obj.update(patch, **kwargs)
 
         return self
 
@@ -12750,7 +12774,9 @@ class FigureWidget(BaseFigureWidget):
 
         return self
 
-    def update_ternaries(self, patch, selector=None, row=None, col=None):
+    def update_ternaries(
+        self, patch=None, selector=None, row=None, col=None, **kwargs
+    ):
         """
         Perform a property update operation on all ternary objects
         that satisfy the specified selection criteria
@@ -12771,14 +12797,18 @@ class FigureWidget(BaseFigureWidget):
             To select ternary objects by row and column, the Figure
             must have been created using plotly.subplots.make_subplots.
             If None (the default), all ternary objects are selected.
-        
+        **kwargs
+            Additional property updates to apply to each selected
+            ternary object. If a property is specified in
+            both patch and in **kwargs then the one in **kwargs
+            takes precedence.
         Returns
         -------
         self
             Returns the Figure object that the method was called on
         """
         for obj in self.select_ternaries(selector=selector, row=row, col=col):
-            obj.update(patch)
+            obj.update(patch, **kwargs)
 
         return self
 
@@ -12846,7 +12876,9 @@ class FigureWidget(BaseFigureWidget):
 
         return self
 
-    def update_xaxes(self, patch, selector=None, row=None, col=None):
+    def update_xaxes(
+        self, patch=None, selector=None, row=None, col=None, **kwargs
+    ):
         """
         Perform a property update operation on all xaxis objects
         that satisfy the specified selection criteria
@@ -12867,14 +12899,18 @@ class FigureWidget(BaseFigureWidget):
             To select xaxis objects by row and column, the Figure
             must have been created using plotly.subplots.make_subplots.
             If None (the default), all xaxis objects are selected.
-        
+        **kwargs
+            Additional property updates to apply to each selected
+            xaxis object. If a property is specified in
+            both patch and in **kwargs then the one in **kwargs
+            takes precedence.
         Returns
         -------
         self
             Returns the Figure object that the method was called on
         """
         for obj in self.select_xaxes(selector=selector, row=row, col=col):
-            obj.update(patch)
+            obj.update(patch, **kwargs)
 
         return self
 
@@ -12942,7 +12978,9 @@ class FigureWidget(BaseFigureWidget):
 
         return self
 
-    def update_yaxes(self, patch, selector=None, row=None, col=None):
+    def update_yaxes(
+        self, patch=None, selector=None, row=None, col=None, **kwargs
+    ):
         """
         Perform a property update operation on all yaxis objects
         that satisfy the specified selection criteria
@@ -12963,13 +13001,17 @@ class FigureWidget(BaseFigureWidget):
             To select yaxis objects by row and column, the Figure
             must have been created using plotly.subplots.make_subplots.
             If None (the default), all yaxis objects are selected.
-        
+        **kwargs
+            Additional property updates to apply to each selected
+            yaxis object. If a property is specified in
+            both patch and in **kwargs then the one in **kwargs
+            takes precedence.
         Returns
         -------
         self
             Returns the Figure object that the method was called on
         """
         for obj in self.select_yaxes(selector=selector, row=row, col=col):
-            obj.update(patch)
+            obj.update(patch, **kwargs)
 
         return self


Test patch:
diff --git a/plotly/tests/test_core/test_update_objects/test_update_subplots.py b/plotly/tests/test_core/test_update_objects/test_update_subplots.py
index d435cd1ca..7ad874021 100644
--- a/plotly/tests/test_core/test_update_objects/test_update_subplots.py
+++ b/plotly/tests/test_core/test_update_objects/test_update_subplots.py
@@ -287,8 +287,8 @@ class TestSelectForEachUpdateSubplots(TestCase):
             selector={'angularaxis.rotation': 0})
 
     def assert_update_subplots(
-            self, subplot_type, subplots_name, expected_nums, patch,
-            selector=None, row=None, col=None, test_no_grid=False):
+            self, subplot_type, subplots_name, expected_nums, patch=None,
+            selector=None, row=None, col=None, test_no_grid=False, **kwargs):
 
         update_fn = getattr(Figure, 'update_' + subplots_name)
 
@@ -300,7 +300,7 @@ class TestSelectForEachUpdateSubplots(TestCase):
 
             # perform update_*
             update_res = update_fn(
-                fig, patch, selector=selector, row=row, col=col)
+                fig, patch, selector=selector, row=row, col=col, **kwargs)
             self.assertIs(update_res, fig)
 
             # Build expected layout keys
@@ -316,7 +316,7 @@ class TestSelectForEachUpdateSubplots(TestCase):
                 if k in expected_keys:
                     # Make sure sure there is an initial difference
                     self.assertNotEqual(orig_obj, new_obj)
-                    orig_obj.update(patch)
+                    orig_obj.update(patch, **kwargs)
 
                 self.assertEqual(new_obj, orig_obj)
 
@@ -470,3 +470,11 @@ class TestSelectForEachUpdateSubplots(TestCase):
             {'radialaxis.title.font.family': 'Rockwell'},
             row=2, col=3,
             selector={'angularaxis.rotation': 0})
+
+        # kwargs
+        self.assert_update_subplots(
+            'xaxis', 'xaxes', [1, 2],
+            title_font_family='Courier',
+            title_font_color='yellow',
+            row=1,
+            selector={'title.text': 'A'})
diff --git a/plotly/tests/test_core/test_update_objects/test_update_traces.py b/plotly/tests/test_core/test_update_objects/test_update_traces.py
index 36d598d2a..70e7a5280 100644
--- a/plotly/tests/test_core/test_update_objects/test_update_traces.py
+++ b/plotly/tests/test_core/test_update_objects/test_update_traces.py
@@ -232,9 +232,8 @@ class TestSelectForEachUpdateTraces(TestCase):
 
     # test update_traces
     # ------------------
-    def assert_update_traces(
-            self, patch, expected_inds, selector=None, row=None, col=None
-    ):
+    def assert_update_traces(self, expected_inds, patch=None, selector=None,
+                             row=None, col=None, **kwargs):
         # Save off original figure
         fig_orig = copy.deepcopy(self.fig)
         for trace1, trace2 in zip(fig_orig.data, self.fig.data):
@@ -242,7 +241,7 @@ class TestSelectForEachUpdateTraces(TestCase):
 
         # Perform update
         update_res = self.fig.update_traces(
-            patch, selector=selector, row=row, col=col
+            patch, selector=selector, row=row, col=col, **kwargs
         )
 
         # Check chaining support
@@ -255,102 +254,70 @@ class TestSelectForEachUpdateTraces(TestCase):
                 self.assertNotEqual(t_orig, t)
 
                 # Check that traces are equal after update
-                t_orig.update(patch)
+                t_orig.update(patch, **kwargs)
 
             # Check that traces are equal
             self.assertEqual(t_orig, t)
 
     def test_update_traces_by_type(self):
-        self.assert_update_traces(
-            {'visible': 'legendonly'},
-            [0, 2],
-            selector={'type': 'scatter'}
-        )
+        self.assert_update_traces([0, 2], {'visible': 'legendonly'},
+                                  selector={'type': 'scatter'})
 
-        self.assert_update_traces(
-            {'visible': 'legendonly'},
-            [1],
-            selector={'type': 'bar'},
-        )
+        self.assert_update_traces([0, 2],
+                                  selector={'type': 'scatter'},
+                                  visible=False)
 
-        self.assert_update_traces(
-            {'colorscale': 'Viridis'},
-            [3],
-            selector={'type': 'heatmap'}
-        )
+        self.assert_update_traces([1], {'visible': 'legendonly'},
+                                  selector={'type': 'bar'})
+
+        self.assert_update_traces([3], {'colorscale': 'Viridis'},
+                                  selector={'type': 'heatmap'})
 
         # Nest dictionaries
-        self.assert_update_traces(
-            {'marker': {'line': {'color': 'yellow'}}},
-            [4, 5],
-            selector={'type': 'scatter3d'}
-        )
+        self.assert_update_traces([4, 5],
+                                  {'marker': {'line': {'color': 'yellow'}}},
+                                  selector={'type': 'scatter3d'})
 
         # dot syntax
-        self.assert_update_traces(
-            {'marker.line.color': 'cyan'},
-            [4, 5],
-            selector={'type': 'scatter3d'}
-        )
+        self.assert_update_traces([4, 5], {'marker.line.color': 'cyan'},
+                                  selector={'type': 'scatter3d'})
 
         # underscore syntax
-        self.assert_update_traces(
-            dict(marker_line_color='pink'),
-            [4, 5],
-            selector={'type': 'scatter3d'}
-        )
+        self.assert_update_traces([4, 5], dict(marker_line_color='pink'),
+                                  selector={'type': 'scatter3d'})
 
-        self.assert_update_traces(
-            {'line': {'dash': 'dot'}},
-            [6, 7],
-            selector={'type': 'scatterpolar'}
-        )
+        # underscore syntax with kwarg
+        self.assert_update_traces([4, 5],
+                                  selector={'type': 'scatter3d'},
+                                  marker_line_color='red')
+
+        self.assert_update_traces([6, 7], {'line': {'dash': 'dot'}},
+                                  selector={'type': 'scatterpolar'})
 
         # Nested dictionaries
-        self.assert_update_traces(
-            {'dimensions': {1: {'label': 'Dimension 1'}}},
-            [8],
-            selector={'type': 'parcoords'}
-        )
+        self.assert_update_traces([8], {
+            'dimensions': {1: {'label': 'Dimension 1'}}},
+                                  selector={'type': 'parcoords'})
 
         # Dot syntax
-        self.assert_update_traces(
-            {'dimensions[1].label': 'Dimension A'},
-            [8],
-            selector={'type': 'parcoords'}
-        )
+        self.assert_update_traces([8], {'dimensions[1].label': 'Dimension A'},
+                                  selector={'type': 'parcoords'})
 
         # underscore syntax
         # Dot syntax
-        self.assert_update_traces(
-            dict(dimensions_1_label='Dimension X'),
-            [8],
-            selector={'type': 'parcoords'}
-        )
+        self.assert_update_traces([8], dict(dimensions_1_label='Dimension X'),
+                                  selector={'type': 'parcoords'})
 
-        self.assert_update_traces(
-            {'hoverinfo': 'label+percent'},
-            [], selector={'type': 'pie'}
-        )
+        self.assert_update_traces([], {'hoverinfo': 'label+percent'},
+                                  selector={'type': 'pie'})
 
     def test_update_traces_by_grid_and_selector(self):
-        self.assert_update_traces(
-            {'marker.size': 5},
-            [4, 6],
-            selector={'marker.color': 'green'},
-            col=2
-        )
+        self.assert_update_traces([4, 6], {'marker.size': 5},
+                                  selector={'marker.color': 'green'}, col=2)
 
-        self.assert_update_traces(
-            {'marker.size': 6},
-            [0, 4],
-            selector={'marker.color': 'green'},
-            row=1
-        )
+        self.assert_update_traces([0, 4], {'marker.size': 6},
+                                  selector={'marker.color': 'green'}, row=1)
 
-        self.assert_update_traces(
-            {'marker.size': 6},
-            [6],
-            selector={'marker.color': 'green'},
-            row=2, col=2
-        )
+        self.assert_update_traces([6], {'marker.size': 6},
+                                  selector={'marker.color': 'green'}, row=2,
+                                  col=2)