1
1
import collections
2
2
import re
3
3
import typing as typ
4
+ import warnings
4
5
from contextlib import contextmanager
5
6
from copy import deepcopy
6
7
from typing import Dict , Tuple , Union , Callable , List
@@ -791,14 +792,114 @@ def _set_in(d, key_path_str, v):
791
792
792
793
# Add traces
793
794
# ----------
794
- def add_traces (self , data ):
795
+ @staticmethod
796
+ def _raise_invalid_rows_cols (name , n , invalid ):
797
+ rows_err_msg = """
798
+ If specified, the {name} parameter must be a list or tuple of integers
799
+ of length {n} (The number of traces being added)
800
+
801
+ Received: {invalid}
802
+ """ .format (name = name , n = n , invalid = invalid )
803
+
804
+ raise ValueError (rows_err_msg )
805
+
806
+ @staticmethod
807
+ def _validate_rows_cols (name , n , vals ):
808
+ if vals is None :
809
+ pass
810
+ elif isinstance (vals , (list , tuple )):
811
+ if len (vals ) != n :
812
+ BaseFigure ._raise_invalid_rows_cols (
813
+ name = name , n = n , invalid = vals )
814
+
815
+ if [r for r in vals if not isinstance (r , int )]:
816
+ BaseFigure ._raise_invalid_rows_cols (
817
+ name = name , n = n , invalid = vals )
818
+ else :
819
+ BaseFigure ._raise_invalid_rows_cols (name = name , n = n , invalid = vals )
820
+
821
+ def add_trace (self , trace , row = None , col = None ):
795
822
"""
796
- Add one or more traces to the figure
823
+ Add a trace to the figure
797
824
798
825
Parameters
799
826
----------
800
- data : BaseTraceType or dict or list[BaseTraceType or dict]
801
- A trace specification or list of trace specifications to be added.
827
+ trace : BaseTraceType or dict
828
+ Either:
829
+ - An instances of a trace classe from the plotly.graph_objs
830
+ package (e.g plotly.graph_objs.Scatter, plotly.graph_objs.Bar)
831
+ - or a dicts where:
832
+
833
+ - The 'type' property specifies the trace type (e.g.
834
+ 'scatter', 'bar', 'area', etc.). If the dict has no 'type'
835
+ property then 'scatter' is assumed.
836
+ - All remaining properties are passed to the constructor
837
+ of the specified trace type.
838
+
839
+ row : int or None (default)
840
+ Subplot row index (starting from 1) for the trace to be added.
841
+ Only valid if figure was created using
842
+ `plotly.tools.make_subplots`
843
+ col : int or None (default)
844
+ Subplot col index (starting from 1) for the trace to be added.
845
+ Only valid if figure was created using
846
+ `plotly.tools.make_subplots`
847
+
848
+ Returns
849
+ -------
850
+ BaseTraceType
851
+ The newly added trace
852
+
853
+ Examples
854
+ --------
855
+ >>> from plotly import tools
856
+ >>> import plotly.graph_objs as go
857
+
858
+ Add two Scatter traces to a figure
859
+ >>> fig = go.Figure()
860
+ >>> fig.add_trace(go.Scatter(x=[1,2,3], y=[2,1,2]))
861
+ >>> fig.add_trace(go.Scatter(x=[1,2,3], y=[2,1,2]))
862
+
863
+
864
+ Add two Scatter traces to vertically stacked subplots
865
+ >>> fig = tools.make_subplots(rows=2)
866
+ This is the format of your plot grid:
867
+ [ (1,1) x1,y1 ]
868
+ [ (2,1) x2,y2 ]
869
+
870
+ >>> fig.add_trace(go.Scatter(x=[1,2,3], y=[2,1,2]), row=1, col=1)
871
+ >>> fig.add_trace(go.Scatter(x=[1,2,3], y=[2,1,2]), row=2, col=1)
872
+ """
873
+ # Validate row/col
874
+ if row is not None and not isinstance (row , int ):
875
+ pass
876
+
877
+ if col is not None and not isinstance (col , int ):
878
+ pass
879
+
880
+ # Make sure we have both row and col or neither
881
+ if row is not None and col is None :
882
+ raise ValueError (
883
+ 'Received row parameter but not col.\n '
884
+ 'row and col must be specified together' )
885
+ elif col is not None and row is None :
886
+ raise ValueError (
887
+ 'Received col parameter but not row.\n '
888
+ 'row and col must be specified together' )
889
+
890
+ return self .add_traces (data = [trace ],
891
+ rows = [row ] if row is not None else None ,
892
+ cols = [col ] if col is not None else None
893
+ )[0 ]
894
+
895
+ def add_traces (self , data , rows = None , cols = None ):
896
+ """
897
+ Add traces to the figure
898
+
899
+ Parameters
900
+ ----------
901
+ data : list[BaseTraceType or dict]
902
+ A list of trace specifications to be added.
802
903
Trace specifications may be either:
803
904
804
905
- Instances of trace classes from the plotly.graph_objs
@@ -810,23 +911,70 @@ def add_traces(self, data):
810
911
property then 'scatter' is assumed.
811
912
- All remaining properties are passed to the constructor
812
913
of the specified trace type.
914
+
915
+ rows : None or list[int] (default None)
916
+ List of subplot row indexes (starting from 1) for the traces to be
917
+ added. Only valid if figure was created using
918
+ `plotly.tools.make_subplots`
919
+ cols : None or list[int] (default None)
920
+ List of subplot column indexes (starting from 1) for the traces
921
+ to be added. Only valid if figure was created using
922
+ `plotly.tools.make_subplots`
923
+
813
924
Returns
814
925
-------
815
926
tuple[BaseTraceType]
816
- Tuple of the newly added trace(s)
927
+ Tuple of the newly added traces
928
+
929
+ Examples
930
+ --------
931
+ >>> from plotly import tools
932
+ >>> import plotly.graph_objs as go
933
+
934
+ Add two Scatter traces to a figure
935
+ >>> fig = go.Figure()
936
+ >>> fig.add_traces([go.Scatter(x=[1,2,3], y=[2,1,2]),
937
+ ... go.Scatter(x=[1,2,3], y=[2,1,2])])
938
+
939
+ Add two Scatter traces to vertically stacked subplots
940
+ >>> fig = tools.make_subplots(rows=2)
941
+ This is the format of your plot grid:
942
+ [ (1,1) x1,y1 ]
943
+ [ (2,1) x2,y2 ]
944
+
945
+ >>> fig.add_traces([go.Scatter(x=[1,2,3], y=[2,1,2]),
946
+ ... go.Scatter(x=[1,2,3], y=[2,1,2])],
947
+ ... rows=[1, 2], cols=[1, 1])
817
948
"""
818
949
819
950
if self ._in_batch_mode :
820
951
self ._batch_layout_edits .clear ()
821
952
self ._batch_trace_edits .clear ()
822
953
raise ValueError ('Traces may not be added in a batch context' )
823
954
824
- if not isinstance (data , (list , tuple )):
825
- data = [data ]
826
-
827
- # Validate
955
+ # Validate traces
828
956
data = self ._data_validator .validate_coerce (data )
829
957
958
+ # Validate rows / cols
959
+ n = len (data )
960
+ BaseFigure ._validate_rows_cols ('rows' , n , rows )
961
+ BaseFigure ._validate_rows_cols ('cols' , n , cols )
962
+
963
+ # Make sure we have both rows and cols or neither
964
+ if rows is not None and cols is None :
965
+ raise ValueError (
966
+ 'Received rows parameter but not cols.\n '
967
+ 'rows and cols must be specified together' )
968
+ elif cols is not None and rows is None :
969
+ raise ValueError (
970
+ 'Received cols parameter but not rows.\n '
971
+ 'rows and cols must be specified together' )
972
+
973
+ # Apply rows / cols
974
+ if rows is not None :
975
+ for trace , row , col in zip (data , rows , cols ):
976
+ self ._set_trace_grid_position (trace , row , col )
977
+
830
978
# Make deep copy of trace data (Optimize later if needed)
831
979
new_traces_data = [deepcopy (trace ._props ) for trace in data ]
832
980
@@ -877,10 +1025,6 @@ def append_trace(self, trace, row, col):
877
1025
col: int
878
1026
Subplot column index (see Figure.print_grid)
879
1027
880
- :param (dict) trace: The data trace to be bound.
881
- :param (int) row: Subplot row index (see Figure.print_grid).
882
- :param (int) col: Subplot column index (see Figure.print_grid).
883
-
884
1028
Examples
885
1029
--------
886
1030
>>> from plotly import tools
@@ -894,6 +1038,14 @@ def append_trace(self, trace, row, col):
894
1038
>>> fig.append_trace(go.Scatter(x=[1,2,3], y=[2,1,2]), row=1, col=1)
895
1039
>>> fig.append_trace(go.Scatter(x=[1,2,3], y=[2,1,2]), row=2, col=1)
896
1040
"""
1041
+ warnings .warn ("""\
1042
+ The append_trace method is deprecated and will be removed in a future version.
1043
+ Please use the add_trace method with the row and col parameters.
1044
+ """ , DeprecationWarning )
1045
+
1046
+ self .add_trace (trace = trace , row = row , col = col )
1047
+
1048
+ def _set_trace_grid_position (self , trace , row , col ):
897
1049
try :
898
1050
grid_ref = self ._grid_ref
899
1051
except AttributeError :
@@ -931,8 +1083,6 @@ def append_trace(self, trace, row, col):
931
1083
trace ['xaxis' ] = ref [0 ]
932
1084
trace ['yaxis' ] = ref [1 ]
933
1085
934
- self .add_traces ([trace ])
935
-
936
1086
# Child property operations
937
1087
# -------------------------
938
1088
def _get_child_props (self , child ):
0 commit comments