@@ -595,6 +595,7 @@ def _parse_get_trace_props(
595
595
hf_y : Iterable = None ,
596
596
hf_text : Iterable = None ,
597
597
hf_hovertext : Iterable = None ,
598
+ check_nans : bool = True ,
598
599
) -> _hf_data_container :
599
600
"""Parse and capture the possibly high-frequency trace-props in a datacontainer.
600
601
@@ -603,14 +604,19 @@ def _parse_get_trace_props(
603
604
trace : BaseTraceType
604
605
The trace which will be parsed.
605
606
hf_x : Iterable, optional
606
- high -frequency trace "x" data, overrides the current trace its x-data.
607
+ High -frequency trace "x" data, overrides the current trace its x-data.
607
608
hf_y : Iterable, optional
608
- high -frequency trace "y" data, overrides the current trace its y-data.
609
+ High -frequency trace "y" data, overrides the current trace its y-data.
609
610
hf_text : Iterable, optional
610
- high -frequency trace "text" data, overrides the current trace its text-data.
611
+ High -frequency trace "text" data, overrides the current trace its text-data.
611
612
hf_hovertext : Iterable, optional
612
- high -frequency trace "hovertext" data, overrides the current trace its
613
+ High -frequency trace "hovertext" data, overrides the current trace its
613
614
hovertext data.
615
+ check_nans: bool, optional
616
+ Whether the `hf_y` should be checked for NaNs, by default True.
617
+ As checking for NaNs is expensive, this can be disabled when the `hf_y` is
618
+ already known to contain no NaNs (or when the downsampler can handle NaNs,
619
+ e.g., EveryNthPoint).
614
620
615
621
Returns
616
622
-------
@@ -680,7 +686,7 @@ def _parse_get_trace_props(
680
686
# Remove NaNs for efficiency (storing less meaningless data)
681
687
# NaNs introduce gaps between enclosing non-NaN data points & might distort
682
688
# the resampling algorithms
683
- if pd .isna (hf_y ).any ():
689
+ if check_nans and pd .isna (hf_y ).any ():
684
690
not_nan_mask = ~ pd .isna (hf_y )
685
691
hf_x = hf_x [not_nan_mask ]
686
692
hf_y = hf_y [not_nan_mask ]
@@ -821,6 +827,7 @@ def add_trace(
821
827
hf_y : Iterable = None ,
822
828
hf_text : Union [str , Iterable ] = None ,
823
829
hf_hovertext : Union [str , Iterable ] = None ,
830
+ check_nans : bool = True ,
824
831
** trace_kwargs ,
825
832
):
826
833
"""Add a trace to the figure.
@@ -848,7 +855,7 @@ def add_trace(
848
855
.. note::
849
856
If this variable is not set, ``_global_downsampler`` will be used.
850
857
limit_to_view: boolean, optional
851
- If set to True the trace's datapoints will be cut to the corresponding
858
+ If set to True, the trace's datapoints will be cut to the corresponding
852
859
front-end view, even if the total number of samples is lower than
853
860
``max_n_samples``, By default False.\n
854
861
Remark that setting this parameter to True ensures that low frequency traces
@@ -866,6 +873,13 @@ def add_trace(
866
873
hf_hovertext: Iterable, optional
867
874
The original high frequency hovertext. If set, this has priority over the
868
875
trace its ```hovertext`` argument.
876
+ check_nans: boolean, optional
877
+ If set to True, the trace's data will be checked for NaNs - which will be
878
+ removed. By default True.
879
+ As this is a costly operation, it is recommended to set this parameter to
880
+ False if you are sure that your data does not contain NaNs (or when the
881
+ downsampler can handle NaNs, e.g., EveryNthPoint). This should considerably
882
+ speed up the graph construction time.
869
883
**trace_kwargs: dict
870
884
Additional trace related keyword arguments.
871
885
e.g.: row=.., col=..., secondary_y=...
@@ -937,7 +951,7 @@ def add_trace(
937
951
938
952
# construct the hf_data_container
939
953
# TODO in future version -> maybe regex on kwargs which start with `hf_`
940
- dc = self ._parse_get_trace_props (trace , hf_x , hf_y , hf_text , hf_hovertext )
954
+ dc = self ._parse_get_trace_props (trace , hf_x , hf_y , hf_text , hf_hovertext , check_nans )
941
955
942
956
# These traces will determine the autoscale RANGE!
943
957
# -> so also store when `limit_to_view` is set.
@@ -996,6 +1010,7 @@ def add_traces(
996
1010
| List [AbstractSeriesAggregator ]
997
1011
| AbstractFigureAggregator = None ,
998
1012
limit_to_views : List [bool ] | bool = False ,
1013
+ check_nans : List [bool ] | bool = True ,
999
1014
** traces_kwargs ,
1000
1015
):
1001
1016
"""Add traces to the figure.
@@ -1030,13 +1045,22 @@ def add_traces(
1030
1045
aggregator is passed, all traces will use this aggregator.
1031
1046
If this variable is not set, ``_global_downsampler`` will be used.
1032
1047
limit_to_views : None | List[bool] | bool, optional
1033
- List of limit_to_view booleans for the added traces. If set to True
1034
- the trace's datapoints will be cut to the corresponding front-end view,
1035
- even if the total number of samples is lower than ``max_n_samples``. If a
1036
- single boolean is passed, all to be added traces will use this value,
1048
+ List of limit_to_view booleans for the added traces. If set to True the
1049
+ trace's datapoints will be cut to the corresponding front-end view, even if
1050
+ the total number of samples is lower than ``max_n_samples``.
1051
+ If a single boolean is passed, all to be added traces will use this value,
1037
1052
by default False.\n
1038
1053
Remark that setting this parameter to True ensures that low frequency traces
1039
1054
are added to the ``hf_data`` property.
1055
+ check_nans : None | List[bool] | bool, optional
1056
+ List of check_nans booleans for the added traces. If set to True, the
1057
+ trace's datapoints will be checked for NaNs. If a single boolean is passed,
1058
+ all to be added traces will use this value, by default True.\n
1059
+ As this is a costly operation, it is recommended to set this parameter to
1060
+ False if the data is known to contain no NaNs (or when the downsampler can
1061
+ handle NaNs, e.g., EveryNthPoint). This will considerably speed up the graph
1062
+ construction time.
1063
+
1040
1064
**traces_kwargs: dict
1041
1065
Additional trace related keyword arguments.
1042
1066
e.g.: rows=.., cols=..., secondary_ys=...
@@ -1076,9 +1100,11 @@ def add_traces(
1076
1100
downsamplers = [downsamplers ] * len (data )
1077
1101
if isinstance (limit_to_views , bool ):
1078
1102
limit_to_views = [limit_to_views ] * len (data )
1103
+ if isinstance (check_nans , bool ):
1104
+ check_nans = [check_nans ] * len (data )
1079
1105
1080
- for i , (trace , max_out , downsampler , limit_to_view ) in enumerate (
1081
- zip (data , max_n_samples , downsamplers , limit_to_views )
1106
+ for i , (trace , max_out , downsampler , limit_to_view , check_nan ) in enumerate (
1107
+ zip (data , max_n_samples , downsamplers , limit_to_views , check_nans )
1082
1108
):
1083
1109
if (
1084
1110
trace .type .lower () not in self ._high_frequency_traces
@@ -1090,7 +1116,7 @@ def add_traces(
1090
1116
if not limit_to_view and (trace .y is None or len (trace .y ) <= max_out_s ):
1091
1117
continue
1092
1118
1093
- dc = self ._parse_get_trace_props (trace )
1119
+ dc = self ._parse_get_trace_props (trace , check_nans = check_nan )
1094
1120
self ._hf_data [trace .uid ] = self ._construct_hf_data_dict (
1095
1121
dc ,
1096
1122
trace = trace ,
0 commit comments