35
35
class AbstractFigureAggregator (BaseFigure , ABC ):
36
36
"""Abstract interface for data aggregation functionality for plotly figures."""
37
37
38
- _high_frequency_traces = ["scatter" , "scattergl" ] # TODO maybe change this
38
+ _high_frequency_traces = ["scatter" , "scattergl" ]
39
39
40
40
def __init__ (
41
41
self ,
@@ -96,7 +96,8 @@ def __init__(
96
96
97
97
self ._global_downsampler = default_downsampler
98
98
99
- # Given figure should always be a BaseFigure (that is not wrapped by a plotly-resampler class)
99
+ # Given figure should always be a BaseFigure that is not wrapped by
100
+ # a plotly-resampler class
100
101
assert isinstance (figure , BaseFigure )
101
102
assert not issubclass (type (figure ), AbstractFigureAggregator )
102
103
self ._figure_class = figure .__class__
@@ -445,8 +446,8 @@ def _get_figure_class(constr: type) -> type:
445
446
The plotly figure class (constructor) of the given `constr`.
446
447
447
448
"""
448
- from ..registering import get_plotly_constr # To avoid ImportError
449
- return get_plotly_constr (constr )
449
+ from ..registering import _get_plotly_constr # To avoid ImportError
450
+ return _get_plotly_constr (constr )
450
451
451
452
@staticmethod
452
453
def _slice_time (
@@ -565,31 +566,31 @@ def _to_hf_series(x: np.ndarray, y: np.ndarray) -> pd.Series:
565
566
def _parse_get_trace_props (
566
567
self ,
567
568
trace : BaseTraceType ,
568
- hf_x = None ,
569
- hf_y = None ,
570
- hf_text = None ,
571
- hf_hovertext = None ,
569
+ hf_x : Iterable = None ,
570
+ hf_y : Iterable = None ,
571
+ hf_text : Iterable = None ,
572
+ hf_hovertext : Iterable = None ,
572
573
) -> _hf_data_container :
573
574
"""Parse and capture the possibly high-frequency trace-props in a datacontainer.
574
575
575
576
Parameters
576
577
----------
577
578
trace : BaseTraceType
578
579
The trace which will be parsed.
579
- hf_x : _type_ , optional
580
- high-frequency trace "x" data, overrides the current trace its x-data
581
- hf_y : _type_ , optional
582
- high-frequency trace "y" data, overrides the current trace its y-data
583
- hf_text : _type_ , optional
580
+ hf_x : Iterable , optional
581
+ high-frequency trace "x" data, overrides the current trace its x-data.
582
+ hf_y : Iterable , optional
583
+ high-frequency trace "y" data, overrides the current trace its y-data.
584
+ hf_text : Iterable , optional
584
585
high-frequency trace "text" data, overrides the current trace its text-data.
585
- hf_hovertext : _type_ , optional
586
+ hf_hovertext : Iterable , optional
586
587
high-frequency trace "hovertext" data, overrides the current trace its
587
588
hovertext data.
588
589
589
590
Returns
590
591
-------
591
592
_hf_data_container
592
- A namedtuple which serves as a datacontainer
593
+ A namedtuple which serves as a datacontainer.
593
594
594
595
"""
595
596
hf_x = (
@@ -695,8 +696,8 @@ def _parse_get_trace_props(
695
696
696
697
def _construct_hf_data_dict (
697
698
self ,
698
- dc ,
699
- trace ,
699
+ dc : _hf_data_container ,
700
+ trace : BaseTraceType ,
700
701
downsampler : AbstractSeriesAggregator | None ,
701
702
max_n_samples : int | None ,
702
703
offset = 0 ,
@@ -706,7 +707,7 @@ def _construct_hf_data_dict(
706
707
Parameters
707
708
----------
708
709
dc : _hf_data_container
709
- The hf_data container, withholding the parsed hf-data
710
+ The hf_data container, withholding the parsed hf-data.
710
711
trace : BaseTraceType
711
712
The trace.
712
713
downsampler : AbstractSeriesAggregator | None
@@ -720,7 +721,8 @@ def _construct_hf_data_dict(
720
721
The hf_data dict.
721
722
"""
722
723
# We will re-create this each time as hf_x and hf_y withholds
723
- # high-frequency data
724
+ # high-frequency data and can be adjusted on the fly with the public hf_data
725
+ # property.
724
726
hf_series = self ._to_hf_series (x = dc .x , y = dc .y )
725
727
726
728
# Checking this now avoids less interpretable `KeyError` when resampling
@@ -748,6 +750,9 @@ def _construct_hf_data_dict(
748
750
default_downsampler = True
749
751
downsampler = self ._global_downsampler
750
752
753
+ # TODO -> can't we just store the DC here (might be less duplication of
754
+ # code knowledge, because now, you need to know all the eligible hf_keys in
755
+ # dc
751
756
return {
752
757
"max_n_samples" : max_n_samples ,
753
758
"default_n_samples" : default_n_samples ,
@@ -885,6 +890,8 @@ def add_trace(
885
890
uuid_str = str (uuid4 ()) if trace .uid is None else trace .uid
886
891
trace .uid = uuid_str
887
892
893
+ # construct the hf_data_container
894
+ # TODO in future version -> maybe regex on kwargs which start with `hf_`
888
895
dc = self ._parse_get_trace_props (trace , hf_x , hf_y , hf_text , hf_hovertext )
889
896
890
897
n_samples = len (dc .x )
@@ -922,6 +929,7 @@ def add_trace(
922
929
return super (self ._figure_class , self ).add_trace (trace , ** trace_kwargs )
923
930
else :
924
931
self ._print (f"[i] NOT resampling { trace ['name' ]} - len={ n_samples } " )
932
+ # TODO: can be made more generic
925
933
trace .x = dc .x
926
934
trace .y = dc .y
927
935
trace .text = dc .text
@@ -940,10 +948,10 @@ def add_traces(
940
948
limit_to_views : List [bool ] | bool = False ,
941
949
** traces_kwargs ,
942
950
):
943
- """Add traces to the figure
951
+ """Add traces to the figure.
944
952
945
953
.. note::
946
- make sure to look at the :func:`add_trace` function for more info about
954
+ Make sure to look at the :func:`add_trace` function for more info about
947
955
**speed optimization**, and dealing with not ``high-frequency`` data, but
948
956
still want to resample / limit the data to the front-end view.
949
957
@@ -954,7 +962,7 @@ def add_traces(
954
962
Trace specifications may be either:
955
963
956
964
- Instances of trace classes from the plotly.graph_objs
957
- package (e.g plotly.graph_objs.Scatter, plotly.graph_objs.Bar)
965
+ package (e.g plotly.graph_objs.Scatter, plotly.graph_objs.Bar).
958
966
- Dicts where:
959
967
960
968
- The 'type' property specifies the trace type (e.g.
@@ -992,7 +1000,7 @@ def add_traces(
992
1000
if not isinstance (data , (list , tuple )):
993
1001
data = [data ]
994
1002
995
- # Convert each trace into a trace object
1003
+ # Convert each trace into a BaseTraceType object
996
1004
data = [
997
1005
self ._data_validator .validate_coerce (trace )[0 ]
998
1006
if not isinstance (trace , BaseTraceType )
@@ -1036,9 +1044,11 @@ def add_traces(
1036
1044
offset = i ,
1037
1045
)
1038
1046
1039
- trace = trace ._props # convert the trace into a dict
1047
+ # convert the trace into a dict, and only withholds the non-hf props
1048
+ trace = trace ._props
1040
1049
trace = {k : trace [k ] for k in set (trace .keys ()).difference (set (dc ._fields ))}
1041
1050
1051
+ # update the trace data with the HF props
1042
1052
trace = self ._check_update_trace_data (trace )
1043
1053
assert trace is not None
1044
1054
data [i ] = trace
@@ -1071,14 +1081,16 @@ def _copy_hf_data(self, hf_data: dict, adjust_default_values: bool = False) -> d
1071
1081
The copied (& default values adjusted) output dict.
1072
1082
1073
1083
"""
1084
+ # TODO: add pass by reference tests for this method
1074
1085
hf_data_cp = {
1075
- k : {
1076
- k_ : hf_data [ k ][ k_ ]
1077
- for k_ in set (v .keys ()) # .difference(_hf_data_container._fields )
1086
+ uid : {
1087
+ k : hf_dict [ k ]
1088
+ for k in set (hf_dict .keys ())
1078
1089
}
1079
- for k , v in hf_data .items ()
1090
+ for uid , hf_dict in hf_data .items ()
1080
1091
}
1081
1092
1093
+ # Adjust the default arguments to the current argument values
1082
1094
if adjust_default_values :
1083
1095
for hf_props in hf_data_cp .values ():
1084
1096
if hf_props .get ("default_downsampler" , False ):
0 commit comments