plotly-resampler
plotly-resampler copied to clipboard
[BUG] Using gunicorn to deploy a dash app with plotly-resampler in Linux
Describe the bug :crayon:
I am trying to use plotly-resampler to generate some figures in Dash app with big data.
step1. Use gunicorn to deploy it in Linux OS and configure the number of workers more than 1
step2. Scale the figure by dragging the mouse more than 10 times
step3. Click the top-right home icon button to reset the plotly figure, it cannot reset the figure like before.
Reproducing the bug :mag: app.py
import numpy as np
import plotly.graph_objects as go
from dash import dcc, Dash, html
from trace_updater import TraceUpdater
from plotly_resampler import FigureResampler
app = Dash(__name__)
server = app.server
fig = FigureResampler()
x = np.arange(1_000_000)
sin = (3 + np.sin(x / 200) + np.random.randn(len(x)) / 10) * x / 1_000
fig.add_trace(
go.Scattergl(
x=x,
y=sin,
name='demo',
mode='lines+markers'
),
max_n_samples=int(len(x) * 0.2)
)
app.layout = html.Div(
[
dcc.Graph(id='demo-graph', figure=fig),
TraceUpdater(id='demo-trace-updater', gdID='demo-graph')
]
)
fig.register_update_graph_callback(app, 'demo-graph')
if __name__ == '__main__':
app.run(debug=True)
deploy script with gunicorn in Linux:
gunicorn --workers=2 app:server -b :8090
step1. Execute deployment script in Linux OS and visit the Dash app
step2. Scale the figure by dragging the mouse more than 10 times
step3. Click the top-right home icon button to reset the plotly figure, it cannot reset the figure like before.
Expected behavior :wrench:
Scaling the figure and clicking the reset button can reset the figure before
Environment information: (please complete the following information)
- OS: Linux
- Python environment:
- Python version: 3.10.x
- plotly-resampler environment: Dash web app (Chrome)
- plotly-resampler version: 0.9.2
Thx for your attention.
Hi @SMOKTEA,
Thank you for providing such a detailed description. I was able to reproduce your example quite easily. 👏🏼
It appears that your (modified) example appears to work for me (tested it in both Firefox and Chromium).
Adapted app.py
⬇️ (Where I did omit the TraceUpdater
, as this was removed from plotly-resampler>=0.9.2
(see docs and examples).
import numpy as np
import plotly.graph_objects as go
from dash import dcc, Dash, html
from plotly_resampler import FigureResampler
app = Dash(__name__)
server = app.server
fig = FigureResampler()
x = np.arange(1_000_000)
sin = (3 + np.sin(x / 200) + np.random.randn(len(x)) / 10) * x / 1_000
fig.add_trace(
go.Scattergl(
x=x,
y=sin,
name='demo',
mode='lines+markers'
),
max_n_samples=int(len(x) * 0.2)
)
app.layout = html.Div([ dcc.Graph(id='demo-graph', figure=fig)])
fig.register_update_graph_callback(app, 'demo-graph')
if __name__ == '__main__':
app.run(debug=True)
Bash command that I utilized to start the gunicorn app (after installing gunicorn and gunicorn in python env):
poetry run gunicorn --workers=2 app:server -b :8097
(using both plotly-reampler=0.9.2.
and the last version on main yielded the expected behavior).
Gif demonstrating my working version:
Hope this helps you further, kind regards, Jonas
Thank you for replying me in a short time! I will try the solution removing whole traceupdaer component later, and back to let you know the expected result. By the way, have you tried the case scaling the figure more than 10 times? As for me, when the number of scaling actions less than 10 times, it seems work fine.
Have a nice day SMOKTEA
What do you mean exactly with scaling? zooming, panning, or resetting the axes? :)
Hi, @jonasvdd
I'm sorry for replying you so late cause blockebd by some own work projects these days. And I finally find the way reproduct the situation mentioned before.
You could donwload this zip and try: resampler_demo.zip
On the basis of previous, I use flask to combine multiple Dash App likes:
from flask import Flask
from app import app as figure_page_app
server = Flask(__name__)
routes = {
'/': figure_page_app
}
for route, app in routes.items():
app.init_app(
server,
routes_pathname_prefix=route,
requests_pathname_prefix=route,
)
And the other different is I use a Dash callback function to generate the figure options of the graph, likes:
@app.callback(
Output('demo-figure', 'figure'),
Input('figure-btn', 'nClicks')
)
def generate_figure_options(clicks_num):
if clicks_num is None:
raise PreventUpdate
x = np.arange(100000)
sin = (3 + np.sin(x / 200) + np.random.randn(len(x)) / 10) * x / 1_000
fig.add_trace(
go.Scattergl(
x=x,
y=sin,
name='demo',
mode='lines+markers'
),
max_n_samples=int(len(x) * 0.2)
)
return fig
Deploy script change to:
gunicorn --workers=2 server:server -b :8090
The steps are same likes before:
step1. Execute deployment script in Linux OS and visit the Dash app
step2. Zoom the figure
step3. Click the top-right home icon button to reset the plotly figure, it cannot reset the figure like before.
I hope I've described the reproduction method clearly
Thx for your attention.
What do you mean exactly with scaling? zooming, panning, or resetting the axes? :)
Hi, @jonasvdd
Have you tried the new demo code? It really confuses me.
Thx for your attention.
Hi @SMOKTEA,
Thank you for your patience. I took a look at your code and altered it slightly (utilized a more recent dash
version and installed dash-extensions
to utilize caching, which is better practice than utilizing a global variable.
However, with these applied changes, everything appears to work as intended. The reset-axes button works as expected. I had also @jvdd test this out (on my updated code version), and on his linux (kubuntu 22.04) machine, It worked as well.
I hope you will be able to get it working with my version. kind regards, Jonas
Thank you sooooooooo much! I will try the newest code later. And could you explain the reason cause this problem?
👍 Thx for your attention.
Have a nice day!