Dash, merge two dashboards and add a button - python

I'm pretty new to Dash. I created two dashboards that read from two different dataframes. They work well individually. I would like to merge them in a single one, giving the possibility to the user to access them using a dropdown menu.
I would like to also add a button which (when clicked) returns a function.
Those are the two dashboards:
first one:
import pandas as pd
df1 = pd.read_csv('/df1.csv')
# Import libraries
from dash import Dash, html, dcc, Input, Output
import pandas as pd
import plotly.express as px
# Create the Dash app
app = Dash()
# Set up the app layout
options_dropdown = dcc.Dropdown(options=df1['options'].unique(),
value='wordcount')
app.layout = html.Div(children=[
html.H1(children='offensive/non offensive username activity dashboard'),
options_dropdown,
dcc.Graph(id='df1')
])
# Set up the callback function
#app.callback(
Output(component_id='df1', component_property='figure'),
Input(component_id=options_dropdown, component_property='value')
)
def update_graph(sel_option):
filtered_options = df1[df1['options'] == sel_option]
bar_fig = px.bar(filtered_options,
x= "user", y = "value",
color='user',
color_discrete_map={
'off': '#d62728',
'non_off': 'green'},
title=f' average {sel_option}',
width=500, height=500)
return bar_fig
print(df1)
# Run local server
if __name__ == '__main__':
app.run_server(debug=True)
second one:
import pandas as pd
df2 = pd.read_csv('/df2.csv')
# Import libraries
from dash import Dash, html, dcc, Input, Output
import pandas as pd
import plotly.express as px
# Create the Dash app
app = Dash()
# Set up the app layout
options_dropdown = dcc.Dropdown(options=df2['options'].unique(),
value='wordcount')
app.layout = html.Div(children=[
html.H1(children='offensive/non offensive username activity dashboard'),
options_dropdown,
dcc.Graph(id='df2')
])
# Set up the callback function
#app.callback(
Output(component_id='df2', component_property='figure'),
Input(component_id=options_dropdown, component_property='value')
)
def update_graph(sel_option):
filtered_options = df2[df2['options'] == sel_option]
line_fig = px.line(filtered_options,
x= "Week_Number", y = "value",
color='offensive',
color_discrete_map={
1: '#d62728',
0: 'green'},
title=f' average {sel_option}')
return line_fig
print(df2)
# Run local server
if __name__ == '__main__':
app.run_server(debug=True)
and this is the function I want to implement pressing a button:
sentences = []
df3 = pd.read_csv('/df3.csv')
def cool_function():
ext = rd.randint(0,len(df3.offensive))
return rd.choice(sentences).format(df3.author[ext], "", df3.text[ext])
How do I merge those three elements in a single dashboard?

Related

update DataFrame in Dash after text input

I want to update my DataFrame that feeds my graphs in realtime. In all the tutorials I have found, the DataFrame is created before creating the app layout. I want to take the input from the input component with the username_input ID and use that in the get_dataFrame function to create my initial DataFrame which will create the figure which will be used in the graph component.
app = Dash(__name__)
df = get_dataFrame(username_input)
fig = px.line(df, x='end', y="user",color="class")
app.layout = html.Div(children=[
dcc.Input(
id="username_input",
placeholder="username",
type='text'
),
dcc.Graph(
id='example-graph',
figure=fig
),
])
I don't fully understand how to structure the code so that this is possible. In essence I want a user input first and then after the user input all the dash data updates to reflect the new input. Any ideas?
Move your dataframe and figure creation into your callback, then return a new figure after the user's input comes in. Working example:
from dash import Dash, dcc, html, Input, Output, no_update
import pandas as pd
import plotly.express as px
import numpy as np
app = Dash(__name__)
def get_dataFrame(username_input):
data = np.random.rand(10) * len(username_input)
return pd.DataFrame({"end": [*range(10)], "user": data, "class": ["red"] * 10})
fig = px.line()
app.layout = html.Div(
children=[
dcc.Input(id="username_input", placeholder="username", type="text"),
dcc.Graph(id="example-graph", figure=fig),
]
)
#app.callback(
Output("example-graph", "figure"), Input("username_input", "value"),
)
def func(username_input: str):
if username_input:
df = get_dataFrame(username_input)
fig = px.line(df, x="end", y="user", color="class")
return fig
return no_update
if __name__ == "__main__":
app.run(debug=True)

Plotly Dash callback function doesn't work

I am learning Dash and wanted to create a dashboard with a dropdown connected to a chart, but it doesn't work. The chart does not fill with data somehow and I get an empty dashboard with a dropdown that does nothing.
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.graph_objs as go
import pandas as pd
df = pd.read_csv('gapminderDataFiveYear.csv')
app = dash.Dash()
year_options = []
for year in df['year'].unique():
year_options.append({'label':str(year), 'value':year})
app.layout = html.Div([
dcc.Graph(id='graph'),
dcc.Dropdown(id='year picker', options=year_options,
value=df['year'].min())
])
#app.callback(Output('graph','figure'),
[Input('year-picker', 'value')])
def update_figure(selected_year):
filtered_df = df[df['year']==selected_year]
traces = []
for continent_name in filtered_df['continent'].unique():
df_by_continent = filtered_df[filtered_df['continent']==continent_name]
traces.append(go.Scatter(
x = df_by_continent['gdpPercap'],
y= df_by_continent['lifeExp'],
mode='markers',
opacity=0.7,
marker = {'size':15},
name = continent_name
))
return {'data':traces,'layout':go.Layout(title='My Plot', xaxis={'title':'GDP Per Cap', 'type':'log'},yaxis={'title':'Life Expectancy'})}
if __name__== '__main__':
app.run_server()

How to use a boolean switch to update a graph in Dash?

I'm new in Dash. I'm trying to use a daq.BooleanSwitch() like an input to callback a graph. I can display a message but I have troubles with the graph.
Does anyone have any advice that can help me?
import dash
from dash.dependencies import Input, Output
import dash_daq as daq
import dash_html_components as html
app = dash.Dash(__name__)
app.layout = html.Div([
html.H1("Here we go"),
daq.BooleanSwitch(id='my_pb', on=False,color="red"),
html.Div(id='power-button-result-1'),
dcc.Graph(id="plot")
])
#app.callback(
Output('power-button-result-1', 'children'),
Input('my_pb', 'on')
)
def update_output(on):
x = '{}'.format(on)
if x == "True":
return "Hi Iḿ using DASH"
#app.callback(
Output('plot', 'figure'),
Input('my_pb', 'on')
)
def figura(on):
x = '{}'.format(on)
if x == "True":
# fig1 = Code to do a nice plot
return fig1
if __name__ == "__main__":
app.run_server(port = 1895)
My DASH output look like this:
I took a look at your code, and a couple changes were necessary:
import dash
import dash_daq as daq
from dash import dcc
from dash import html
from dash.dependencies import Input
from dash.dependencies import Output
app = dash.Dash(__name__)
app.layout = html.Div(
[
html.H1("Here we go"),
daq.BooleanSwitch(id="my_pb", on=False, color="red"),
html.Div(id="power-button-result-1"),
]
)
#app.callback(
Output("power-button-result-1", "children"),
Input("my_pb", "on"),
)
def update_output(on):
x = "{}".format(on)
if x == "True":
return [dcc.Graph(id="plot")]
if __name__ == "__main__":
app.run_server(debug=True)
You were super close - I think you only need one callback. Here, you can see the boolean switch now toggles the display (or not) of the dcc.Graph object. Is this what you were looking for?
↓ (toggle the switch)
If you want the graph to already be displayed, and then updated upon toggling, here's a slightly modified expanded version of same code above to do that:
import dash
import dash_daq as daq
from dash import dcc
from dash import html
from dash import no_update
from dash.dependencies import Input
from dash.dependencies import Output
import plotly.express as px
import pandas as pd
app = dash.Dash(__name__)
app.layout = html.Div(
[
html.H1("Here we go"),
daq.BooleanSwitch(id="my_pb", on=False, color="red"),
html.Div(
[dcc.Graph(id="plot")], id="power-button-result-1"
),
]
)
#app.callback(
Output("power-button-result-1", "children"),
Input("my_pb", "on"),
)
def update_output(on):
df = px.data.iris()
if on:
fig = px.scatter(df, x="sepal_width", y="sepal_length")
dcc.Graph(figure=fig)
return [dcc.Graph(figure=fig)]
else:
fig = px.scatter()
return [dcc.Graph(figure=fig)]
if __name__ == "__main__":
app.run_server(debug=True)
There - that's much better, hopefully helpful?

python: dash live plot legends

I recently wrote a dash program
it is refreshing number of records and refreshes or redraws the fig
the problem is when I do filter over 1 or multiple legends it won't show any of the points
but when you hover over invisible points it shows the data of the point
my code:
from threading import Event
import dash
from dash import dcc, Input, Output
from dash import html
from dash.dcc.Interval import Interval
import plotly.express as px
import pandas as pd
import sqlalchemy
app = dash.Dash(__name__)
# assume you have a "long-form" data frame
# see https://plotly.com/python/px-arguments/ for more options
connection = sqlalchemy.create_engine('mysql+pymysql://*:*#localhost:*')
df = pd.read_sql_table('rawdata_clean', connection)
fig = px.scatter(df, x="Size", y="Price", color="Neighbourhood_Per")
index = df.index
app.layout = html.Div(children=[
html.H1(id='Numberofrecords', children= len(index)),
dcc.Interval(id='up-Numberofrecords', interval=3000, n_intervals=0),
html.Div(children='''
Dash: A web application framework for Python.
'''),
dcc.Graph(
id='grph',
animate=True
),
dcc.Interval(id='up-graph', interval=3000, n_intervals=0)
])
#app.callback(Output('grph', 'figure'),
Input('up-graph', 'n_intervals'))
def update_graph (n):
df = pd.read_sql_table('rawdata_clean', connection)
fig = px.scatter(df, x="Size", y="Price", color="Neighbourhood_Per")
return fig
#app.callback(Output('Numberofrecords', 'children'),
Input('up-Numberofrecords', 'n_intervals'))
def up_Numberofrecords (n):
df = pd.read_sql_table('rawdata_clean', connection)
index = df.index
print('up_Numberofrecords')
return len(index)
if __name__ == '__main__':
app.run_server(debug=True, port=9876)
is there any problems with this code?
i'm new to dash and plotly :D
the problem was :
animate=True
IDK what this code does but by deleting it, it get to work

How to get the count from a dataframe from a Dash Callback

I'd like to display the count of certain criteria inside a div in my dash layout based off callback selection from dropdown.
I'm able to get the dropdown for the values in a pandas dataframe column, but I'm having trouble figuring out how to display the total count of the a selected element of the column.
For example, I've written a function in Jupyter notebook to get a count
def getCount(df, selected_org):
totCount = df[df['ORGANIZATIONS'] == selected_org].AGENCY.count()
return count
selected_org = 'REGION 1'
getCount(df, selected_org)
Which displays a value of: 3187
This value is the result of my selected_org variable.
Now, I'd like to do the same thing in my dash layout based off the selection from dropdown. I used much of the code here to get started from Udemy course: Interactive Python Dashboards with Plotly and Dash
I start with my layout:
org_options = []
for org in df['ORG_CODE_LEVEL_2_SHORT'].unique():
org_options.append({'label': str(org), 'value': org})
app.layout = html.Div(children=[
html.Label('Select Org:'),
dcc.Dropdown(id='org-dropdown', options=org_options,
value=df['ORG_CODE_LEVEL_2_SHORT'].min()),
html.P(html.Div(id='container'))
Then my call back:
#app.callback(
Output(component_id='container', component_property='children'),
[Input(component_id='org-dropdown', component_property='value')])
def update_table(selected_org):
filtered_org = df[df['ORG_CODE_LEVEL_2_SHORT'] == selected_org]
return getCount(df, filtered_org)
And a function to generate the count:
def getCount(df, selected_org):
totCount = df[df['ORG_CODE_LEVEL_2_SHORT'] ==
selected_org].AGENCY_INFO_5.count()
return html.H2(totCount)
Which give me the following:
But it isn't giving me the count. Any help is appreciated.
Final complete program:
import os
import glob
import pandas as pd
import numpy as np
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
app = dash.Dash()
# DATA FROM EEPROFILE
path = r'mydata'
extension = 'xlsx'
os.chdir(path)
files = [i for i in glob.glob('*.{}'.format(extension))]
latest_file = max(files, key=os.path.getctime)
df = pd.DataFrame()
eeprofi = pd.read_excel(latest_file, converters={'ORG_CODE_LEVEL_3': str})
df = df.append(eeprofi)
def getCount(df, selected_org):
totCount = df[df['ORG_CODE_LEVEL_2_SHORT'] == selected_org].AGENCY_INFO_5.count()
return html.H2(totCount)
org_options = []
for org in df['ORG_CODE_LEVEL_2_SHORT'].unique():
org_options.append({'label': str(org), 'value': org})
app.layout = html.Div(children=[
html.Label('Select Org:'),
dcc.Dropdown(id='org-dropdown', options=org_options, value=df['ORG_CODE_LEVEL_2_SHORT'].min()),
html.P(html.Div(id='container'))
])
#app.callback(
Output(component_id='container', component_property='children'), [Input(component_id='org-dropdown', component_property='value')])
def update_table(selected_org):
filtered_org = df[df['ORG_CODE_LEVEL_2_SHORT'] == selected_org]
return getCount(df, filtered_org)
if __name__ == '__main__':
app.run_server()
Your input is a children so you should return a list and not html.H2(your_count) like you did ;) so the solution is to replace this function
def getCount(df, selected_org):
totCount = df[df['ORG_CODE_LEVEL_2_SHORT'] == selected_org].AGENCY_INFO_5.count()
return html.H2(totCount)
by this one :
def getCount(df, selected_org):
totCount = df[df['ORG_CODE_LEVEL_2_SHORT'] == selected_org].AGENCY_INFO_5.count()
return [html.H2(totCount)]

Categories

Resources