Hi all!
I have the following snippet. The idea is that I do give a data file as input and do some scientific processing on the backend using my Python library.
I want to interactively display two graphs on my Dash. The problem is that if I run the same code using a Jupyter Notebook, the execution and display is instantaneous (I use matplotlib as you may have noticed). With Dash though, that’s extremely slow. I recognise it’s something on my end, as when I do single-output (and not multiple) one graph is instantaneous but the plot_csd_graph is super slow.
I tried profiling it but the cProfile
r says that’s the execution of the main function takes 0.5 seconds (but in reality, it takes around 20 seconds). Any ideas on how to debug or what am I doing wrong? Code follows!
Is that I need to save the output of the first class inside a hidden div or so?
Thanks for your time
# Set the relative data path
MYPATH = pathlib.Path(__file__).parent
DATA_PATH = MYPATH.joinpath("data").resolve()
def plot_atd(f, my_grain, my_poly_order, my_smoothes, my_window_len):
""" Plot the Arrival Time Distribution (ATD)
Args:
f (path): The f with the data (tab delim. CSV)
Returns:
It shows a plot. TODO: Return a matplotlib/plotly/JSON object
"""
# Plot the ATD
ms = MassSpectrum()
ms.read_text_file(f, 0, my_grain, normalisationtype="bpi")
ms.smoothingSG(my_window_len, my_smoothes, my_poly_order)
ms.normalisation_bpi()
# ms.select_ms_range(4200,9000)
# fig = plt.figure(figsize=(12, 8)
# ax = plt.subplot(311)
fig, ax = plt.subplots()
ms.plot_simulated_spectrum_simple(ax, color=tableau20[2])
return fig, ms
def plot_pp_csd(my_simul_peak, msobj):
pp = PeakPicking()
pp.calculate_gradient(msobj.xvals, msobj.yvals)
found_peaks = pp.find_peaks(1)
fig, ax2 = plt.subplots()
msobj.plot_simulated_spectrum_simple(ax2, color=tableau20[6])
for peak in found_peaks:
peak.plotSimulatedPeak(ax2, msobj.xvals, fwhm=my_simul_peak, color=tableau20[5])
# plt.show()
return fig
# Navigation bar and logo
logo = "assets/logo.png"
encoded_logo = base64.b64encode(open(logo, "rb").read())
navbar = dbc.Navbar(
[
html.A(
dbc.Row(
[
dbc.Col(
html.Img(
src="data:image/png;base64,{}".format(
encoded_logo.decode()
),
height="20px",
)
),
dbc.Col(
dbc.NavbarBrand(
"IMMS Dashboard",
className="navbar-brand",
)
),
],
align="center",
justify="between",
no_gutters=True,
),
href="/",
)
],
color="light",
dark=False,
)
# Content definitions
card_content_settings = [
dbc.CardHeader("Choose your settings"),
dbc.CardBody(
[
dcc.Upload(
id="upload-data",
children=dbc.Button("Upload Data", color="primary", className="mr-1"),
),
html.Label("Select grain:"),
dcc.Slider(
id="grain-slider", min=0, max=20, value=10, marks={0: "0", 20: "20"}
),
html.Label("Select the order of the poly:"),
dcc.Slider(
id="poly-order-slider",
min=0,
max=10,
value=5,
marks={0: "0", 5: "5", 10: "10"},
),
html.Label("Select the smooth parameter:"),
dcc.Slider(
id="smoothes-slider", min=0, max=10, value=2, marks={0: "0", 10: "10"}
),
html.Label("Select the window length:"),
dcc.Slider(
id="windowlen-slider",
min=0,
max=100,
value=10,
marks={0: "0", 50: "50", 100: "100"},
),
html.Label("Simulated peak:"),
dcc.Slider(
id="simulpeak-slider",
min=0,
max=120,
value=75,
marks={0: "0", 50: "50", 100: "100"},
),
]
),
]
adt_content_settings = [
dbc.CardHeader("ADT Plot"),
dbc.CardBody([dcc.Graph(id="adt-graph")]),
]
csd_content_settings = [
dbc.CardHeader("CSD Plot"),
dbc.CardBody([dcc.Graph(id="csd-graph")]),
]
input_data_raw = dbc.Row(
[
dbc.Col(dbc.Card(card_content_settings, outline=True), md=2),
dbc.Col(dbc.Card(adt_content_settings, outline=True), md=5),
dbc.Col(dbc.Card(csd_content_settings, outline=True), md=5),
]
# className="mb-4"
)
body = html.Div(
[input_data_raw],
style={"marginBottom": 50, "marginTop": 25, "text-align": "center"},
)
app.config["suppress_callback_exceptions"] = False
app.layout = html.Div([navbar, body])
@app.callback(
[
dash.dependencies.Output("adt-graph", "figure"),
dash.dependencies.Output("csd-graph", "figure"),
],
[
dash.dependencies.Input("upload-data", "filename"),
dash.dependencies.Input("grain-slider", "value"),
dash.dependencies.Input("poly-order-slider", "value"),
dash.dependencies.Input("smoothes-slider", "value"),
dash.dependencies.Input("windowlen-slider", "value"),
dash.dependencies.Input("simulpeak-slider", "value"),
],
)
def update_adt_graph(
data_file,
grain_value,
poly_order_value,
smoothes_value,
windowlen_value,
simulpeak_value,
):
atd, msobj = plot_atd(
DATA_PATH.joinpath(data_file),
grain_value,
poly_order_value,
smoothes_value,
windowlen_value,
)
return (
tls.mpl_to_plotly(atd),
go.Figure(tls.mpl_to_plotly(plot_pp_csd(simulpeak_value, msobj))),
)