Hi @YaKuzuri , thanks for the code example. As you will see in the following screenshot, after the first reload, it seems that the two first charts are not displayed, but they are. You can see the stats and a bit of the beginning of the Kaplan-Meier curves (if you hover and click on it the chart appears entirely). The thing is that is useless and confusing.
If I’m right, when new DashKaplanMeier
components is injected via callback, they might render before the browser fully recalculates layout, especially if they rely on canvas or SVG sizing that’s computed based on their container’s visible dimensions.
If you wrap each DahKaplanMeier
component inside a dcc.Loading
the problem is solved.
Another alternative to solve the problem, is to add in each DahKaplanMeier
style a 'minHeight': 500
. This also will avoid the bad performance.
Other things I would change (that are not involved in your problem) according your code example are the following:
- In the
DashKaplanMeier
style there is a grammatical error. Change high
by height
.
- When you declare the
app.layout
, you are wrapping everything in a list. I think is not a good practice and sometimes can be the problem of a bad performance depending on what you are using in your Dash app. Wrap everything inside an html.Div
.
- If the children of your
reload_div
, is empty when you declare the app.layout
, there is no need to write an empty list there.
As I said, this things are not involved in your problem, and are personal opinion. Here I leave you the final code with my modifications that is working fine. I hope it works also for you 
from dash import Dash, html, dcc, callback, Output, Input
import random
import dash_kaplan_meier as dkm
from dash_kaplan_meier.survival_stats import compute_survival_stats
n = 50 # Number of random numbers
groups = ['Group 1', 'Group 2']
time_observed = random.choices(range(1, 36), k=n)
time_to_recid = random.choices(range(1, 36), k=n)
event_overal = random.choices(range(2), k=n)
event_specific = random.choices(range(2), k=n)
event_recid = random.choices(range(2), k=n)
group = random.choices(groups, k=n)
print(group)
# Compute statistics
stats_overal = compute_survival_stats(time_observed, event_overal, group)
print(stats_overal)
stats_specific = compute_survival_stats(time_observed, event_specific, group)
stats_recid = compute_survival_stats(time_to_recid, event_recid, group)
app = Dash()
# Requires Dash 2.17.0 or later
app.layout = html.Div(children=[
html.Button('Reload', id='reload_btn'),
html.Div(id='reload_div')
])
@callback(
Output('reload_div', 'children'),
Input('reload_btn', "n_clicks"),
# prevent_initial_call=True,
)
def update_plots(n_clicks):
dkm_overal = dkm.DashKaplanMeier(
id='km-overal',
time=time_observed,
event=event_overal,
group=group,
showCIs=True,
colors=['blue', 'green', 'red'],
showStatistics=True,
logrankP=stats_overal["logrank_p"],
coxP=stats_overal["cox_p"],
hazardRatio=stats_overal["hazard_ratio"],
layout={'title': 'Общая выживаемость',
'xaxis': {'title': 'Time'},
'yaxis': {'title': 'Survival Probability'}},
title="Общая выживаемость",
config={'responsive': False},
style={'display': 'inline-block', 'height': 500, 'width': 500}
)
dkm_specific = dkm.DashKaplanMeier(
id='km-specific',
time=time_observed,
event=event_specific,
group=group,
showCIs=True,
colors=['blue', 'green', 'red'],
showStatistics=True,
logrankP=stats_specific["logrank_p"],
coxP=stats_specific["cox_p"],
hazardRatio=stats_specific["hazard_ratio"],
layout={'title': 'Специфическая выживаемость',
'xaxis': {'title': 'Time'},
'yaxis': {'title': 'Survival Probability'}},
title="Специфическая выживаемость",
config={'responsive': False},
style={'display': 'inline-block', 'height': 500, 'width': 500}
)
dkm_recid = dkm.DashKaplanMeier(
id='km-recid',
time=time_to_recid,
event=event_recid,
group=group,
showCIs=True,
colors=['blue', 'green', 'red'],
showStatistics=True,
logrankP=stats_recid["logrank_p"],
coxP=stats_recid["cox_p"],
hazardRatio=stats_recid["hazard_ratio"],
layout={'title': 'Безрецидивная выживаемость',
'xaxis': {'title': {'text': 'Time'}},
'yaxis': {'title': {'text': 'Survival Probability'}}},
title="Безрецидивная выживаемость",
config={'responsive': False},
style={'display': 'inline-block', 'height': 500, 'width': 500}
)
reload_div = html.Div(
[
html.Div([
html.Div([
html.H1('Общая выживаемость'),
dcc.Loading([dkm_overal]),
], id='overal'),
html.Div([
html.H1('Специфическая выживаемость'),
dcc.Loading([dkm_specific]),
], id='specific'),
html.Div([
html.H1('Безрецидивная выживаемость'),
dcc.Loading([dkm_recid]),
], id='recid'),
])
]
)
return reload_div
if __name__ == '__main__':
app.run(debug=True)