Dropdown filters for plotly dashboard - python

I have this dataset below and this code that outputs this chart
Column A
Tools
Category
role
figure
Occurences After
idx
0
PostgreSQL
DatabaseHaveWorkedWith
Developer, front-end
38.044286
4
False
1
MySQL
DatabaseHaveWorkedWith
Developer, front-end
45.883489
2
False
0
MongoDB
DatabaseWantToWorkWith
Developer, front-end
39.018110
1
True
1
PostgreSQL
DatabaseWantToWorkWith
Developer, front-end
48.236203
3
False
0
MySQL
DatabaseHaveWorkedWith
Developer, back-end
26.096002
1
True
1
PostgreSQL
DatabaseHaveWorkedWith
Developer, back-end
33.771734
2
False
0
Redis
DatabaseWantToWorkWith
Developer, back-end
28.495408
1
True
1
PostgreSQL
DatabaseWantToWorkWith
Developer, back-end
40.314136
1
True
from itertools import cycle
import plotly.express as px
fig = go.Figure()
palette = cycle(px.colors.qualitative.Alphabet)
colors = {c:next(palette) for c in daata['Tools'].values}
#Build dropdown Labels
labels = daata['role'].unique()
for i, row in daata.iterrows():
fig.add_trace(
go.Bar(x=[[row['role']],[row["Category"]]],
y=[row["figure"]],
name=row["Tools"],
text=str(round(row["figure"],2))+'%', showlegend=row['idx'],marker_color=colors[row["Tools"]],
legendgroup=row["Tools"]# Fix legend
))
fig.update_layout({
'barmode': 'group',
'xaxis': {
'tickangle': -45,
},
'yaxis': {
'title_text': "figures",
},
})
fig.show()
The above code outputs this chart
However, I want to also add a dropdown filter for the roles (i.e the chart can be filtered by 'Developer, back-end', 'Developer, front-end' and 'All'
I have tried adding button labels, all what have tried kept filtering the chart wrongly

With dash you can add Dropdown and then use value to return fig. Please check below code:
from dash import Dash, dcc, html, dash_table, Input, Output, callback
import plotly.express as px
import dash_bootstrap_components as dbc
import pandas as pd
from itertools import cycle
palette = cycle(px.colors.qualitative.Alphabet)
colors = {c:next(palette) for c in daata['Tools'].values}
#Build dropdown Labels
labels = daata['role'].unique()
app = Dash(__name__, external_stylesheets=[dbc.themes.LUX])
app.layout = html.Div([
dcc.Dropdown(id='dropdown',
options=[
{'label': x, 'value': x} for x in df['role'].unique()],
value=[],
multi=True,
disabled=False,
clearable=True,
searchable=True),
dcc.Graph(id='graph',figure={})
])
#app.callback(Output('graph','figure'),
Input('dropdown','value'))
def update_graph(role):
if role == []:
dff= daata.copy()
fig = go.Figure()
for i, row in dff.iterrows():
fig.add_trace(
go.Bar(x=[[row['role']],[row["Category"]]],
y=[row["figure"]],
name=row["Tools"],
text=str(round(row["figure"],2))+'%', showlegend=row['idx'],marker_color=colors[row["Tools"]],
legendgroup=row["Tools"]# Fix legend
))
fig.update_layout({
'barmode': 'group',
'xaxis': {'tickangle': -45},
'yaxis': {'title_text': "figures",},
})
else:
dff= daata[daata['role'].isin(role)]
fig = go.Figure()
for i, row in dff.iterrows():
fig.add_trace(
go.Bar(x=[[row['role']],[row["Category"]]],
y=[row["figure"]],
name=row["Tools"],
text=str(round(row["figure"],2))+'%', showlegend=row['idx'],marker_color=colors[row["Tools"]],
legendgroup=row["Tools"]# Fix legend
))
fig.update_layout({
'barmode': 'group',
'xaxis': {'tickangle': -45},
'yaxis': {'title_text': "figures",},
})
return fig
if __name__ == "__main__":
app.run_server(debug=False)
Hope this help

Related

How can I use multiple datasets in the dash app to visualize a graph?

I am building a dash app. I want to viz a graph for crypto data (being extracted from APIs). The dash dropdowns contain different crypto ticker symbols & on that basis, I want to showcase different graphs. For e.g, if a user selects ETH in the dropdown, the API will extract the eth market price data & feeds it to the dash app so the user can see the graph, but I am struggling with using multiple datasets with the dropdowns.
So far, I think a dropdown is used to change the property of 1 dataset via changing rows, limits, etc. but unable to choose between multiple datasets.
I am looking for a method to show market price graphs for different cryptocurrencies through the dash app.
########################### Importing Libraries #############################################
import numpy as np
import pandas as pd
from dash import dcc,html,Dash
import plotly.express as px
import warnings
warnings.filterwarnings("ignore")
from api_to_df import open_df,high_df,low_df,close_df,volume_df,mkt_cap_df
###########################################################################################
# Defining app name
app = Dash(__name__)
colors = {
'background': '#231F20',
'text': '#ADD8E6'
}
############### Defining elements for dropdowns ####################################################
ticker_list = ['ETH', 'XRP','BTC','LTC','LRC','DOT','MANA','EGLD','SHIB','SOL','TFUEL','ICP','SAND','MATIC']
type_list = ['Open', 'High','Low','Close','Volume','Mkt cap']
currency_list = ['USD']
############################################################################################################
markdown_text = '''
Koin is a webapp focussed at providing crypto coin data to crypto newbies in a simple yet elegant fashion.
'''
def generate_table(dataframe, max_rows=15):
'''
generate_table function is used to parse pandas dataframes into html tables.
'''
return html.Table([
html.Thead(
html.Tr([html.Th(col) for col in dataframe.columns])
),
html.Tbody([
html.Tr([
html.Td(dataframe.iloc[i][col]) for col in dataframe.columns
]) for i in range(min(len(dataframe), max_rows))
])
])
#fig = px.bar(open_df, x="date", y="open",barmode = "group")
fig = px.line(open_df, x="date", y="open",markers = 1)
# Updating the layout of the figure
fig.update_layout(
plot_bgcolor=colors['background'],
paper_bgcolor=colors['background'],
font_color=colors['text']
)
#fig.update_traces(marker=dict(size=12,
# line=dict(width=2,
# color='Red')),
# selector=dict(mode='markers'))
# Div is used to create divisions in an html block
# children is a subbranch of an Division tree
app.layout = html.Div(style={'backgroundColor': colors['background']}, children=[
# H1 is header 1 i.e Heading of the webapp
html.H1(
children='KOIN',
style={
'textAlign': 'center',
'color': colors['text']
}
),
# style is used to style a particular dash/html component
html.Div(children='Your Koin, Our Data', style={
'textAlign': 'center',
'color': colors['text']
}),
#dcc.markdown is used to add markdown/text info to the frontend
html.Div(children =[dcc.Markdown(children=markdown_text,style={
'textAlign': 'center',
'color': colors['text'] } )]),
#Inside children branch, a dcc dropdown component is created to add filters
html.Div(children =[html.Label('Ticker symbol'),
dcc.Dropdown(ticker_list,style={'color':'#000000'})
],
style={'color': colors['text'],'padding': 10, 'flex': 1}
),
html.Div(children =[html.Label('Data type'),
dcc.Dropdown(type_list,style={'color':'#000000'})
],
style={'color': colors['text'],'padding': 10, 'flex': 1}
),
html.Div(children = [html.Label('Currency'),
dcc.Dropdown(currency_list,style={'color':'#000000'})
],
style={'color': colors['text'],'padding': 10, 'flex': 1}
),
html.H2(children='ETH opening price',style={'color':colors['text']}),
# Adding generate_table function to html division
html.Div(generate_table(open_df),style={'color':colors['text']}),
#dcc.graph is used to parse plotly graphs to html
dcc.Graph(
id='open graph',
figure=fig
)
]
)
if __name__ =="__main__":
app.run_server(debug=True)enter code here
You need a callback that listens to the dropdown and builds a graph for each value selected. It should loop over the selected values, and append a graph to the output value for each one.

Plotly: How to create 'input text' on one page and output (graphs) on second page or tab, by using plotly-dash?

I am creating an app where the first page should take only 'text input' and results(graph) must show on second page or new tab. I do not want text input and charts on the same page. It means, if I write the input as 'USA' in text input bar, the graph of USA should populate on second tab. Following is the working code that I have written so far in dropdown format. In this code, dropdown and graphs are on the same page which I do not want. Please suggest.
import pandas as pd
import plotly.express as px
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Output, Input
import numpy as np
import plotly.io as pio
pio.renderers.default='browser'
app = dash.Dash(__name__)
app.layout = html.Div([
html.H1("Economy Analysis"),
dcc.Dropdown(id='Country_select',
options=[{'label': x, 'value': x}
for x in df.Country.unique()],
value = 'USA'
),
dcc.Graph(id ='my-graph', figure = {})
])
#app.callback(
Output(component_id = 'my-graph', component_property = 'figure'),
Input(component_id = 'Country_select', component_property = 'value'))
def interactive_graphing(value_country):
print(value_country)
s = 100
cat_g = ["developing","develop"]
sample_cat = [cat_g[np.random.randint(0,2)]for i in range(100)]
df = pd.DataFrame({"Country": np.random.choice(["USA", "JPY", "MEX", "IND", "AUS"], s),
"Net": np.random.randint(5, 75, s),
})
df["sample_cat"] = sample_cat
df = df[df.Country==value_country]
df2 = df.pivot_table(index='Country',columns='sample_cat',values='Net',aggfunc='sum')
df2.reset_index(inplace=True)
fig = px.bar(df2, x="Country",
y=['develop','developing'])
return fig
if __name__=='__main__':
app.run_server()
You can use dcc.Tabs and dcc.Tab containers in your layout, and put the input/graph in separate tabs. Dash bootstrap components tabs would also work for this. The ids will still work as inputs/outputs with your callback.
Sample layout:
app.layout = html.Div([
html.H1("Economy Analysis"),
dcc.Tabs([
dcc.Tab(
label='Dropdown',
children=[
dcc.Dropdown(id='Country_select',
options=[{'label': x, 'value': x}
for x in df.Country.unique()],
value = 'USA')
]
),
dcc.Tab(
label='Graph',
children=[
dcc.Graph(id ='my-graph')
]
)
])
])

MongoDb, Dash and Python

I can't get this code to run and I am supposed to get a couple of things to work. First, a data table which I managed to get up and get to work. Then I created a few buttons so I can filter the data table. The buttons don't do anything to change the data table, I need to get them to work. Second, I am trying to get a pie chart to work and have it be interactive with the data table. The pie chart does not render. Lastly, I need a geolocation chart that interacts with the data table as well. The data table has a lateral location and a longitude location. geolocation doesn't render either*
from jupyter_plotly_dash import JupyterDash
import dash
import dash_leaflet as dl
import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
import dash_table as dt
from dash.dependencies import Input, Output, State
import os
import numpy as np
import pandas as pd
from pymongo import MongoClient
from bson.json_util import dumps
# change animal_shelter and AnimalShelter to match your CRUD Python module file name and class name
from AnimalShelter import AnimalShelter
import base64
###########################
# Data Manipulation / Model
###########################
# FIX ME change for your username and password and CRUD Python module name
username = "aacuser"
password = "42213"
shelter = AnimalShelter(username, password)
# class read method must support return of cursor object
df = pd.DataFrame.from_records(shelter.read())
#########################
# Dashboard Layout / View
#########################
app = JupyterDash('SimpleExample')
#FIX ME Add in Grazioso Salvare’s logo
image_filename = 'Grazioso Salvare Logo.png' # replace with your own image
encoded_image = base64.b64encode(open(image_filename, 'rb').read())
#FIX ME Place the HTML image tag in the line below into the app.layout code according to your design
#FIX ME Also remember to include a unique identifier such as your name or date
#html.Img(src='data:image/png;base64,{}'.format(encoded_image.decode()))
app.layout = html.Div([
html.Div(id='hidden-div', style={'display':'none'}),
html.Img(src='data:image/png;base64,{}'.format(encoded_image.decode())),
html.Center(html.B(html.H1('Willi Blanco CS-340 Dashboard'))),
html.Hr(),
html.Div(
#FIXME Add in code for the interactive filtering options. For example, Radio buttons, drop down, checkboxes, etc.
className='row',
style={'display': 'flex'},
children=[
html.Button(id='submit-button-one',n_clicks=0, children= 'Water Rescue'),
html.Button(id='submit-button-two',n_clicks=0, children= 'Mountain or Wilderness Rescue'),
html.Button(id='submit-button-three',n_clicks=0, children='Disaster Rescue or Individual Tracking'),
html.Button(id='submit-button-four', n_clicks=0, children='reset')
]
),
html.Hr(),
dt.DataTable(
id='datatable-id',
columns=[
{"name": i, "id": i, "deletable": False, "selectable": True} for i in df.columns
],
data=df.to_dict('records'),
#FIXME: Set up the features for your interactive data table to make it user-friendly for your client
#If you completed the Module Six Assignment, you can copy in the code you created here
page_size=100,
style_table={'height':'300px','overflowY':'auto','overflowX':'auto'},
style_header={
'backgroundColor':'rgb(230,230,230)',
'fontWeight':'bold'
},
style_data={
'whiteSpace':'normal',
'height':'auto'
},
#tooltips that we are going to use on the table so that we know what information we are looking at
tooltip ={i: {
'value': i,
'use_with': 'both' # both refers to header & data cell
} for i in df.columns},
tooltip_delay=0,
tooltip_duration = None,
#sorting features that we are going to use
sort_action='native',
sort_mode='multi',
filter_action='native',
editable=False,
column_selectable=False,
row_selectable='single',
row_deletable=False,
selected_rows=[],
),
html.Br(),
html.Hr(),
#This sets up the dashboard so that your chart and your geolocation chart are side-by-side
html.Div(className='row',
style={'display' : 'flex'},
children=[
html.Div(
id='graph-id',
className='col s12 m6',
),
html.Div(
id='map-id',
className='col s12 m6',
)
])
])
#############################################
# Interaction Between Components / Controller
#############################################
#app.callback([Output('datatable-id','data')],
[Input('submit-button-one', 'n_clicks'),Input('submit-button-two','n_clicks'),
Input('submit-button-three','n_clicks'),Input('submit-button-four','n_clicks')])
def update_dashboard(bt1,bt2,bt3,bt4):
### FIX ME Add code to filter interactive data table with MongoDB queries
if (int(bt1) >= 1):
df = pd.Dataframe.from_records(shelter.read({'$and': [
{'$or': [ {'breed':'Labrador Retriever Mix'}, {'breed':'Chesapeake Bay Retriever'},
{'breed':'Newfoundland'}]},
{'sex_upon_outcome':'Intact Female'}, {'age_upon_outcome_in_weeks':{'$lte':26, 'gte':156}}]}))
bt2, bt3, bt4 = 0
elif (int(bt2)>= 1):
df = pd.Dataframe.from_records(shelter.read({'$and': [
{'$or': [ {'breed':'German Shepherd'}, {'breed':'Alaskan Malamute'},
{'breed':'Old English Sheepdog'},{'breed':'Siberian Husky'},{'breed':'Rottweiler'}]},
{'sex_upon_outcome':'Intact Male'}, {'age_upon_outcome_in_weeks':{'$lte':26, 'gte':156}}]}))
bt1, bt3 ,bt4 = 0
elif (int(bt3)>=1):
df = pd.Dataframe.from_records(shelter.read({'$and': [
{'$or': [ {'breed':'Doberman Pinscher'}, {'breed':'German Sheperd'},
{'breed':'Golden Retriever'},{'breed':'Bloodhound'},{'breed':'Rottweiler'}]},
{'sex_upon_outcome':'Intact Male'}, {'age_upon_outcome_in_weeks':{'$lte':20, 'gte':300}}]}))
bt1, bt2, bt4 = 0
elif(int(bt4)>=1):
df = pd.Dataframe.from_records(shelter.read())
bt1, bt2, bt3 = 0
columns=[{"name": i, "id": i, "deletable": False, "selectable": True} for i in df.columns]
data=df.to_dict('records')
return data
#app.callback(
Output('datatable-id', 'style_data_conditional'),
[Input('datatable-id', 'selected_columns')]
)
def update_styles(selected_columns):
return [{
'if': { 'column_id': i },
'background_color': '#D2F3FF'
} for i in selected_columns]
#app.callback(
Output('graph-id', "children"),
[Input('datatable-id', "derived_viewport_data")])
def update_graphs(viewData):
###FIX ME ####
# add code for chart of your choice (e.g. pie chart)
df = pd.DataFrame.from_dict(viewData)
return [
dcc.Graph(
figure = px.pie(df, values=values, names=names, title='Percentage of breeds available')
)
]
#app.callback(
Output('map-id', "children"),
[Input('datatable-id', "derived_viewport_data"),
Input('datatable-id',"derived_viewport_selected_rows")])
def update_map(viewData):
#FIXME: Add in the code for your geolocation chart
#If you completed the Module Six Assignment, you can copy in the code you created here.
viewDF = pd.DataFrame.from_dict(viewData)
dff = viewDF.loc[rows]
return [ dl.Map(style={'width': '1000px', 'height': '500px'}, center=[dff.loc[0,'location_lat'],dff.loc[0,'location_long']], zoom=15, children=[
dl.TileLayer(id="base-layer-id"),
# Marker with tool tip and pop up
dl.Marker(position=[dff.loc[0,'location_lat'],dff.loc[0,'location_long']], children=[
dl.Tooltip(dff['breed']),
dl.Popup([
html.H1("Animal Name"),
html.P(dff.loc[0,'name'])
])
])
])]
app
In the #app.callback([Output('datatable-id','data')], add [Input('filter-type', 'value')]).
Also, in the callback before update_map, remove Input('datatable-id',"derived_viewport_selected_rows")]). Try: #app.callback(Output('map-id', "children"), [Input('datatable-id', "derived_viewport_data")])

In dash, how do I use a callback to update a graph when a radio button is selected?

I'm new to dash and I'm having problems finding examples on using data frames within a callback. I created a weekly radio button and a monthly radio button.
When the monthly radio button is selected I would like the graph to pull data from df_monthly where each bar would be a monthly sum of pay. When the weekly radio button is checked I would like to see the graph populate each bar on a weekly basis which would be each row in the data frame since I get paid once a week.
I'm not certain where I'm going wrong but I keep receiving an error stating TypeError: update_fig() takes 0 positional arguments but 1 was given
The graph populates without data like the picture below. Thanks for any help on this matter.
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.plotly as py
import plotly.graph_objs as go
import sqlite3
import pandas as pd
from functools import reduce
import datetime
conn = sqlite3.connect('paychecks.db')
df_ct = pd.read_sql('SELECT * FROM CheckTotal',conn)
df_earn = pd.read_sql('SELECT * FROM Earnings', conn)
df_whold = pd.read_sql('SELECT * FROM Withholdings', conn)
data_frames = [df_ct, df_earn, df_whold]
df_paystub = reduce(lambda left,right: pd.merge(left,right,on=['Date'], how='outer'), data_frames)
def date_extraction(df):
df['Date'] = pd.to_datetime(df['Date'])
df['Year'] = df['Date'].dt.strftime('%Y')
df['Month'] = df['Date'].dt.strftime('%B')
df['Day'] = df['Date'].dt.strftime('%d')
return df
date_extraction(df_paystub)
df_monthly = df_paystub.groupby(['Month']).sum()
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.css.append_css({'external_url': 'https://codepen.io/amyoshino/pen/jzXypZ.css'})
app.layout = html.Div(children=[
html.Div([
html.Div([
dcc.RadioItems(
id='data-view',
options=[
{'label': 'Weekly', 'value': 'Weekly'},
{'label': 'Monthly', 'value': 'Monthly'},
],
value='',
labelStyle={'display': 'inline-block'}
),
], className = 'two columns'),
html.Div([
dcc.Dropdown(
id='year-dropdown',
options=[
{'label': i, 'value': i} for i in df_paystub['Year'].unique()
],
placeholder="Select a year",
),
], className='five columns'),
html.Div([
dcc.Dropdown(
id='month-dropdown',
options=[
{'label': i, 'value': i} for i in df_paystub['Month'].unique()
],
placeholder="Select a month(s)",
multi=True,
),
], className='five columns'),
], className = 'row'),
# HTML ROW CREATED IN DASH
html.Div([
# HTML COLUMN CREATED IN DASH
html.Div([
# PLOTLY BAR GRAPH
dcc.Graph(
id='pay',
)
], className = 'six columns'),
# HTML COLUMN CREATED IN DASH
html.Div([
# PLOTLY LINE GRAPH
dcc.Graph(
id='hours',
figure={
'data': [
go.Scatter(
x = df_earn['Date'],
y = df_earn['RegHours'],
mode = 'lines',
name = 'Regular Hours',
),
go.Scatter(
x = df_earn['Date'],
y = df_earn['OtHours'],
mode = 'lines',
name = 'Overtime Hours',
)
]
}
)
], className='six columns')
], className='row')
], className='ten columns offset-by-one')
#app.callback(dash.dependencies.Output('pay', 'figure'),
[dash.dependencies.Input('data-view', 'value')])
def update_fig():
figure={
'data': [
go.Bar(
x = df_monthly['Month'],
y = df_monthly['CheckTotal'],
name = 'Take Home Pay',
),
go.Bar(
x = df_monthly['Month'],
y = df_monthly['EarnTotal'],
name = 'Earnings',
)
],
'layout': go.Layout(
title = 'Take Home Pay vs. Earnings',
barmode = 'group',
yaxis = dict(title = 'Pay (U.S. Dollars)'),
xaxis = dict(title = 'Date Paid')
)
}
return figure
if __name__ == "__main__":
app.run_server(debug=True)
Hi #prime90 and welcome to Dash.
In glancing at your callback signature it looks like the update_fig() function needs to take the Input you've given it (using dash.dependencies.Input).
The callback is sending this Input what changes in your app you've specified. So it's sending along the value of #data-view you've given to your function update_fig(), which doesn't currently accept any variables, causing the error message.
Just update your function signature and add a couple of boolean variables to rid yourself of the error and get the potential functionality:
def update_fig(dataview_value):
# define your weekly OR monthly dataframe
# you'll need to supply df_weekly similarly to df_monthly
# though DO NOT modify these, see note below!
df = df_weekly if dataview == 'weekly' else df_monthly
dfkey = 'Week' if 'week' in df.columns else 'Month' # eh, worth a shot!
figure={
'data': [
go.Bar(
x = df[dfkey],
y = df['CheckTotal'],
name = 'Take Home Pay',
),
go.Bar(
x = df[dfkey],
y = df['EarnTotal'],
name = 'Earnings',
)
],
'layout': go.Layout(
title = 'Take Home Pay vs. Earnings',
barmode = 'group',
yaxis = dict(title = 'Pay (U.S. Dollars)'),
xaxis = dict(title = 'Date Paid')
)
}
return figure
As was written in the comments above, you'll need to do some type of prior manipulation to create a df_weekly, as you have with your current df_monthly.
In addition, the code snippet I wrote assumes the df column is named "Week" and "Month"--obviously update these as is necessary.
Data manipulation in Dash:
Ensure you read the data sharing docs, as they highlight how data should never be modified out of scope.
I hope this helps :-)

Python Plotly Dash Live Streaming

I’m new to Dash. But I really loved the way it works.
I’m trying to implement a certain live streaming code for stocks which plots the graph by reading it from an external dictionary variable.
I’m sure that I get data continuously. However, this live streaming works perfectly only for 15 minutes and then it stops working. I have to restart the app which I’m not interested in doing so.
Please guide me to solve this.
Also, if I zoom during streaming, it resets my scale because of interval time. How can I fix this ?
Here is my code:
# Import statements
# Importing external python script which is useful in handling the stock data
from StockData import StockData
# dash is an open source graph and dashboard building framework using PlotLy and Flask
import dash
# dcc contains the core graph components
import dash_core_components as dcc
# for javascript and css especially for html components such as id and div
import dash_html_components as html
# for live events
from dash.dependencies import Event
# working with data-frames and datetime series
import pandas as pd
class ChartPlot:
"""
Everything related to plotting chart should be inside this class
Once I initiate the class from the Main.py file, it should start plotting
StockData.data_dictionary has the data
"""
def __init__(self, title="STOCK CHARTS"):
"""
Initialising the dash app
:param title: title of the graph
"""
# Name of the app - stock-tickers
app = dash.Dash('stock-tickers')
# TITLE OF THE APP - THAT WILL BE REFLECTED ON THE TAB
app.title = title
external_css = ["https://fonts.googleapis.com/css?family=Product+Sans:400,400i,700,700i",
"https://cdn.rawgit.com/plotly/dash-app-stylesheets/2cc54b8c03f4126569a3440aae611bbef1d7a5dd/stylesheet.css"]
for css in external_css:
app.css.append_css({"external_url": css,
'modeBarButtonsToRemove': ['sendDataToCloud'], 'displaylogo': False})
def plot_live(self, stock_symbols=StockData.symbol_list, hostname='127.0.0.1', port=5000):
app = self.app
# LAYOUT OF OUR APPLICATION
app.layout = html.Div([
# THE FIRST LINE DESIGN
html.Div([
html.H2('STOCK CHARTS',
# styling can be customised here for title
style={'display': 'inline',
'float': 'left',
'font-size': '2.65em',
'margin-left': '7px',
'font-weight': 'bolder',
'font-family': 'Product Sans',
'color': "rgba(117, 117, 117, 0.95)",
'margin-top': '20px',
'margin-bottom': '0'
})
]),
# DROP DOWN FROM THE AVAILABLE TICKERS
# we are using the stock_symbols from the stock_symbols StockData.symbol_list
dcc.Dropdown(
id='stock-ticker-input',
options=[{'label': s, 'value': s}
for s in stock_symbols],
# DEFAULT VALUE - CAN BE EMPTY AS WELL
value=[stock_symbols[0]],
# INDICATES MULTIPLE SELECTION IS POSSIBLE
multi=True
),
dcc.Checklist(
id='check-list-input',
options=[
{'label': 'High', 'value': 'High'},
{'label': 'Low', 'value': 'Low'}
],
values=['High', 'Low'],
labelStyle={'display': 'inline-block'}
),
# WHERE THE GRAPHS ARE APPEARED
html.Div(id='graphs'),
# INTERVAL FOR UPDATING
dcc.Interval(
id='graph-update',
# 1000 MILLI-SECONDS
interval=1 * 1000
),
], className="container")
# BOOTSTRAP CONTAINER CLASS
# CALL BACK FUNCTION DECORATOR - DEFAULT
#app.callback(
# WHERE THE OUTPUT IS EXPECTED
dash.dependencies.Output('graphs', 'children'),
# WHAT IS THE INPUT FOR THE OUTPUT
[dash.dependencies.Input('stock-ticker-input', 'value'),
dash.dependencies.Input('check-list-input', 'values')],
# ANY SPECIFIC EVENTS - HERE UPDATING BASED ON INTERVAL
events=[Event('graph-update', 'interval')])
def update_graph(symbols, checkers):
"""
This plots the graphs based on the symbol selected
:param symbols: list of available symbols
:return: graphs with high and low values
"""
# Total graphs
graphs = list()
# where all the data is present
data = list()
# running through the selected tickers
for i, symbol in enumerate(symbols):
# StockData has data_dictionary with symbols as keys containing time stamp, high and low data for particular key
data_dictionary = StockData.data_dictionary[symbol]
# Extracting data out of selected data frame
if len(checkers) == 2:
graph_data = [{'x': pd.to_datetime(data_dictionary['Time Stamp']), 'y': data_dictionary['High'],
'type': 'line', 'name': str(symbol) + " High"},
{'x': pd.to_datetime(data_dictionary['Time Stamp']), 'y': data_dictionary['Low'],
'type': 'line', 'name': str(symbol) + ' Low'}]
elif 'High' in checkers:
graph_data = [{'x': pd.to_datetime(data_dictionary['Time Stamp']),
'y': data_dictionary['High'],
'type': 'line', 'name': str(symbol) + " High"}]
elif 'Low' in checkers:
graph_data = [{'x': pd.to_datetime(data_dictionary['Time Stamp']),
'y': data_dictionary['Low'],
'type': 'line', 'name': str(symbol) + ' Low'}]
else:
graph_data = None
# adding to total data
data.extend(graph_data)
# DRAWING THE GRAPH
graphs = [dcc.Graph(
figure={
'data': data,
'layout': {"hovermode": "closest", "spikesnap": "cursor",
"xaxis": {"showspikes": True, "spikemode": "across"},
"yaxis": {"showspikes": True, "spikemode": "across"}}
},
config={'modeBarButtonsToRemove': ['sendDataToCloud'], 'displaylogo': False}
)]
return graphs
app.run_server(debug=True, host=hostname, port=port)
Kindly let me know if I’m doing it wrong anywhere
Based on the Dash documentation snippet
events=[Event('graph-update', 'interval')])
should be:
events=[Event('graph-update', 'n_intervals')])
This seems to be a common hiccup in live streaming dash code... Hope this helps!

Categories

Resources