I had unknowingly added in the answer section of the following thread as I was trying to use that example to complete my usecase:
Plotly: How to display graph after clicking a button?
I am looking for a very similar solution and I tried suggestion 2 (from the above thread), because I want to display images depending upon user's choice of clicking button. I have image_1
, image_2
, image_3
and image_4
under one directory. I have tried so far like below:
import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objs as go
from dash.dependencies import Input, Output
import numpy as np
from plotly.subplots import make_subplots
import plotly.express as px
pd.options.plotting.backend = "plotly"
from datetime import datetime
palette = px.colors.qualitative.Plotly
# sample data
df = pd.DataFrame({'Prices': [1, 10, 7, 5, np.nan, np.nan, np.nan],
'Predicted_prices': [np.nan, np.nan, np.nan, 5, 8, 6, 9]})
# app setup
app = dash.Dash()
# controls
controls = dcc.Card(
[dcc.FormGroup(
[
dcc.Label("Options"),
dcc.RadioItems(id="display_figure",
options=[{'label': 'None', 'value': 'Nope'},
{'label': 'Figure 1', 'value': 'Figure1'},
{'label': 'Figure 2', 'value': 'Figure2'},
{'label': 'Figure 3', 'value': 'Figure3'}
],
value='Nope',
labelStyle={'display': 'inline-block', 'width': '10em', 'line-height': '0.5em'}
)
],
),
dcc.FormGroup(
[dcc.Label(""), ]
),
],
body=True,
style={'font-size': 'large'})
app.layout = dcc.Container(
[
html.H1("Button for predictions"),
html.Hr(),
dcc.Row([
dcc.Col([controls], xs=4),
dcc.Col([
dcc.Row([
dcc.Col(dcc.Graph(id="predictions")),
])
]),
]),
html.Br(),
dcc.Row([
]),
],
fluid=True,
)
@app.callback(
Output("predictions", "figure"),
[Input("display_figure", "value"),
],
)
def make_graph(display_figure):
# main trace
y = 'Prices'
y2 = 'Predicted_prices'
# print(display_figure)
if 'Nope' in display_figure:
fig = go.Figure()
fig.update_layout(plot_bgcolor='rgba(0,0,0,0)', paper_bgcolor='rgba(0,0,0,0)',
yaxis=dict(showgrid=False, zeroline=False, tickfont=dict(color='rgba(0,0,0,0)')),
xaxis=dict(showgrid=False, zeroline=False, tickfont=dict(color='rgba(0,0,0,0)')))
return fig
if 'Figure1' in display_figure:
fig = go.Figure(go.Scatter(name=y, x=df.index, y=df[y], mode='lines'))
fig.add_traces(go.Scatter(name=y, x=df.index, y=df[y2], mode='lines'))
fig.update_layout(template='plotly_dark')
# prediction trace
if 'Figure2' in display_figure:
fig = go.Figure((go.Scatter(name=y, x=df.index, y=df[y], mode='lines')))
fig.add_traces(go.Scatter(name=y, x=df.index, y=df[y2], mode='lines'))
fig.update_layout(template='seaborn')
if 'Figure3' in display_figure:
fig = go.Figure((go.Scatter(name=y, x=df.index, y=df[y], mode='lines')))
fig.add_traces(go.Scatter(name=y, x=df.index, y=df[y2], mode='lines'))
fig.update_layout(template='plotly_white')
# Aesthetics
fig.update_layout(margin={'t': 30, 'b': 0, 'r': 0, 'l': 0, 'pad': 0})
fig.update_layout(hovermode='x')
fig.update_layout(showlegend=True, legend=dict(x=1, y=0.85))
fig.update_layout(uirevision='constant')
fig.update_layout(title="Prices and predictions")
return (fig)
app.run_server(debug=True)
but I got the following error and couldn't proceed further.
line 24, in <module>
controls = dcc.Card(
AttributeError: module 'dash_core_components' has no attribute 'Card'
The problem is that the different components used in your code are defined in different libraries (dash_core_components
, dash_html_components
and
dash_bootstrap_components
), while you are trying to get all the components from the same library (dash_core_components
). For instance, dcc.Card
should be replaced with dbc.Card
where dbc
stands for dash_bootstrap_components
, see the code below.
import pandas as pd
import numpy as np
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output
import plotly.graph_objs as go
# sample data
df = pd.DataFrame({
'Prices': [1, 10, 7, 5, np.nan, np.nan, np.nan],
'Predicted_prices': [np.nan, np.nan, np.nan, 5, 8, 6, 9]
})
# app setup
app = dash.Dash()
# controls
controls = dbc.Card([
dbc.FormGroup([
html.Label('Options'),
dcc.RadioItems(
id='display_figure',
options=[
{'label': 'None', 'value': 'None'},
{'label': 'Figure 1', 'value': 'Figure1'},
{'label': 'Figure 2', 'value': 'Figure2'},
{'label': 'Figure 3', 'value': 'Figure3'}
],
value='None',
labelStyle={
'display': 'inline-block',
'width': '10em',
'line-height': '0.5em'
}
)
]),
],
body=True,
style={'font-size': 'large'}
)
app.layout = dbc.Container([
html.H1('Button for predictions'),
html.Hr(),
dbc.Row([
dbc.Col([controls], xs=4),
dbc.Col([
dbc.Row([
dbc.Col(dcc.Graph(id='predictions')),
])
]),
]),
],
fluid=True,
)
@app.callback(
Output('predictions', 'figure'),
[Input('display_figure', 'value')],
)
def make_graph(display_figure):
y = 'Prices'
y2 = 'Predicted_prices'
if 'Figure1' in display_figure:
fig = go.Figure(go.Scatter(name=y, x=df.index, y=df[y], mode='lines'))
fig.add_trace(go.Scatter(name=y, x=df.index, y=df[y2], mode='lines'))
fig.update_layout(template='plotly_dark')
fig.update_layout(title='Prices and predictions')
elif 'Figure2' in display_figure:
fig = go.Figure((go.Scatter(name=y, x=df.index, y=df[y], mode='lines')))
fig.add_trace(go.Scatter(name=y, x=df.index, y=df[y2], mode='lines'))
fig.update_layout(template='seaborn')
fig.update_layout(title='Prices and predictions')
elif 'Figure3' in display_figure:
fig = go.Figure((go.Scatter(name=y, x=df.index, y=df[y], mode='lines')))
fig.add_trace(go.Scatter(name=y, x=df.index, y=df[y2], mode='lines'))
fig.update_layout(template='plotly_white')
fig.update_layout(title='Prices and predictions')
else:
fig = go.Figure()
fig.update_layout(
plot_bgcolor='rgba(0,0,0,0)',
paper_bgcolor='rgba(0,0,0,0)',
yaxis=dict(showgrid=False, zeroline=False, tickfont=dict(color='rgba(0,0,0,0)')),
xaxis=dict(showgrid=False, zeroline=False, tickfont=dict(color='rgba(0,0,0,0)'))
)
fig.update_layout(margin={'t': 30, 'b': 0, 'r': 0, 'l': 0, 'pad': 0})
fig.update_layout(hovermode='x')
fig.update_layout(showlegend=True, legend=dict(x=1, y=0.85))
fig.update_layout(uirevision='constant')
return fig
if __name__ == '__main__':
app.run_server(host='127.0.0.1', debug=True)
Once you have fixed this issue, you can update the app to display the static PNG files instead of the interactive graphs as shown below. Note that the dcc.Graph
component has been replaced by the html.Img
component, and that the figure
property has been replaced by the src
property.
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output
# app setup
app = dash.Dash()
# controls
controls = dbc.Card([
dbc.FormGroup([
html.Label('Options'),
dcc.RadioItems(
id='display_figure',
options=[
{'label': 'None', 'value': 'None'},
{'label': 'Figure 1', 'value': 'Figure1'},
{'label': 'Figure 2', 'value': 'Figure2'},
{'label': 'Figure 3', 'value': 'Figure3'}
],
value='None',
labelStyle={
'display': 'inline-block',
'width': '10em',
'line-height': '0.5em'
}
)
]),
],
body=True,
style={'font-size': 'large'}
)
app.layout = dbc.Container([
html.H1('Button for predictions'),
html.Hr(),
dbc.Row([
dbc.Col([controls], xs=4),
dbc.Col([
dbc.Row([
dbc.Col(html.Img(id='predictions')),
])
]),
]),
],
fluid=True,
)
@app.callback(
Output('predictions', 'src'),
[Input('display_figure', 'value')],
)
def make_graph(display_figure):
if 'Figure1' in display_figure:
return app.get_asset_url('image_1.png')
elif 'Figure2' in display_figure:
return app.get_asset_url('image_2.png')
elif 'Figure3' in display_figure:
return app.get_asset_url('image_3.png')
else:
return None
if __name__ == '__main__':
app.run_server(host='127.0.0.1', debug=True)
Note also that the PNG files will need to be saved in the assets
folder, as shown below: