Skip to content

Commit fd8c2f6

Browse files
committed
🚲 add show_dash_kwargs to FigureResampler constructor
1 parent f9929de commit fd8c2f6

File tree

3 files changed

+59
-17
lines changed

3 files changed

+59
-17
lines changed

plotly_resampler/figure_resampler/figure_resampler.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
__author__ = "Jonas Van Der Donckt, Jeroen Van Der Donckt, Emiel Deprost"
1212

1313
import warnings
14-
from typing import Tuple
14+
from typing import Tuple, List
1515

1616
import dash
1717
import plotly.graph_objects as go
@@ -41,6 +41,7 @@ def __init__(
4141
show_mean_aggregation_size: bool = True,
4242
convert_traces_kwargs: dict | None = None,
4343
verbose: bool = False,
44+
show_dash_kwargs: dict | None = None,
4445
):
4546
# `pr_props`` is a variable to store properties of a plotly-resampler figure
4647
# This variable will only be set when loading a pickled plotly-resampler figure
@@ -85,6 +86,8 @@ def __init__(
8586
# A single trace dict or a list of traces
8687
f.add_traces(figure)
8788

89+
self._show_dash_kwargs = show_dash_kwargs if show_dash_kwargs is not None else {}
90+
8891
super().__init__(
8992
f,
9093
convert_existing_traces,
@@ -155,6 +158,8 @@ def show_dash(
155158
See more https://dash.plotly.com/dash-core-components/graph
156159
**kwargs: dict
157160
Additional app.run_server() kwargs. e.g.: port
161+
Note that these kwargs take precedence over the ones passed to the
162+
constructor via the ``show_dash_kwargs`` argument.
158163
159164
"""
160165
graph_properties = {} if graph_properties is None else graph_properties
@@ -184,6 +189,9 @@ def show_dash(
184189
fig_height = self.layout.height if self.layout.height is not None else 450
185190
kwargs["height"] = fig_height + 18
186191

192+
# kwargs take precedence over the show_dash_kwargs
193+
kwargs = {**self._show_dash_kwargs, **kwargs}
194+
187195
# Store the app information, so it can be killed
188196
self._app = app
189197
self._host = kwargs.get("host", "127.0.0.1")
@@ -241,5 +249,10 @@ def register_update_graph_callback(
241249
prevent_initial_call=True,
242250
)(self.construct_update_data)
243251

252+
def _get_pr_props_keys(self) -> List[str]:
253+
# Add the additional plotly-resampler properties of this class
254+
return super()._get_pr_props_keys() + ["_show_dash_kwargs"]
255+
244256
def _ipython_display_(self):
245-
return self.show_dash(mode="inline")
257+
# To display the figure inline as a dash app
258+
self.show_dash(mode="inline")

plotly_resampler/figure_resampler/figure_resampler_interface.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,6 +1273,25 @@ def _re_matches(regex: re.Pattern, strings: Iterable[str]) -> List[str]:
12731273
return sorted(matches)
12741274

12751275
## Magic methods (to use plotly.py words :grin:)
1276+
1277+
def _get_pr_props_keys(self) -> List[str]:
1278+
"""Returns the keys (i.e., the names) of the plotly-resampler properties.
1279+
1280+
Note
1281+
----
1282+
This method is used to serialize the object in the `__reduce__` method.
1283+
1284+
"""
1285+
return [
1286+
"_hf_data",
1287+
"_global_n_shown_samples",
1288+
"_print_verbose",
1289+
"_show_mean_aggregation_size",
1290+
"_prefix",
1291+
"_suffix",
1292+
"_global_downsampler",
1293+
]
1294+
12761295
def __reduce__(self):
12771296
"""Overwrite the reduce method (which is used to support deep copying and
12781297
pickling).
@@ -1288,15 +1307,6 @@ def __reduce__(self):
12881307

12891308
# Add the plotly-resampler properties
12901309
props["pr_props"] = {}
1291-
pr_keys = [
1292-
"_hf_data",
1293-
"_global_n_shown_samples",
1294-
"_print_verbose",
1295-
"_show_mean_aggregation_size",
1296-
"_prefix",
1297-
"_suffix",
1298-
"_global_downsampler",
1299-
]
1300-
for k in pr_keys:
1310+
for k in self._get_pr_props_keys():
13011311
props["pr_props"][k] = getattr(self, k)
13021312
return (self.__class__, (props,)) # (props,) to comply with plotly magic

tests/test_serialization.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from hashlib import sha1
12
import plotly.graph_objects as go
23
import plotly.express as px
34
import numpy as np
@@ -23,14 +24,16 @@ def test_pickle_figure_resampler(pickle_figure):
2324
nb_traces = 3
2425
nb_samples = 5_007
2526

26-
fig = FigureResampler(default_n_shown_samples=50)
27+
fig = FigureResampler(default_n_shown_samples=50, show_dash_kwargs=dict(port=8051))
2728
for i in range(nb_traces):
2829
fig.add_trace(go.Scattergl(name=f"trace--{i}"), hf_y=np.arange(nb_samples))
30+
assert fig._show_dash_kwargs["port"] == 8051
2931

3032
pickle.dump(fig, open(pickle_figure, "wb"))
3133
fig_pickle = pickle.load(open(pickle_figure, "rb"))
3234

3335
assert isinstance(fig_pickle, FigureResampler)
36+
assert fig_pickle._show_dash_kwargs["port"] == 8051
3437
assert len(fig_pickle.data) == nb_traces
3538
assert len(fig_pickle.hf_data) == nb_traces
3639
for i in range(nb_traces):
@@ -73,20 +76,22 @@ def test_pickle_figure_resampler_registered(registering_cleanup, pickle_figure):
7376
nb_traces = 4
7477
nb_samples = 5_043
7578

76-
register_plotly_resampler(mode="figure", default_n_shown_samples=50)
79+
register_plotly_resampler(mode="figure", default_n_shown_samples=50, show_dash_kwargs=dict(port=8051))
7780

7881
fig = go.Figure()
7982
for i in range(nb_traces):
8083
fig.add_trace(go.Scattergl(name=f"trace--{i}"), hf_y=np.arange(nb_samples))
8184
assert isinstance(fig, FigureResampler)
8285
assert not isinstance(fig, FigureWidgetResampler)
86+
assert fig._show_dash_kwargs["port"] == 8051
8387

8488
pickle.dump(fig, open(pickle_figure, "wb"))
8589

8690
# Loading with PR registered
8791
assert isinstance(go.Figure(), FigureResampler)
8892
fig_pickle = pickle.load(open(pickle_figure, "rb"))
8993
assert isinstance(fig_pickle, FigureResampler)
94+
assert fig_pickle._show_dash_kwargs["port"] == 8051
9095
assert len(fig_pickle.data) == nb_traces
9196
assert len(fig_pickle.hf_data) == nb_traces
9297
for i in range(nb_traces):
@@ -104,6 +109,7 @@ def test_pickle_figure_resampler_registered(registering_cleanup, pickle_figure):
104109
assert not isinstance(go.Figure(), FigureResampler)
105110
fig_pickle = pickle.load(open(pickle_figure, "rb"))
106111
assert isinstance(fig_pickle, FigureResampler)
112+
assert fig_pickle._show_dash_kwargs["port"] == 8051
107113
assert len(fig_pickle.data) == nb_traces
108114
assert len(fig_pickle.hf_data) == nb_traces
109115
for i in range(nb_traces):
@@ -121,6 +127,7 @@ def test_pickle_figure_resampler_registered(registering_cleanup, pickle_figure):
121127
assert not isinstance(go.Figure(), FigureResampler)
122128
fig_pickle = pickle.load(open(pickle_figure, "rb"))
123129
assert isinstance(fig_pickle, FigureResampler)
130+
assert fig_pickle._show_dash_kwargs["port"] == 8051
124131
assert len(fig_pickle.data) == nb_traces
125132
assert len(fig_pickle.hf_data) == nb_traces
126133
for i in range(nb_traces):
@@ -138,6 +145,7 @@ def test_pickle_figure_resampler_registered(registering_cleanup, pickle_figure):
138145
pickle.dump(fig, open(pickle_figure, "wb"))
139146
fig_pickle = pickle.load(open(pickle_figure, "rb"))
140147
assert isinstance(fig_pickle, FigureResampler)
148+
assert fig_pickle._show_dash_kwargs["port"] == 8051
141149
assert len(fig_pickle.data) == nb_traces
142150
assert len(fig_pickle.hf_data) == nb_traces
143151
for i in range(nb_traces):
@@ -239,13 +247,15 @@ def test_copy_and_deepcopy_figure_resampler():
239247
nb_traces = 3
240248
nb_samples = 3_243
241249

242-
fig = FigureResampler(default_n_shown_samples=50)
250+
fig = FigureResampler(default_n_shown_samples=50, show_dash_kwargs=dict(port=8051))
243251
for i in range(nb_traces):
244252
fig.add_trace(go.Scattergl(name=f"trace--{i}"), hf_y=np.arange(nb_samples))
253+
assert fig._show_dash_kwargs["port"] == 8051
245254

246255
fig_copy = copy.copy(fig)
247256

248257
assert isinstance(fig_copy, FigureResampler)
258+
assert fig_copy._show_dash_kwargs["port"] == 8051
249259
assert len(fig_copy.data) == nb_traces
250260
assert len(fig_copy.hf_data) == nb_traces
251261
for i in range(nb_traces):
@@ -260,6 +270,7 @@ def test_copy_and_deepcopy_figure_resampler():
260270
fig_copy = copy.deepcopy(fig)
261271

262272
assert isinstance(fig_copy, FigureResampler)
273+
assert fig_copy._show_dash_kwargs["port"] == 8051
263274
assert len(fig_copy.data) == nb_traces
264275
assert len(fig_copy.hf_data) == nb_traces
265276
for i in range(nb_traces):
@@ -314,18 +325,20 @@ def test_copy_figure_resampler_registered():
314325
nb_traces = 3
315326
nb_samples = 4_069
316327

317-
register_plotly_resampler(mode="figure", default_n_shown_samples=50)
328+
register_plotly_resampler(mode="figure", default_n_shown_samples=50, show_dash_kwargs=dict(port=8051))
318329

319330
fig = go.Figure()
320331
for i in range(nb_traces):
321332
fig.add_trace(go.Scattergl(name=f"trace--{i}"), hf_y=np.arange(nb_samples))
322333
assert isinstance(fig, FigureResampler)
323334
assert not isinstance(fig, FigureWidgetResampler)
335+
assert fig._show_dash_kwargs["port"] == 8051
324336

325337
# Copy with PR registered
326338
fig_copy = copy.copy(fig)
327339
assert isinstance(go.Figure(), FigureResampler)
328340
assert isinstance(fig_copy, FigureResampler)
341+
assert fig_copy._show_dash_kwargs["port"] == 8051
329342
assert len(fig_copy.data) == nb_traces
330343
assert len(fig_copy.hf_data) == nb_traces
331344
for i in range(nb_traces):
@@ -343,6 +356,7 @@ def test_copy_figure_resampler_registered():
343356
assert not isinstance(go.Figure(), FigureResampler)
344357
fig_copy = copy.copy(fig)
345358
assert isinstance(fig_copy, FigureResampler)
359+
assert fig_copy._show_dash_kwargs["port"] == 8051
346360
assert len(fig_copy.data) == nb_traces
347361
assert len(fig_copy.hf_data) == nb_traces
348362
for i in range(nb_traces):
@@ -360,6 +374,7 @@ def test_copy_figure_resampler_registered():
360374
assert not isinstance(go.Figure(), FigureResampler)
361375
fig_copy = copy.copy(fig)
362376
assert isinstance(fig_copy, FigureResampler)
377+
assert fig_copy._show_dash_kwargs["port"] == 8051
363378
assert len(fig_copy.data) == nb_traces
364379
assert len(fig_copy.hf_data) == nb_traces
365380
for i in range(nb_traces):
@@ -376,18 +391,20 @@ def test_deepcopy_figure_resampler_registered():
376391
nb_traces = 4
377392
nb_samples = 3_169
378393

379-
register_plotly_resampler(mode="figure", default_n_shown_samples=50)
394+
register_plotly_resampler(mode="figure", default_n_shown_samples=50, show_dash_kwargs=dict(port=8051))
380395

381396
fig = go.Figure()
382397
for i in range(nb_traces):
383398
fig.add_trace(go.Scattergl(name=f"trace--{i}"), hf_y=np.arange(nb_samples))
384399
assert isinstance(fig, FigureResampler)
385400
assert not isinstance(fig, FigureWidgetResampler)
401+
assert fig._show_dash_kwargs["port"] == 8051
386402

387403
# Copy with PR registered
388404
fig_copy = copy.deepcopy(fig)
389405
assert isinstance(go.Figure(), FigureResampler)
390406
assert isinstance(fig_copy, FigureResampler)
407+
assert fig_copy._show_dash_kwargs["port"] == 8051
391408
assert len(fig_copy.data) == nb_traces
392409
assert len(fig_copy.hf_data) == nb_traces
393410
for i in range(nb_traces):
@@ -405,6 +422,7 @@ def test_deepcopy_figure_resampler_registered():
405422
assert not isinstance(go.Figure(), FigureResampler)
406423
fig_copy = copy.deepcopy(fig)
407424
assert isinstance(fig_copy, FigureResampler)
425+
assert fig_copy._show_dash_kwargs["port"] == 8051
408426
assert len(fig_copy.data) == nb_traces
409427
assert len(fig_copy.hf_data) == nb_traces
410428
for i in range(nb_traces):
@@ -422,6 +440,7 @@ def test_deepcopy_figure_resampler_registered():
422440
assert not isinstance(go.Figure(), FigureResampler)
423441
fig_copy = copy.deepcopy(fig)
424442
assert isinstance(fig_copy, FigureResampler)
443+
assert fig_copy._show_dash_kwargs["port"] == 8051
425444
assert len(fig_copy.data) == nb_traces
426445
assert len(fig_copy.hf_data) == nb_traces
427446
for i in range(nb_traces):

0 commit comments

Comments
 (0)