I am trying to make a graph with Dash. When I copy the examples in Plotly it works fine, but when I change some variables with my values and run it then all the elements appear except for the graph.
This is the code:
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Graph(id='graph-with-slider'),
dcc.Slider(
id='year-slider',
min=subset_date['Year'].unique().min(),
max=subset_date['Year'].unique().max(),
value=subset_date['Year'].unique().min(),
step=None
)
])
#app.callback(
Output('graph-with-slider', 'figure'),
[Input('year-slider', 'value')])
def update_figure(selected_year):
return {
'data': go.Scatter(x=subset_date.index,
y=subset_date['Value'],
mode='lines'),
'layout': go.Layout(
title='My Title'
)
}
if __name__=='__main__':
app.run_server()
What am I doing wrong?
Here is a simple app layout:
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import pandas as pd
import plotly.graph_objs as go
# Step 1. Launch the application
app = dash.Dash()
# Step 2. Import the dataset
# Scimago Journal & Country Rank
# from www.scimagojr.com
st = {'Date': ['2008-01-01', '2009-01-01', '2010-01-01', '2011-01-01', '2012-01-01', '2013-01-01', '2014-01-01', '2015-01-01', '2016-01-01','2017-01-01', '2018-01-01'],
# 'Turkey': [26526, 30839, 33325, 34926, 36766, 40302, 41400, 44529, 47138, 44584,45582],
'Iran': [20006, 24509, 30013, 39682, 41513, 42252, 44923, 45013, 52538, 56029, 60268]
}
st = pd.DataFrame(st)
# range slider options
st['Date'] = pd.to_datetime(st.Date)
dates = ['2008-01-01', '2009-01-01', '2010-01-01', '2011-01-01', '2012-01-01', '2013-01-01', '2014-01-01', '2015-01-01', '2016-01-01','2017-01-01', '2018-01-01']
# Step 3. Create a plotly figure
trace_1 = go.Scatter(x = st.Date, y = st['Iran'],
name = 'Iran',
line = dict(width = 2,
color = 'rgb(229, 151, 50)'))
layout = go.Layout(title = 'Scimago Journal & Country Rank (Iran)',
hovermode = 'closest')
fig = go.Figure(data = [trace_1], layout = layout)
# Step 4. Create a Dash layout
app.layout = html.Div([
# adding a plot
dcc.Graph(id = 'plot', figure = fig),
# range slider
dcc.RangeSlider(id = 'slider',
marks = {i : dates[i] for i in range(0, 11)},
min = 0,
max = 10,
value = [1, 7])
])
# Step 5. Add callback functions
#app.callback(Output('plot', 'figure'),
[
Input('slider', 'value')])
def update_figure( input2):
# filtering the data
st2 = st[(st.Date > dates[input2[0]]) & (st.Date < dates[input2[1]])]
# updating the plot
trace_1 = go.Scatter(x = st2.Date, y = st2['Iran'],
name = 'Iran',
# mode = 'markers'
line = dict(width = 2,
color = 'rgb(229, 151, 50)'))
fig = go.Figure(data = [trace_1], layout = layout)
return fig
# Step 6. Add the server clause
if __name__ == '__main__':
app.run_server(debug = False)
Related
I created a dash app to render some real time charts using plotly.objs. All the data is being created in the database so it's not like the charts are empty.
The page where the dash app renders the charts is blank. It does not show any errors even in debug mode.The complete code is given below:
import dash
from dash import html,dcc
from dash.dependencies import Output, Input
import plotly
import random
import plotly.graph_objs as go
# from collections import deque
import datetime
from plotly.subplots import make_subplots
from pymongo import MongoClient
# from time import ctime
import time
from math import ceil
from configparser import ConfigParser
from waitress import serve
todays_date = str(datetime.datetime.today().date())
config = ConfigParser()
configfile = 'config.ini'
config.read(configfile)
try:
host = config['server']['host']
port = int(config['server']['port'])
mhost = config['mongo']['host']
mport = int(config['mongo']['port'])
muser = config['mongo']['user']
mpass = config['mongo']['pass']
except Exception as e:
print(f'Error in taking config values: {e}')
app = dash.Dash(__name__)
conn = MongoClient(host=mhost,port=mport,username=muser,password=mpass)
db = conn['GraphData']
collec = db[todays_date]
app = dash.Dash(__name__,title='IV Graphs',update_title='Plotting...')
app.layout = html.Div(
[
html.Div(children=html.Div(id='live-graph'), className='row'),
dcc.Interval(
id = 'graph-update',
interval = 5000,
n_intervals = 0
),
]
)
#app.callback(
Output('live-graph', 'children'),
[ Input('graph-update', 'n_intervals') ]
)
def update_graph_scatter(n):
colLimit = 2
plotData = list(collec.find())#{'$and':[{'title':{'$ne':'AD BN'}},{'title':{'$ne':'AD N'}}]}))
# print(plotData)
titleList = []
reqOrder = ['AD N','AD BN','NIFTY CALL WEEKLY IV', 'BANKNIFTY CALL WEEKLY IV',
'NIFTY PUT WEEKLY IV', 'BANKNIFTY PUT WEEKLY IV',
'NIFTY CALL MONTHLY IV', 'BANKNIFTY CALL MONTHLY IV',
'NIFTY PUT MONTHLY IV', 'BANKNIFTY PUT MONTHLY IV', 'PCR CURRENT N',
'PCR CURRENT BN','PCR NEXT N','PCR NEXT BN']
for titleData in reqOrder:
for dbData in plotData:
if dbData['title'] == titleData:
if titleData == 'AD BN' or titleData == 'AD N':
titleList.append(f"{dbData['title']}: {dbData['ratio']} UP: {dbData['up']} DOWN: {dbData['down']}")
break
else:
titleList.append(dbData['title'] + ": "+ str(round(float(dbData['yaxis'][-1]),2)))
print(titleList)
fig = make_subplots(rows=ceil(len(reqOrder)/colLimit), cols=colLimit,
subplot_titles=tuple(titleList),
)
colNum = 1
rowNum = 1
graphs = []
LAYOUT = {
'plot_bgcolor': 'white',
'paper_bgcolor': 'white'
}
fig['layout'].update(LAYOUT)
for algo in reqOrder:
for dbData in plotData:
if dbData['title'] == algo:
xData = convertTimeStamps(dbData['xaxis'])
yData = convertToFloat(dbData['yaxis'])
if colNum>colLimit:
colNum = 1
rowNum+=1
# print([0 for i in plotData[dbData].keys()])
fig.add_trace(
go.Scatter(mode ="lines",
x=xData, y=yData),
row=rowNum, col=colNum
)
if dbData['title'] == 'AD BN' or dbData['title'] == 'AD N':
# fig.add_hline(y=0)
fig.add_trace(
go.Scatter( mode = 'lines',line = dict(dash = 'longdash'),x=xData,
y=[0 for i in xData]),
row=rowNum, col=colNum
)
fig.add_trace(
go.Scatter( mode = 'lines',line = dict(dash = 'longdash'),x=xData,
y=[0 for i in xData]),
row=rowNum, col=colNum
)
fig.add_trace(
go.Scatter( mode = 'lines',line = dict(dash = 'longdash'),x=xData,
y=[2 for i in xData]),
row=rowNum, col=colNum
)
fig.add_trace(
go.Scatter( mode = 'lines',line = dict(dash = 'longdash'),x=xData,
y=[0.5 for i in xData]),
row=rowNum, col=colNum
)
colNum+=1
# break
fig.update_layout(
autosize = True
)
print(fig)
graphs.append(html.Div(style={
'display': 'flex',
'flex-flow': 'column',
'background-color': 'green',
'height': '200vh',
'width': '100%'
},children = [ dcc.Graph(
id='basic-interactions',
figure=fig,
style={'height': '100%'}
)]))
return graphs
def convertTimeStamps(epochList):
ans = []
for timeStamp in epochList:
ans.append(datetime.datetime.fromtimestamp(timeStamp))
return ans
def convertToFloat(data):
ans = []
for p in data:
ans.append(float(p))
return ans
if __name__ == '__main__':
app.run_server(host=host, port=port,debug = False)
I tried to restart the page and even the system. What is wrong here?
I'm trying to plot certain values using dash as a bar chart but use a separate column to map the colors. Using below, I'm plotting dates as a bar-chart that corresponds to a drop down bar.
Is it possible to keep the dates as the x-axis but use DOW (day of the week) as a discrete color map? I'll attach the current output below. The dates get plotted but there are a few issues.
The string formatting for each date in the dropdown isn't in date time
The color map isn't sequenced to the day of the week
import dash
from dash import dcc
from dash import html
from dash.dependencies import Input, Output
import dash_bootstrap_components as dbc
import plotly.express as px
import plotly.graph_objs as go
import pandas as pd
from datetime import datetime as dt
df = pd.DataFrame({
'Type': ['A','B','B','B','C','C','D','E','E','E','E','F','F','F'],
})
N = 30
df = pd.concat([df] * N, ignore_index=True)
df['TIMESTAMP'] = pd.date_range(start='2022/01/01 07:30', end='2022/01/30 08:30', periods=len(df))
df['TIMESTAMP'] = pd.to_datetime(df['TIMESTAMP'], dayfirst = True).sort_values()
df['DATE'], df['TIME'] = zip(*[(d.date(), d.time()) for d in df['TIMESTAMP']])
df['DATE'] = pd.to_datetime(df['DATE'])
df = df.sort_values(by = 'DATE')
df['DOW'] = df['DATE'].dt.weekday
df = df.sort_values('DOW').reset_index(drop=True)
df['DOW'] = df['DATE'].dt.day_name()
external_stylesheets = [dbc.themes.SPACELAB, dbc.icons.BOOTSTRAP]
app = dash.Dash(__name__, external_stylesheets = external_stylesheets)
filter_box = html.Div(children=[
html.Div(children=[
html.Label('Day of the week:', style={'paddingTop': '2rem'}),
dcc.Dropdown(
id='DATE',
options=[
{'label': x, 'value': x} for x in df['DATE'].unique()
],
value=df['DATE'].unique(),
multi=True
),
], className="four columns",
style={'padding':'2rem', 'margin':'1rem'} )
])
app.layout = dbc.Container([
dbc.Row([
dbc.Col(html.Div(filter_box, className="bg-secondary h-100"), width=2),
dbc.Col([
dbc.Row([
dbc.Col(dcc.Graph(id = 'date-bar-chart'),
),
]),
], width=5),
])
], fluid=True)
#app.callback(
Output('date-bar-chart', 'figure'),
[Input("DATE", "value"),
])
def date_chart(date):
dff = df[df['DATE'].isin(date)]
count = dff['DATE'].value_counts()
data = px.bar(x = count.index,
y = count.values,
#color = dff['DOW'],
)
layout = go.Layout(title = 'Date')
fig = go.Figure(data = data, layout = layout)
return fig
if __name__ == '__main__':
app.run_server(debug=True, port = 8051)
Not sure why do you want to use DATE as Dropdown but I think you should change it to string and then pass it to dcc.Dropdown. Used the previous way to add color_discrete_map I think you can revise your code as below:
import dash
from dash import dcc
from dash import html
from dash.dependencies import Input, Output
import dash_bootstrap_components as dbc
import plotly.express as px
import plotly.graph_objs as go
import pandas as pd
from datetime import datetime as dt
from dash.exceptions import PreventUpdate
df = pd.DataFrame({
'Type': ['A','B','B','B','C','C','D','E','E','E','E','F','F','F'],
})
N = 30
df = pd.concat([df] * N, ignore_index=True)
df['TIMESTAMP'] = pd.date_range(start='2022/01/01 07:30', end='2022/01/30 08:30', periods=len(df))
df['TIMESTAMP'] = pd.to_datetime(df['TIMESTAMP'], dayfirst = True).sort_values()
df['DATE'], df['TIME'] = zip(*[(d.date(), d.time()) for d in df['TIMESTAMP']])
df['DATE'] = pd.to_datetime(df['DATE'],format='%Y-%m-%d')
df = df.sort_values(by = 'DATE')
df['DOW'] = df['DATE'].dt.weekday
df = df.sort_values('DOW').reset_index(drop=True)
df['DOW'] = df['DATE'].dt.day_name()
df['DATE'] = df['DATE'].astype(str)
df['Color'] = df['DOW'].map(dict(zip(df['DOW'].unique(),
px.colors.qualitative.Plotly[:len(df['DOW'].unique())])))
Color = df['Color'].unique()
Category = df['DOW'].unique()
Color = df['Color'].unique()
Category = df['DOW'].unique()
cats = dict(zip(Category,Color))
external_stylesheets = [dbc.themes.SPACELAB, dbc.icons.BOOTSTRAP]
app = dash.Dash(__name__, external_stylesheets = external_stylesheets)
filter_box = html.Div(children=[
html.Div(children=[
html.Label('Day of the week:', style={'paddingTop': '2rem'}),
dcc.Dropdown(
id='DATE',
options=[
{'label': x, 'value': x} for x in df['DATE'].unique()
],
value=df['DATE'].unique(),
multi=True
),
], className="four columns",
style={'padding':'2rem', 'margin':'1rem'} )
])
app.layout = dbc.Container([
dbc.Row([
dbc.Col(html.Div(filter_box, className="bg-secondary h-100"), width=2),
dbc.Col([
dbc.Row([
dbc.Col(dcc.Graph(id = 'date-bar-chart'),
),
]),
], width=5),
])
], fluid=True)
#app.callback(
Output('date-bar-chart', 'figure'),
[Input("DATE", "value"),
])
def date_chart(date):
if date:
dff = df[df['DATE'].isin(date)]
count = dff.groupby(['DATE',"DOW"])['DATE'].count().reset_index(name='counts')
data = px.bar(x = count['DATE'],
y = count['counts'],
color = count['DOW'],
color_discrete_map = cats,
)
layout = go.Layout(title = 'Date')
fig = go.Figure(data = data, layout = layout)
return fig
else:
raise PreventUpdate
if __name__ == '__main__':
app.run_server(debug=False, port = 8051)
I used groupby in callback to return new dataframe and then use it to make graph. Hope this help.
I want to create a parallel category in plotly that have linked brushing as the documentation from plotly.
https://plotly.com/python/parallel-categories-diagram/#parallel-categories-linked-brushing
However, inside, it only show how to do it without plotly-dash.
How to combine go.Pract and dash? Can someone help me with this?
Let myself answer this question, hopefully can save someone's developing time.
There are two key point to take away before jumping to the code:
A dash callback is required to pass the selected index between two graphs. Reference to plotly docs.
go.Parcat dose not support selectedData for the callback, instead, you need to use clickData. This is a bit tricky.
Here is my approach.
import plotly.graph_objects as go
import pandas as pd
import numpy as np
import dash
from dash import dcc
from dash import html
from dash.dependencies import Input, Output
cars_df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/imports-85.csv')
# Build figure as FigureWidget
def get_parcat_fig(selected_index, cars_df): # create function to update fig object
# Build parcats dimensions
categorical_dimensions = ['body-style', 'drive-wheels', 'fuel-type']
dimensions = [dict(values=cars_df[label], label=label) for label in categorical_dimensions]
color = np.zeros(len(cars_df), dtype='uint8')
colorscale = [[0, 'gray'], [1, 'firebrick']]
color[selected_index] = 1
fig = go.FigureWidget(
data=[go.Scatter(x=cars_df.horsepower, y=cars_df['highway-mpg'],
marker={'color': 'gray'}, mode='markers', selected={'marker': {'color': 'firebrick'}},
unselected={'marker': {'opacity': 0.3}}, selectedpoints=selected_index),
go.Parcats(
domain={'y': [0, 0.4]}, dimensions=dimensions,
line={'colorscale': colorscale, 'cmin': 0,
'cmax': 1, 'color': color, 'shape': 'hspline'})
])
fig.update_layout(
height=800, xaxis={'title': 'Horsepower'},
yaxis={'title': 'MPG', 'domain': [0.6, 1]},
dragmode='lasso', hovermode='closest')
return fig
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Graph(
id='parallel_category'
)
])
#app.callback(
Output("parallel_category", "figure"),
Input("parallel_category", "selectedData"),
Input("parallel_category", "clickData")
)
def get_fig_callback(selected_data, click_data):
ctx = dash.callback_context
if (ctx.triggered[0]['prop_id'] == "parallel_category.selectedData") \
or (ctx.triggered[0]['prop_id'] == "parallel_category.clickData"):
selected_data = [point['pointNumber'] for point in ctx.triggered[0]['value']['points']]
else:
selected_data = []
return get_parcat_fig(selected_data, cars_df)
if __name__ == '__main__':
app.run_server(debug=True)
import plotly.graph_objects as go
import pandas as pd
import numpy as np
import dash
from dash import dcc
from dash import html
from dash.dependencies import Input, Output
cars_df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/imports-85.csv')
# Build figure as FigureWidget
def get_parcat_fig(selected_index, cars_df): # create function to update fig object
# Build parcats dimensions
categorical_dimensions = ['body-style', 'drive-wheels', 'fuel-type']
dimensions = [dict(values=cars_df[label], label=label) for label in categorical_dimensions]
color = np.zeros(len(cars_df), dtype='uint8')
colorscale = [[0, 'gray'], [1, 'firebrick']]
color[selected_index] = 1
fig = go.FigureWidget(
data=[go.Scatter(x=cars_df.horsepower, y=cars_df['highway-mpg'],
marker={'color': 'gray'}, mode='markers', selected={'marker': {'color': 'firebrick'}},
unselected={'marker': {'opacity': 0.3}}, selectedpoints=selected_index),
go.Parcats(
domain={'y': [0, 0.4]}, dimensions=dimensions,
line={'colorscale': colorscale, 'cmin': 0,
'cmax': 1, 'color': color, 'shape': 'hspline'})
])
fig.update_layout(
height=800, xaxis={'title': 'Horsepower'},
yaxis={'title': 'MPG', 'domain': [0.6, 1]},
dragmode='lasso', hovermode='closest')
return fig
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Graph(
id='parallel_category'
)
])
#app.callback(
Output("parallel_category", "figure"),
Input("parallel_category", "selectedData"),
Input("parallel_category", "clickData")
)
def get_fig_callback(selected_data, click_data):
ctx = dash.callback_context
if (ctx.triggered[0]['prop_id'] == "parallel_category.selectedData") \
or (ctx.triggered[0]['prop_id'] == "parallel_category.clickData"):
selected_data = [point['pointNumber'] for point in ctx.triggered[0]['value']['points']]
else:
selected_data = []
return get_parcat_fig(selected_data, cars_df)
if __name__ == '__main__':
app.run_server(debug=True)
I am trying not the show the defult dcc.graph when the app runs. I just want to show my graph when app runs
Here is my code,
App layout
dbc.Row([
dbc.Col([
dcc.Graph(id='datatable-upload-graph', responsive=True, style={
'display': 'block'
})
], xs=10, sm=8, md=5, lg=6, xl=5)
])
Callbacks and methods
#app.callback(
Output('datatable-upload-graph', 'figure'),
Input('container-datatable', 'data')
)
def display_gantt(container_datatable):
df = pd.DataFrame(container_datatable)
df['Start Date'] = pd.to_datetime(df['Start Date'], errors='coerce')
df['End Date'] = pd.to_datetime(df['End Date'], errors='coerce')
fig = px.timeline(df, x_start="Start Date", x_end="End Date", y="Project Name", color="Status")
fig.update_yaxes(autorange="reversed")
if container_datatable is None:
return []
else:
return fig
app.config['suppress_callback_exceptions'] = True
if __name__ == '__main__':
app.run_server(debug=True, use_reloader=False)
The essence:
Just make sure to not leave the figure attribute of dcc.Graph unspecified, but rather, for example, like this:
dcc.Graph(id='datatable-upload-graph', figure = blank_figure())
Where blank_figure() is a figure that is not only empty like in the default version, but stripped of all visible features.
The details:
In your app layout you've set up your dcc.Graph as:
dcc.Graph(id='datatable-upload-graph', responsive=True, style={
'display': 'block'
})
What you're missing here is a specification for the figure attribute. Your app will work perfectly fine without it, but you will end up with that empty figure until you've managed to populate the figure object through one of your callbacks. And for longer loading times the empty figure will become visible.
But you can remedy this by specifying a completely blank figure like:
dcc.Graph(id='datatable-upload-graph', figure = blank_figure())
where blank_figure() is this:
def blank_fig():
fig = go.Figure(go.Scatter(x=[], y = []))
fig.update_layout(template = None)
fig.update_xaxes(showgrid = False, showticklabels = False, zeroline=False)
fig.update_yaxes(showgrid = False, showticklabels = False, zeroline=False)
return fig
The code snippet below will let you test this with a random data sample. The app itself is pretty neat as well (in all modesty). Nothing too fancy, but it will let you check out some templates available for your figures through fig.update_layout(template = <template>)
Without including figure = blank_figure() in dcc.Graph, the app will look like this for a brief moment:
And with figure = blank_figure() the app will look like this:
And when the simulations have come to an end the app will look like this:
And now you can easily take a look at how the figure will look like using the different templates, like 'plotly_dark':
Just switch between commenting out these two lines to see the effects in the complete snippet below.
dcc.Graph(id="graph", figure = blank_fig())
# dcc.Graph(id="graph")
Complete code:
import numpy as np
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import dash
import dash_core_components as dcc
import dash_html_components as html
from jupyter_dash import JupyterDash
from dash.dependencies import Input, Output
templates = ['plotly', 'seaborn', 'simple_white', 'ggplot2',
'plotly_white', 'plotly_dark', 'presentation', 'xgridoff',
'ygridoff', 'gridon', 'none']
def blank_fig():
fig = go.Figure(go.Scatter(x=[], y = []))
fig.update_layout(template = None)
fig.update_xaxes(showgrid = False, showticklabels = False, zeroline=False)
fig.update_yaxes(showgrid = False, showticklabels = False, zeroline=False)
return fig
# startfig = blank_fig()
# Dash
app = JupyterDash(__name__)
app.layout = html.Div([
dcc.RadioItems(
id='template_radio',
options=[{'label': k, 'value': k} for k in templates],
value=templates[0]
),
html.Hr(),
html.Div(id='display_templates'),
dcc.Graph(id="graph", figure = blank_fig())
# dcc.Graph(id="graph")
])
# Make a figure with selected template
#app.callback(Output('graph', 'figure'),
[Input('template_radio', 'value')])
def make_graph(template):
np.random.seed(1)
start = 2021
ncols = 50
nrows = 100
cols = [str(i) for i in np.arange(start, start+ncols)]
df = pd.DataFrame(np.random.randint(-2,3, (nrows,ncols)), columns = cols).cumsum()
df.iloc[0] = 0
# figure
fig = px.line(df, x=df.index, y=cols)
fig.update_layout(template = template)
return fig
app.run_server(mode='inline', port = 8070, dev_tools_ui=True,
dev_tools_hot_reload =True, threaded=True)
In this app, I'm trying to display a plot that changes when the value in the dropdown menu is changed. The values are the boroughs in London. The data can be found here. Below is the code for base plot.
import plotly.graph_objects as go
df = pd.read_excel('multi-year-station-entry-and-exit-figures.xls', sheet_name='2017 Entry & Exit', skiprows=6)
df = df.loc[df['Borough'] == 'Islington']
df['Sunday'] = df['Sunday'] + df['Sunday.1']
df['Saturday'] = df['Saturday'] + df['Saturday.1']
df = df[['Borough', 'Station', 'Saturday', 'Sunday']]
df.index = range(len(df))
print(df['Borough'])
fig = go.Figure(data=[
go.Bar(name='Saturday', x=df["Station"], y=df["Saturday"]),
go.Bar(name='Sunday', x=df["Station"], y=df["Sunday"])
])
fig.update_layout(title='Weekend entry and exit figures in 2017',
xaxis_tickfont_size=14,
yaxis=dict(
title='Entry and exit numbers',
titlefont_size=16,
tickfont_size=14,
)
, barmode='group', template='plotly_dark', bargap=0.3, bargroupgap=0.1)
fig.show()
I am able to change the the borough name manually to change the plot. I then created the Dash app with the the dropdown menu. However, I can't figure out how to change the plot when a dropdown option is selected. I created a version using conditional statements where I add an if-elif statement for each borough. I am still unable to change the plot itself however. Basically, I need to incorporate this piece of code df = df.loc[df['Borough'] == 'Islington'] to the Dash app. The Dash app code is shown below.
import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
import pandas as pd
import os
import plotly.io as pio
import plotly.graph_objects as go
import dash_bootstrap_components as dbc
df = pd.read_excel('multi-year-station-entry-and-exit-figures.xls', sheet_name='2017 Entry & Exit', skiprows=6)
df['Sunday'] = df['Sunday'] + df['Sunday.1']
df['Saturday'] = df['Saturday'] + df['Saturday.1']
df = df[['Borough', 'Station', 'Saturday', 'Sunday']]
df.index = range(len(df))
df = df[:-3]
app = dash.Dash()
fig_names = ['Islington', 'Camden']
fig_dropdown = html.Div([
dcc.Dropdown(
id='fig_dropdown',
options=[{'label': x, 'value': x} for x in fig_names],
value=None
)])
fig_plot = html.Div(id='fig_plot')
app.layout = html.Div([fig_dropdown, fig_plot])
#app.callback(
dash.dependencies.Output('fig_plot', 'children'),
[dash.dependencies.Input('fig_dropdown', 'value')])
def update_output(fig_name):
return name_to_figure(fig_name)
def name_to_figure(fig_name):
figure = go.Figure()
if fig_name == 'Islington':
figure = go.Figure(data=[
go.Bar(name='Saturday', x=df["Station"], y=df["Saturday"]),
go.Bar(name='Sunday', x=df["Station"], y=df["Sunday"])
])
elif fig_name == 'Camden':
figure = go.Figure(data=[
go.Bar(name='Saturday', x=df["Station"], y=df["Saturday"]),
go.Bar(name='Sunday', x=df["Station"], y=df["Sunday"])
])
return dcc.Graph(figure=figure)
app.run_server(debug=True, use_reloader=False)
You can create a copy of your data frame containing only the data corresponding to the dropdown selection, and then use this filtered data frame for generating the figure:
import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objects as go
app = dash.Dash()
# load the data
df = pd.read_excel('multi-year-station-entry-and-exit-figures.xls', sheet_name='2017 Entry & Exit', skiprows=6)
df['Sunday'] = df['Sunday'] + df['Sunday.1']
df['Saturday'] = df['Saturday'] + df['Saturday.1']
df = df[['Borough', 'Station', 'Saturday', 'Sunday']]
df.index = range(len(df))
df = df[:-3]
# extract the list of all boroughs
fig_names = df['Borough'].unique().tolist()
# generate the app layout
app.layout = html.Div([
# add a dropdown for selecting the borough
html.Div([
dcc.Dropdown(
id='fig_dropdown',
options=[{'label': x, 'value': x} for x in fig_names],
value=fig_names[0] # use the first borough as the initial selection
)]),
# add a container for the figure
html.Div(id='fig_plot'),
])
# define a callback for updating the figure
# based on the dropdown selection
#app.callback(dash.dependencies.Output('fig_plot', 'children'),
[dash.dependencies.Input('fig_dropdown', 'value')])
def update_output(fig_name):
# extract the data for the selected borough
df_fig = df[df['Borough'] == fig_name]
# plot the data for the selected borough
figure = go.Figure(data=[
go.Bar(name='Saturday', x=df_fig['Station'], y=df_fig['Saturday']),
go.Bar(name='Sunday', x=df_fig['Station'], y=df_fig['Sunday'])
])
return dcc.Graph(figure=figure)
if __name__ == '__main__':
app.run_server(debug=True, host='0.0.0.0', port=1234)