Related
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:
I am trying to place a figure and a table side-by-side but the table always shows below the figure vertically although its horizontally in the correct position. Similar code works for me if both elements are figures. Here is a minimal code example.
fig = make_subplots()
fig.add_trace(go.Scatter(x = [1,2,3], y = [1,2,3]))
df = pd.DataFrame({'col1': [1, 2, 3], 'col2': ['This is a test ', 'This is a test', 'This is a test'], 'col3': [99, 100, 101]})
app = dash.Dash(__name__)
app.layout = html.Div([
html.Div([dcc.Graph(figure = fig)], style = {'width': '49%', 'display': 'inline-block'}),
html.Div([dt.DataTable(
data=df.to_dict('records'),
columns=[{'id': c, 'name': c} for c in df.columns],
style_table = {'height': 200, 'overflowX': 'auto'})], style = {'width': '49%', 'display': 'inline-block'}),
])
if __name__ == '__main__':
app.run_server(debug = True)
Here is an image of what I get:
Try including the figure and table in a flex container, i.e. an html.Div() with style={'display': 'flex'}.
import pandas as pd
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_table as dt
import plotly.graph_objects as go
app = dash.Dash(__name__)
app.layout = html.Div([
# Flex container
html.Div([
# Graph container
html.Div([
dcc.Graph(figure=go.Figure(data=go.Scatter(x=[1, 2, 3], y=[1, 2, 3]), layout=dict(margin=dict(t=0, b=0, l=0, r=0))))
], style={'width': '49%', 'display': 'inline-block'}),
# Table container
html.Div([
dt.DataTable(
data=pd.DataFrame({'col1': [1, 2, 3], 'col2': [99, 100, 101]}).to_dict('records'),
columns=[{'id': c, 'name': c} for c in ['col1', 'col2']],
style_table={'height': 200, 'overflowX': 'auto'}
)
], style={'width': '49%', 'display': 'inline-block'}),
], style={'display': 'flex'}),
])
if __name__ == '__main__':
app.run_server(host='127.0.0.1', debug=True)
Hi I have an excel file that looks like this where there are three diferent servers (A, B, C).
I am trying to build a dash app that has a dropdown menu which will make it possible to select the desired server and display the graph for CPU Usage and Memory Usage for each server.
I have tried to modify the following code from the official Dash website. Data can be found on https://plotly.github.io/datasets/country_indicators.csv
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import pandas as pd
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
df = pd.read_csv('https://plotly.github.io/datasets/country_indicators.csv')
available_indicators = df['Indicator Name'].unique()
app.layout = html.Div([
html.Div([
html.Div([
dcc.Dropdown(
id='xaxis-column',
options=[{'label': i, 'value': i} for i in available_indicators],
value='Fertility rate, total (births per woman)'
),
dcc.RadioItems(
id='xaxis-type',
options=[{'label': i, 'value': i} for i in ['Linear', 'Log']],
value='Linear',
labelStyle={'display': 'inline-block'}
)
],
style={'width': '48%', 'display': 'inline-block'}),
html.Div([
dcc.Dropdown(
id='yaxis-column',
options=[{'label': i, 'value': i} for i in available_indicators],
value='Life expectancy at birth, total (years)'
),
dcc.RadioItems(
id='yaxis-type',
options=[{'label': i, 'value': i} for i in ['Linear', 'Log']],
value='Linear',
labelStyle={'display': 'inline-block'}
)
],style={'width': '48%', 'float': 'right', 'display': 'inline-block'})
]),
dcc.Graph(id='indicator-graphic'),
dcc.Slider(
id='year--slider',
min=df['Year'].min(),
max=df['Year'].max(),
value=df['Year'].max(),
marks={str(year): str(year) for year in df['Year'].unique()},
step=None
)
])
#app.callback(
Output('indicator-graphic', 'figure'),
[Input('xaxis-column', 'value'),
Input('yaxis-column', 'value'),
Input('xaxis-type', 'value'),
Input('yaxis-type', 'value'),
Input('year--slider', 'value')])
def update_graph(xaxis_column_name, yaxis_column_name,
xaxis_type, yaxis_type,
year_value):
dff = df[df['Year'] == year_value]
return {
'data': [dict(
x=dff[dff['Indicator Name'] == xaxis_column_name]['Value'],
y=dff[dff['Indicator Name'] == yaxis_column_name]['Value'],
text=dff[dff['Indicator Name'] == yaxis_column_name]['Country Name'],
mode='markers',
marker={
'size': 15,
'opacity': 0.5,
'line': {'width': 0.5, 'color': 'white'}
}
)],
'layout': dict(
xaxis={
'title': xaxis_column_name,
'type': 'linear' if xaxis_type == 'Linear' else 'log'
},
yaxis={
'title': yaxis_column_name,
'type': 'linear' if yaxis_type == 'Linear' else 'log'
},
margin={'l': 40, 'b': 40, 't': 10, 'r': 0},
hovermode='closest'
)
}
if __name__ == '__main__':
app.run_server(debug=True)
The ouput of this code gives an output similar to mine except that the second drop down menu and the slicer would not be needed
I am struggling to understand how to modify the code to be able to apply to mine. Any help would be welcome. Thank you.
Your callback func will have a single Output and a single Input. The output will be the figure of the graph, and the input will be the value of the dropdown.
In your callback, you can filter the dataframe you build from the Excel file something like this:
df = pandas.read_excel('path/to/my/file.xlsx')
df = df[df['server'].eq(dropdown_value)]
From there just fit the data into the dict that represents the figure much like it's done in the Dash example and return it.
I am wondering if there is a way that you can have a dash table scroll vertically up and down automatically when the scroll bar is available.
This is a simple example (I used the same dataframe 7 times to make it long enough).
import dash
import dash_table
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/solar.csv')
long_data = pd.concat([df,df,df,df,df,df,df])
app = dash.Dash(__name__)
app.layout = dash_table.DataTable(
id='table',
columns=[{"name": i, "id": i} for i in long_data.columns],
data=long_data.to_dict('records'),
)
if __name__ == '__main__':
app.run_server(debug=False)
Is there a way to make what's on this page go vertically up and down?
I'm not sure if this is what you're looking for, but you can make the table scrollable via style_table (reference):
app.layout = dash_table.DataTable(
id='table',
columns=[{"name": i, "id": i} for i in long_data.columns],
data=long_data.to_dict('records'),
style_table={
'overflowY': 'scroll'
}
)
If you're looking to have the table scroll automatically at a given speed, I doubt dash/plotly has in-built functionality to do that.
Have you attempted to use "overflow":"Scroll" or overflowY
Example:
dbc.Col(
html.Div(id='timeline-div',),
width=4,
style={'width': '100%',
'height': '750px',
'overflow': 'scroll',
'padding': '10px 10px 10px 20px'
}
),
Resource: https://community.plotly.com/t/how-to-make-a-data-table-scrollable-with-using-overflowy-but-without-the-double-scroll-bars/27920
Issue Fixed :-
style_header=
{
'fontWeight': 'bold',
'border': 'thin lightgrey solid',
'backgroundColor': 'rgb(100, 100, 100)',
'color': 'white'
},
style_cell={
'fontFamily': 'Open Sans',
'textAlign': 'left',
'width': '150px',
'minWidth': '180px',
'maxWidth': '180px',
'whiteSpace': 'no-wrap',
'overflow': 'hidden',
'textOverflow': 'ellipsis',
'backgroundColor': 'Rgb(230,230,250)'
},
style_data_conditional=[
{
'if': {'row_index': 'odd'},
'backgroundColor': 'rgb(248, 248, 248)'
},
{
'if': {'column_id': 'country'},
'backgroundColor': 'rgb(255, 255, 255)',
'color': 'black',
'fontWeight': 'bold',
'textAlign': 'center'
}
],
fixed_rows={'headers': True, 'data': 0}
You can accomplish this using callbacks and dcc.interval, but it is clunky!
Hello I am working on a dash app, and somehow I am not able to update graphs between different divs callback. This is how the app works:
The user gives a url input on the frontend in a textinput box and button is clicked to run analysis.
The user can select the view mode as well before running the analysis, The view mode depends on the dropdown selector
The url is used to display a video frame and run a python function.
The processed results should be stored in the dcc.store component.
The stored data is then called in to update the graphs.
Below is the callback codes:
#Video Selection
#app.callback(Output("video-display", "url"),
[Input("submit_button", "n_clicks")],
[State('video_url', 'value')])
def select_footage(n_clicks, video_url):
if n_clicks is not None and n_clicks > 0:
url = video_url
return url
# Processing and Storing the results in dcc.store
#app.callback(Output("intermediate-value", "data"),
[Input("submit_button", "n_clicks")],
[State('video_url', 'value')])
def video_processing(n_clicks, value ):
global frame
if n_clicks is not None and n_clicks > 0:
frame = python_func(url)
return frame.to_json(orient='split')
# Callback to change the graph view mode div
#app.callback(Output("div-graph-mode", "children"),
[Input("dropdown-graph-view-mode", "value")])
def update_graph_mode(value):
if value == "graphical":
return [
html.Div(
children=[
html.P(children="Retention Score of Detected Labels",
className='plot-title'),
dcc.Graph(
id="bar-score-graph",
style={'height': '55vh', 'width': '100%'}
),
html.P(children="Audience Retention Behavior",
className='plot-title'),
dcc.Graph(
id="line_chart_retention",
style={'height': '45vh', 'width': '100%'}
)
]
)
]
else:
return []
#app.callback(Output("div-table-mode", "children"),
[Input("dropdown-graph-view-mode", "value")])
def update_table_mode(dropdown_value):
if dropdown_value == "table":
return [
html.Div(
children=[
html.P(children="Retention By Label",
className='plot-title'),
html.Div([
table.DataTable(
id="label_retention",
)],
style={'height': '45vh'}),
html.P(children="Retention by Time Stamp",
className='plot-title'),
html.Div([
table.DataTable(
id="timestamp_retention",
style_table={'maxHeight': '40vh', 'width': '100%', 'overflowY': 'scroll'})],
style={'height': '40vh'}
)
]
)
]
else:
return []
# Updating Graphs
#app.callback(Output("label_retention", "figure"),
[Input("dropdown-graph-view-mode", "value")])
def update_table_bar(value):
global frame
if frame is not None:
print(frame)
print("table")
print(value)
#app.callback(Output("bar-score-graph", "figure"),
[Input("dropdown-graph-view-mode", "value")])
def update_score_bar(value):
global frame
if frame is not None:
print(frame)
print("graph")
print(value)
Now what happens is that if I try to toggle between the two graph view modes, the app does not reflect the graphs and requires to click on the button again to get the results. So, basically I believe the data does not gets lost in the dcc.store component when I toggle with the dropdowns.
How can I make the app behave in a way that my python function runs only once on the submit button, but then I am able to toggle between the view modes to see the graphs.
Thanks a lot in advance!!
P.S. This is just a snippet of codes, as the code is too long, but please let me know if you would want to see the entire code.
UPDATE: I have just realised that when I select the Graph Mode, the app prints the results for Table Mode and when I select the table model, the app prints the results for graph mode. I am not able to figure out as to why this is happening.
I was finally able to resolve my issue as below:
#app.callback(Output("div-table-mode", "children"),
[Input("dropdown-graph-view-mode", "value")])
def update_table_mode(dropdown_value):
if dropdown_value == "tabular":
return [
html.Div(
children=[
html.P(children="Retention By Label",
className='plot-title', style={'margin': '0 0 1em 0'}),
html.Div([
table.DataTable(
id="label_retention",
columns=[{"name": i, "id": i} for i in label_retention.columns],
data=label_retention.to_dict("rows"),
style_table={'maxHeight': '40vh', 'width': '100%', 'overflowY': 'scroll'},
style_cell_conditional=[
{
'if': {'column_id': c},
'textAlign': 'left'
} for c in ['Labels']
],
style_data_conditional=[
{
'if': {'row_index': 'odd'},
'backgroundColor': 'rgb(248, 248, 248)'
}
],
style_header={
'backgroundColor': 'rgb(230, 230, 230)',
'fontWeight': 'bold'
}
)],
style={'height': '40vh'}),
html.P(children="Retention by Time Stamp",
className='plot-title', style={'margin': '1em 0 1em 0'}),
html.Div([
table.DataTable(
id="timestamp_retention",
columns=[{"name": i, "id": i} for i in timeline_retention.columns],
data=timeline_retention.to_dict("rows"),
style_table={'maxHeight': '40vh', 'width': '100%', 'overflowY': 'scroll'},
style_cell={'textAlign': 'left', 'minWidth': '20px', 'width': '20px', 'maxWidth': '50px',
'whiteSpace': 'normal'},
css=[{
'selector': '.dash-cell div.dash-cell-value',
'rule': 'display: inline; white-space: inherit; overflow: inherit; text-overflow: inherit;'
}],
style_data_conditional=[
{
'if': {'row_index': 'odd'},
'backgroundColor': 'rgb(248, 248, 248)'
}
],
style_header={
'backgroundColor': 'rgb(230, 230, 230)',
'fontWeight': 'bold'
}
)],
style={'height': '40vh'}
)
],
style={'backgroundColor': '#F2F2F2'}
)
]
else:
return []
#app.callback(Output("div-graph-mode", "children"),
[Input("dropdown-graph-view-mode", "value")])
def update_graph_mode(value):
if value == "graphical":
return [
html.Div(
children=[
html.P(children="Retention Score of Detected Labels",
className='plot-title', style={'margin': '0 0 1em 0', 'width': '100%'}),
dcc.Graph(
id="bar-score-graph",
figure=go.Figure({
'data': [{'hoverinfo': 'x+text',
'name': 'Detection Scores',
#'text': y_text,
'type': 'bar',
'x': label_retention["Description"],
'marker': {'color': colors},
'y': label_retention["sum"].tolist()}],
'layout': {'showlegend': False,
'autosize': False,
'paper_bgcolor': 'rgb(249,249,249)',
'plot_bgcolor': 'rgb(249,249,249)',
'xaxis': {'automargin': True, 'tickangle': -45},
'yaxis': {'automargin': True, 'range': [minval, maxval], 'title': {'text': 'Score'}}}
}
),
style={'height': '55vh', 'width': '100%'}
),
html.P(children="Audience Retention Behavior",
className='plot-title', style={'margin': '0 0 1em 0', 'width': '100%'}),
dcc.Graph(
id="line_chart_retention",
figure=go.Figure({
'data': [go.Scatter(x=label_retention['Start'], y=label_retention['sum'], mode='lines', name='Audience Retention',
line=dict(color='firebrick', width=4))],
'layout': {
'yaxis': {'title': {'text': 'Audience Retention'}, 'automargin': True},
'xaxis': {'title': {'text': 'Time Segment'}, 'automargin': True},
'paper_bgcolor': 'rgb(249,249,249)',
'plot_bgcolor': 'rgb(249,249,249)',
}
}),
style={'height': '45vh', 'width': '100%'}
)
],
style={'backgroundColor': '#F2F2F2', 'width': '100%'}
)
]
else:
return []