Skip to content

Commit a99e088

Browse files
committed
🔥 improving kaleido output
1 parent 386944f commit a99e088

File tree

1 file changed

+37
-30
lines changed

1 file changed

+37
-30
lines changed

plotly_resampler/figure_resampler/figure_resampler.py

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030

3131
class JupyterDashPersistentInlineOutput(JupyterDash):
32-
""" Extension of the JupyterDash class to support the custom inline output for
32+
"""Extension of the JupyterDash class to support the custom inline output for
3333
``FigureResampler`` figures.
3434
3535
Specifically we embed a div in the notebook to display the figure inline.
@@ -46,7 +46,7 @@ class JupyterDashPersistentInlineOutput(JupyterDash):
4646
4747
.. Note::
4848
This subclass is only used when the mode is set to ``"inline_persistent"`` in
49-
the :func:`FigureResampler.show_dash <plotly_resampler.figure_resampler.FigureResampler.show_dash>`
49+
the :func:`FigureResampler.show_dash <plotly_resampler.figure_resampler.FigureResampler.show_dash>`
5050
method. However, the mode should be passed as ``"inline"`` since this subclass
5151
overwrites the inline behavior.
5252
"""
@@ -57,8 +57,8 @@ def __init__(self, *args, **kwargs):
5757
self._uid = str(uuid.uuid4()) # A new unique id for each app
5858

5959
# Mimic the _alive_{token} endpoint but with cors
60-
@self.server.route(f'/_is_alive_{self._uid}', methods=['GET'])
61-
@cross_origin(origin=['*'], allow_headers=['Content-Type'])
60+
@self.server.route(f"/_is_alive_{self._uid}", methods=["GET"])
61+
@cross_origin(origin=["*"], allow_headers=["Content-Type"])
6262
def broadcast_alive():
6363
return "Alive"
6464

@@ -74,7 +74,10 @@ def _display_inline_output(self, dashboard_url, width, height):
7474

7575
# Get the image from the dashboard and encode it as base64
7676
fig = self.layout.children[0].figure # is stored there in the show_dash method
77-
fig_base64 = base64.b64encode(fig.to_image("png")).decode("utf8")
77+
f_width = 1000 if fig.layout.width is None else fig.layout.width
78+
fig_base64 = base64.b64encode(
79+
fig.to_image(format="png", width=f_width, scale=1, height=fig.layout.height)
80+
).decode("utf8")
7881

7982
# The unique id of this app
8083
# This id is used to couple the output in the notebook with this app
@@ -85,23 +88,23 @@ def _display_inline_output(self, dashboard_url, width, height):
8588
# The html (& javascript) code to display the app / figure
8689
display(
8790
{
88-
"text/html":
89-
f"""
91+
"text/html": f"""
9092
<div id='PR_div__{uid}'></div>
9193
<script type='text/javascript'>
92-
""" +
9394
"""
95+
+ """
9496
9597
function setOutput(timeout) {
96-
""" +
97-
# Variables should be in local scope (in the closure)
98-
f"""
98+
"""
99+
+
100+
# Variables should be in local scope (in the closure)
101+
f"""
99102
var pr_div = document.getElementById('PR_div__{uid}');
100103
var url = '{dashboard_url}';
101104
var pr_img_src = 'data:image/png;base64, {fig_base64}';
102105
var is_alive_suffix = '_is_alive_{uid}';
103-
""" +
104106
"""
107+
+ """
105108
106109
if (pr_div.firstChild) return // return if already loaded
107110
@@ -135,12 +138,14 @@ def _display_inline_output(self, dashboard_url, width, height):
135138
var pr_img = document.createElement("img");
136139
pr_img.setAttribute("src", pr_img_src)
137140
pr_img.setAttribute("alt", 'Server unreachable - using image instead');
138-
""" +
139-
f"""
140-
pr_img.setAttribute("width", '{width}');
141-
pr_img.setAttribute("height", '{height}');
142-
""" +
143141
"""
142+
+ f"""
143+
pr_img.setAttribute("max-width", '{width}');
144+
pr_img.setAttribute("max-height", '{height}');
145+
pr_img.setAttribute("width", 'auto');
146+
pr_img.setAttribute("height", 'auto');
147+
"""
148+
+ """
144149
element.appendChild(pr_img);
145150
}
146151
@@ -150,17 +155,20 @@ def _display_inline_output(self, dashboard_url, width, height):
150155
pr_iframe.setAttribute("src", url);
151156
pr_iframe.setAttribute("frameborder", '0');
152157
pr_iframe.setAttribute("allowfullscreen", '');
153-
""" +
154-
f"""
158+
"""
159+
+ f"""
155160
pr_iframe.setAttribute("width", '{width}');
156161
pr_iframe.setAttribute("height", '{height}');
157-
""" +
158162
"""
163+
+ """
159164
element.appendChild(pr_iframe);
160165
}
161166
</script>
162167
"""
163-
}, raw=True, clear=True, display_id=uid,
168+
},
169+
raw=True,
170+
clear=True,
171+
display_id=uid,
164172
)
165173

166174
def _display_in_jupyter(self, dashboard_url, port, mode, width, height):
@@ -257,7 +265,7 @@ def __init__(
257265
f._grid_ref = figure._grid_ref
258266
f.add_traces(figure.data)
259267
elif isinstance(figure, dict) and (
260-
"data" in figure or "layout" in figure # or "frames" in figure # TODO
268+
"data" in figure or "layout" in figure # or "frames" in figure # TODO
261269
):
262270
# A figure as a dict, can be;
263271
# - a plotly figure as a dict (after calling `fig.to_dict()`)
@@ -279,7 +287,9 @@ def __init__(
279287
# A single trace dict or a list of traces
280288
f.add_traces(figure)
281289

282-
self._show_dash_kwargs = show_dash_kwargs if show_dash_kwargs is not None else {}
290+
self._show_dash_kwargs = (
291+
show_dash_kwargs if show_dash_kwargs is not None else {}
292+
)
283293

284294
super().__init__(
285295
f,
@@ -360,9 +370,9 @@ def show_dash(
360370
361371
"""
362372
available_modes = ["external", "inline", "inline_persistent", "jupyterlab"]
363-
assert mode is None or mode in available_modes, (
364-
f"mode must be one of {available_modes}"
365-
)
373+
assert (
374+
mode is None or mode in available_modes
375+
), f"mode must be one of {available_modes}"
366376
graph_properties = {} if graph_properties is None else graph_properties
367377
assert "config" not in graph_properties.keys() # There is a param for config
368378
# 1. Construct the Dash app layout
@@ -387,10 +397,7 @@ def show_dash(
387397
self.register_update_graph_callback(app, "resample-figure", "trace-updater")
388398

389399
# 2. Run the app
390-
if (
391-
mode == "inline"
392-
and "height" not in kwargs
393-
):
400+
if mode == "inline" and "height" not in kwargs:
394401
# If app height is not specified -> re-use figure height for inline dash app
395402
# Note: default layout height is 450 (whereas default app height is 650)
396403
# See: https://plotly.com/python/reference/layout/#layout-height

0 commit comments

Comments
 (0)