-
Hi, |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 9 replies
-
Related issues: #56 |
Beta Was this translation helpful? Give feedback.
-
Hi @malammar0, From When #104 is merged, this will also be highlighted in our examples folder. For sake of completeness, I will copy a working example here: """Minimal dash app example.
Click on a button, and see a plotly-resampler graph of a noisy sinusoid.
No dynamic graph construction / pattern matching callbacks are needed.
This example uses the dash-extensions its ServersideOutput functionality to cache
the FigureResampler per user/session on the server side. This way, no global figure
variable is used and shows the best practice of using plotly-resampler Figures within
dash-apps.
"""
import dash
import numpy as np
import plotly.graph_objects as go
from dash import Input, Output, State, dcc, html
from dash_extensions.enrich import (
DashProxy,
ServersideOutput,
ServersideOutputTransform,
)
from plotly_resampler import FigureResampler
from trace_updater import TraceUpdater
# Data that will be used for the plotly-resampler figures
x = np.arange(2_000_000)
noisy_sin = (3 + np.sin(x / 200) + np.random.randn(len(x)) / 10) * x / 1_000
# --------------------------------------Globals ---------------------------------------
app = DashProxy(__name__, transforms=[ServersideOutputTransform()])
app.layout = html.Div(
[
html.H1("plotly-resampler + dash-extensions", style={"textAlign": "center"}),
html.Button("plot chart", id="plot-button", n_clicks=0),
html.Hr(),
# The graph and it's needed components to serialize and update efficiently
# Note: we also add a dcc.Store component, which will be used to link the
# server side cached FigureResampler object
dcc.Graph(id="graph-id"),
dcc.Loading(dcc.Store(id="store")),
TraceUpdater(id="trace-updater", gdID="graph-id"),
]
)
# ------------------------------------ DASH logic -------------------------------------
# The callback used to construct and store the FigureResampler on the serverside
@app.callback(
[Output("graph-id", "figure"), ServersideOutput("store", "data")],
Input("plot-button", "n_clicks"),
prevent_initial_call=True,
memoize=True,
)
def plot_graph(n_clicks):
ctx = dash.callback_context
if len(ctx.triggered) and "plot-button" in ctx.triggered[0]["prop_id"]:
fig: FigureResampler = FigureResampler(go.Figure())
# Figure construction logic
fig.add_trace(go.Scattergl(name="log"), hf_x=x, hf_y=noisy_sin * 0.9999995**x)
fig.add_trace(go.Scattergl(name="exp"), hf_x=x, hf_y=noisy_sin * 1.000002**x)
return fig, fig
else:
raise dash.exceptions.PreventUpdate()
@app.callback(
Output("trace-updater", "updateData"),
Input("graph-id", "relayoutData"),
State("store", "data"), # The server side cached FigureResampler per session
prevent_initial_call=True,
memoize=True,
)
def update_fig(relayoutdata, fig):
if fig is None:
raise dash.exceptions.PreventUpdate()
return fig.construct_update_data(relayoutdata)
# --------------------------------- Running the app ---------------------------------
if __name__ == "__main__":
app.run_server(debug=True, port=9023) Kind regards & Hope this answers your question, |
Beta Was this translation helpful? Give feedback.
-
Hi, |
Beta Was this translation helpful? Give feedback.
Hi @malammar0,
From
plotly-resampler>=0.8.0rc5
(pypi) on, we haveFigureResampler
serialization support. As a result, no global variables are needed and the figure can be cached per session using for example dash-extensions. This way, no global variables are used! 🔥When #104 is merged, this will also be highlighted in our examples folder. For sake of completeness, I will copy a working example here: