I have this callback that created different kinds of plots and it worked as expected. All of a sudden this callback returns results from past calls. E.g. I create the histograms but the boxplots are still returned. I am puzzled. There is no caching, and the arguments are passed correctly. Why would this callback return boxplots if boxplot
is not provided in kinds
?
@app.callback(
Output('qc-figures', 'children'),
Input('qc-update', 'n_clicks'),
State('tab', 'value'),
State('qc-groupby', 'value'),
State('qc-graphs', 'value'),
State('qc-select', 'value'),
State('wdir', 'children')
)
def qc_figures(n_clicks, tab, groupby, kinds, options, wdir):
if n_clicks is None:
raise PreventUpdate
print('groupby:', groupby)
print('kinds:', kinds)
print('options:', options)
df = get_complete_results( wdir )
sns.set_context('paper')
by_col = 'Label'
by_col = 'Batch'
quant_col = 'peak_max'
quant_col = 'log(peak_max+1)'
if options is None:
options = []
figures = []
n_total = len(df.peak_label.drop_duplicates())
for i, (peak_label, grp) in tqdm( enumerate(df.groupby('peak_label')), total=n_total ):
if not 'Dense' in options: figures.append(dcc.Markdown(f'#### `{peak_label}`', style={'float': 'center'}))
fsc.set('progress', int(100*(i+1)/n_total))
df = get_complete_results( wdir )
if len(grp) < 1:
continue
if 'hist' in kinds:
fig = sns.displot(data=grp, x=quant_col, height=3, hue=groupby, aspect=1)
plt.title(peak_label)
src = fig_to_src(dpi=150)
figures.append( html.Img(id='hist', src=src, style={'width': '300px'}) )
if 'boxplot' in kinds:
fig = sns.catplot(data=grp, y=quant_col, x=groupby, height=3, kind='box', aspect=1.3, color = "w")
if quant_col in ['peak_max', 'peak_area']:
plt.gca().ticklabel_format(axis='y', style='sci', scilimits=(0,0))
plt.title(peak_label)
src = fig_to_src(dpi=150)
figures.append( html.Img(id='box', src=src, style={'width': '300px'}) )
if not 'Dense' in options: figures.append(dcc.Markdown('---'))
if i == 3: break
return figures
def fig_to_src(dpi=100, format='png'):
out_img = io.BytesIO()
plt.savefig(out_img, format=format, bbox_inches='tight', dpi=dpi)
plt.close('all')
out_img.seek(0) # rewind file
encoded = base64.b64encode(out_img.read()).decode("ascii").replace("\n", "")
return "data:image/png;base64,{}".format(encoded)
When I look at the generated figures, there are as many figures produced as expected. It seems the output container is not cleared correctly.
I think the problem is with multiple images the id=
were not unique. I removed the id argument and now it is working as expected. But why was it working before and switched to the unexpected behavior out of the blue?