I try to do a dashboard on python dash.
I succeeded the front-end. Indeed, I made appear a "year selector" but I do not understand how to change the graph depending on this year selector. Is anyone has idea or an explaination ? Thanks a lot.
#
# Imports
#
import plotly_express as px
import dash
import dash_core_components as dcc
import dash_html_components as html
#
# Data
if __name__ == '__main__':
app = dash.Dash(__name__) # (3)
fig = px.bar(df2, x="dpe", y="Percentage", color="signature") # (4)
app.layout = html.Div(children=[
html.H1(children=f'Répartition des Leads DEC',
style={'textAlign': 'center', 'color': '#7FDBFF'}), # (5)
html.Label('Year'),
dcc.Dropdown(
id="year-dropdown",
options=[
{'label': '2019', 'value': 2019},
{'label': '2020', 'value': 2020},
{'label': '2021', 'value': 2021},
{'label': '2022', 'value': 2022},
],
value=2022,
),
dcc.Graph(
id='graph1',
figure=fig
), # (6)
html.Div(children=f'''
This a graph which show the repartition of the DPE
'''), # (7)
]
)
#
# RUN APP
#
app.run_server(debug=False, port =4056) # (8)```
You need to use callbacks for the selection of dropdowns to appear. Check out the official documentation
You need to use callback to make you fig be interactive:
Change your dcc.Graph to: dcc.Graph(id='graph1',figure={})
Call back
#app.callback(Output('graph1', 'figure'),[Input('year-dropdown', 'value')]) def update_graph_1(year_dropdown): df2 = df2[(df2['Year'] == year_dropdown)] (# I dont see your dataframe so you will need to change this code) fig = px.bar(df2, x="dpe", y="Percentage", color="signature") return fig
Related
I have created this very simplified example in which I would like to dynamically update the title of a chart as a dropdown label changes.
Here's the code:
data = {'Stock': ['F', 'NFLX', 'AMZN'], 'Number': [10, 15, 7]}
df = pd.DataFrame(data, columns=['Stock', 'Number'])
stock_options = df['Stock']
app = dash.Dash(__name__)
app.layout = html.Div(children=[
html.H1(children='Example Bar Chart'),
html.Div([
dcc.Dropdown(
id='dropdown',
options=[{'label': i, 'value': i} for i in stock_options],
value='F',
),
html.Div(dcc.Graph(id='graph')),
]),
])
#app.callback(
Output(component_id='graph', component_property='figure'),
Input(component_id='dropdown', component_property='value')
)
def update_graph(stock):
msk = df.Stock.isin([stock])
figure = px.bar(df[msk], x='Stock', y='Number', title=f"{stock} open price")
return figure
if __name__ == '__main__':
app.run_server(debug=True)
So, while keeping the same label in dropdown instead of 'F open price' in the title I would like to get 'Facebook open price'... and so on.
I've tried to solve this with map but I couldn't get it working. Can someone point me in the direction on how to resolve this?
Thanks in advance.
As I wrote in my comment, not sure how you want to store the mapping between symbol name and the displayed title in the graph. Here is one solution that works using a dictionary stock_name_mapping that contains the symbols als keys and the displayed names as values:
import pandas as pd
import dash
from dash.dependencies import Input, Output
import dash_html_components as html
import dash_core_components as dcc
import plotly.express as px
data = {'Stock': ['F', 'NFLX', 'AMZN'], 'Number': [10, 15, 7]}
df = pd.DataFrame(data, columns=['Stock', 'Number'])
stock_options = df['Stock']
stock_name_mapping = {'F': 'Facebook',
'NFLX': 'Netflix',
'AMZN': 'Amazon'}
app = dash.Dash(__name__)
app.layout = html.Div(children=[
html.H1(children='Example Bar Chart'),
html.Div([
dcc.Dropdown(
id='dropdown',
options=[{'label': i, 'value': i} for i in stock_options],
value='F',
),
html.Div(dcc.Graph(id='graph')),
]),
])
#app.callback(
Output(component_id='graph', component_property='figure'),
Input(component_id='dropdown', component_property='value')
)
def update_graph(stock):
msk = df.Stock.isin([stock])
stock_name = stock_name_mapping[stock]
figure = px.bar(df[msk], x='Stock', y='Number', title=f"{stock_name} open price")
return figure
if __name__ == '__main__':
app.run_server(debug=True)
I am trying capture mouse hover events using Dash. I capture the position of the mouse using hoverData.
The problem appears when I filter the time series using the range selector or the range slider. The plot correctly reduces to the selected time, but when I hover it with the mouse it resets to the main view (whole main series).
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
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv")
app.layout = html.Div([
dcc.Graph(
id='stock-plot'
),
], className="container")
#app.callback(
Output('stock-plot', 'figure'),
[Input('stock-plot', 'hoverData')])
def drawStockPrice(hoverData):
traces = [go.Scatter(
x=df.Date,
y=df['AAPL.High'],
mode='lines',
opacity=0.7,
connectgaps=True),
]
return {'data': traces,
'layout': go.Layout(colorway=["#5E0DAC", '#FF4F00', '#375CB1', '#FF7400', '#FFF400', '#FF0056'],
height=600,
title=f"Closing prices",
xaxis={"title": "Date",
'rangeselector': {'buttons': list([{'count': 1, 'label': '1M',
'step': 'month',
'stepmode': 'backward'},
{'count': 6, 'label': '6M',
'step': 'month',
'stepmode': 'backward'},
{'step': 'all'}])},
'rangeslider': {'visible': True}, 'type': 'date'},
yaxis={"title": "Price (USD)"},
)}
if __name__ == '__main__':
app.run_server(debug=True)
I am sure there should be a better solution but this is what I got (Dash v1.6.0):
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, State
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv")
layout = go.Layout( colorway=["#5E0DAC", '#FF4F00', '#375CB1', '#FF7400', '#FFF400', '#FF0056'],
height=600,
title=f"Closing prices",
xaxis={"title": "Date",
'rangeselector': {'buttons': list([{'count': 1, 'label': '1M',
'step': 'month',
'stepmode': 'backward'},
{'count': 6, 'label': '6M',
'step': 'month',
'stepmode': 'backward'},
{'step': 'all'}]
),
},
'rangeslider': {'visible': True},
'type': 'date',
},
yaxis={"title": "Price (USD)"},
)
traces = [go.Scatter( x=df.Date,
y=df['AAPL.High'],
mode='lines',
opacity=0.7,
connectgaps=True
)]
app.layout = html.Div([
dcc.Graph(
id='stock-plot',
figure={
'data': traces,
'layout': layout
}
),
], className="container")
#app.callback(
Output('stock-plot', 'figure'),
[Input('stock-plot', 'hoverData'),
Input('stock-plot', 'relayoutData')],
[State('stock-plot', 'figure')]
)
def drawStockPrice(hoverData, selected, figure):
data = figure['data']
layout = figure['layout']
if selected is not None and 'xaxis.range' in selected:
layout['xaxis']['range'] = selected['xaxis.range']
return {'data': data,
'layout': layout
}
if __name__ == '__main__':
app.run_server(debug=True)
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 :-)
I am trying to create some chart using Dash for Python. I have some file with values that I want to read in, save the values in a list and use it to create the graph. My code:
app = dash.Dash()
app.layout = html.Div([
html.H1('Title'),
dcc.Dropdown(
id='my-dropdown',
options=[
{'label': 'Fruit', 'value': 'FRUIT'}
# {'label': 'Tesla', 'value': 'TSLA'},
# {'label': 'Apple', 'value': 'AAPL'}
],
value='TEMPERATUR'
),
dcc.Slider(
min=-5,
max=10,
step=0.5,
value=-3,
),
dcc.Graph(id='my-graph', animate=True),
])
path = "/../example.csv"
with open(path,"r") as file:
reader = csv.reader(file)
dataCopy=[]
for line in file:
dataCopy.append(line)
arrayValues = np.array(dataCopy)
#app.callback(Output('my-graph', 'figure'), [Input('my-dropdown', 'value')])
def update_graph(selected_dropdown_value):
return {
'data': arrayValues }
if __name__ == '__main__':
app.run_server(
)
When I print the arrayValues I get:
['28.687', '29.687', '24.687', '21.687', '25.687', '28.687']
But when I check my graph it has no values shown on it. Do you know what could my mistake be?
UPDATE: I tried with the line
arrayValues = list(map(float, arrayValues))
after getting it as a suggestion in the comments, but still no workable code.
You need to provide some additional information to the Graph data field,
If you want the arrayValues to be plotted in Y axis in a line graph the following code should work.
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
import plotly.graph_objs as go
#hardcoding arrayValues since csv is not provided
arrayValues = ['28.687', '29.687', '24.687', '21.687', '25.687', '28.687']
app = dash.Dash()
app.layout = html.Div([
html.H1('Title'),
dcc.Dropdown(
id='my-dropdown',
options=[
{'label': 'Fruit', 'value': 'FRUIT'}
# {'label': 'Tesla', 'value': 'TSLA'},
# {'label': 'Apple', 'value': 'AAPL'}
],
value='TEMPERATUR'
),
dcc.Slider(
min=-5,
max=10,
step=0.5,
value=-3,
),
dcc.Graph(id='my-graph', animate=True),
])
#path = "/../example.csv"
#with open(path,"r") as file:
# reader = csv.reader(file)
# dataCopy=[]
# for line in file:
# dataCopy.append(line)
# arrayValues = np.array(dataCopy)
#app.callback(Output('my-graph', 'figure'), [Input('my-dropdown', 'value')])
def update_graph(selected_dropdown_value):
return {
'data': [
{'y': arrayValues}
]
}
if __name__ == '__main__':
app.run_server(
)
As Dash uses plotly graph representation, you can refer to the official plotly docs to a variety of such Graphs.
Here is the documentation,
https://plot.ly/python/basic-charts/
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!