I'm trying to insert an interactive bar-chart using values in a df. Using below, I've got the unique values from Type
displayed as RadioItems
. I'm aiming to link these to a bar chart within the dbc.Container. The first 5 rows of the df are displayed below. I'm hoping to group each unique value of Type
as a total count to be displayed as a bar chart.
Ideally, I'd like to be able to add/remove as many unique values to bar chart through the RadioItems.
Eventually, I'd like to add a date slide where I can select
Type time DATE TIME
0 A 2022-01-01 07:30:00 2022-01-01 07:30:00
1 B 2022-01-01 23:01:00 2022-01-01 23:01:00
2 A 2022-01-01 21:28:00 2022-01-01 21:28:00
3 E 2022-01-01 18:21:00 2022-01-01 18:21:00
4 E 2022-01-01 16:48:00 2022-01-01 16:48:00
current code:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import plotly.express as px
import plotly.graph_objs as go
import dash
from dash import dcc
from dash import html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output
df = pd.DataFrame({
'Type': ['A','B','B','C','D','D','E','E','F']
})
N = 50
df = pd.concat([df] * N, ignore_index=True)
df['time'] = pd.date_range(start='2022/01/01 07:30', end='2022/01/30 08:30', periods=len(df))
df['time'] = pd.to_datetime(df['time'], dayfirst = True).sort_values()
df['time'] = df['time'].dt.floor('1min')
df['DATE'], df['TIME'] = zip(*[(d.date(), d.time()) for d in df['time']])
df['DATE'] = pd.to_datetime(df['DATE'])
df = df.sort_values(by = 'DATE')
date_count = df.groupby(['DATE']).size().reset_index(name = 'Count').sort_values('Count', ascending = False)
date_count["DOW"] = date_count["DATE"].dt.weekday
date_count = date_count.sort_values("DOW").reset_index(drop=True)
date_count["DOW"] = date_count["DATE"].dt.day_name()
external_stylesheets = [dbc.themes.SPACELAB, dbc.icons.BOOTSTRAP]
app = dash.Dash(__name__, external_stylesheets = external_stylesheets)
radio_items = html.Div([
html.P("Type"),
dcc.RadioItems(
id='Type',
value='Type',
options=[{'value': x, 'label': x}
for x in ['A', 'B', 'C', 'D', 'E', 'F']],
),
])
vess_date_barfig = px.bar(data_frame = date_count,
x = 'DATE',
y = 'Count',
color = 'DOW',
opacity = 0.5,
title = 'Total Daily Count of Type'
)
app.layout = dbc.Container([
dbc.Row([
dbc.Col(html.Div(radio_items, className="bg-secondary h-100"), width=2),
dbc.Col([
dbc.Row([
dbc.Col(),
]),
dbc.Row([
dbc.Col(dcc.Graph(figure = vess_date_barfig), style={
"padding-bottom": "10px",
}),
]),
dbc.Row([
dbc.Col(dcc.Graph(id = 'bar-chart')),
]),
], width=5),
dbc.Col([
dbc.Row([
dbc.Col(),
]),
dbc.Row([
# insert bar chart
dbc.Col(dcc.Graph()),
], className="h-100"),
], width=5),
])
], fluid=True)
@app.callback(
[Output('bar-chart', 'figure')],
[Input("Type", "value")])
def generate_chart(value):
bar_data = df[df['Type'] == value]
count = bar_data['Type'].value_counts()
data = go.Bar(x = count.index, y = count.values)
layout = go.Layout(title = 'title')
fig = go.Figure(data = data, layout = layout)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
I'm currently getting this error:
Traceback (most recent call last):
File "/Users/venv/lib/python3.9/site-packages/flask/app.py", line 1820, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/venv/lib/python3.9/site-packages/flask/app.py", line 1796, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
File "/Users/venv/lib/python3.9/site-packages/dash/dash.py", line 1274, in dispatch
ctx.run(
File "/Users/venv/lib/python3.9/site-packages/dash/_callback.py", line 455, in add_context
flat_output_values = flatten_grouping(output_value, output)
File "/Users/venv/lib/python3.9/site-packages/dash/_grouping.py", line 35, in flatten_grouping
validate_grouping(grouping, schema)
File "/Users/venv/lib/python3.9/site-packages/dash/_grouping.py", line 210, in validate_grouping
SchemaTypeValidationError.check(grouping, full_schema, path, (tuple, list))
File "/Users/venv/lib/python3.9/site-packages/dash/_grouping.py", line 162, in check
raise SchemaTypeValidationError(value, full_schema, path, expected_type)
dash._grouping.SchemaTypeValidationError: Schema: [<Output `bar-chart.figure`>]
Path: ()
Expected type: (<class 'tuple'>, <class 'list'>)
Received value of type <class 'plotly.graph_objs._figure.Figure'>:
Figure({
'data': [{'type': 'bar', 'x': array([], dtype=object), 'y': array([], dtype=int64)}],
'layout': {'template': '...', 'title': {'text': 'title'}}
})
Your Output
in the @app.callback
decorator shouldn't be inside a list. If you change it to the following:
@app.callback(
Output('bar-chart', 'figure'),
[Input("Type", "value")])
def generate_chart(value):
bar_data = df[df['Type'] == value]
count = bar_data['Type'].value_counts()
data = go.Bar(x = count.index, y = count.values)
layout = go.Layout(title = 'title')
fig = go.Figure(data = data, layout = layout)
return fig
Then your app runs and responds correctly to radio item selection, as shown below.