Reputation: 1
I am taking the IBM Data science certification course on Coursera and I am trying on creating a dashboard with Plotly and Dash using Google Colab. The assignment includes two dropdowns (Select report type and Year) and based on the users selection, it will have an output of 4 graphs. The second dropdown (for selecting the year) should be enabled only if when the user selects “Yearly Statistics report” from the previous dropdown, else it should be disabled only. - The second dropdown (for selecting the year) should be enabled only if when the user selects “Yearly Statistics report” from the previous dropdown, else it should be disabled only. Callback functions to return to the layout and display graphs. First callback will be required to take the input for the report type and set the years dropdown to be enabled to take the year input for “Years Statistics Report”, else this dropdown be put on disabled. In the second callback it should fetch the value of report type and year and return the required graphs appropriately for each type of report. However, I don't see any graphs when I try to select an option in dropdown menu and I get a Callback error updating output-container.children. I will really appreciate any help. Here's my code:
import dash
from dash import dcc
from dash import html
from dash.dependencies import Input, Output
import pandas as pd
import plotly.graph_objs as go
import plotly.express as px
# Load the data using pandas
data = pd.read_csv('https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-DV0101EN-SkillsNetwork/Data%20Files/historical_automobile_sales.csv')
# Initialize the Dash app
app = dash.Dash(__name__)
# Set the title of the dashboard
#app.title = "Automobile Statistics Dashboard"
dropdown_options = [
{'label': 'Yearly Statistics Report', 'value': 'Yearly Statistics'},
{'label': 'Recession Period Statistics', 'value': 'Recession Period Statistics'}
]
# List of years
year_list = [i for i in range(1980, 2024, 1)]
# Initialize the Dash app
app = dash.Dash(__name__)
# Set the title of the dashboard
#app.title = "Automobile Statistics Dashboard"
dropdown_options = [
{'label': 'Yearly Statistics Report', 'value': 'Yearly Statistics'},
{'label': 'Recession Period Statistics', 'value': 'Recession Period Statistics'}
]
# List of years
year_list = [i for i in range(1980, 2024, 1)]
# Create the layout of the app
app.layout = html.Div(children=[
#TASK 2.1 Add title to the dashboard
html.H1("Automobile Sales Statistics Dashboard", style={'textAlign': 'center', 'color': '#503D36', 'font-size': 24}),
html.Div ([
#TASK 2.2: Add two dropdown menus
html.Label("Select Statistics:"),
dcc.Dropdown (id='dropdown-statistics',
options=[
{'label': 'Yearly Statistics', 'value': 'Yearly Statistics'},
{'label': 'Recession Period Statistics', 'value': 'Recession Period Statistics'}],
value='Select Statistics',
placeholder='Select a report type',
style={'textAlign': 'center', 'width': '80%', 'padding': 3, 'font-size': 20})
]),
html.Div(
dcc.Dropdown(id='select-year',
options=[{'label': i, 'value': i} for i in year_list],
value='Select Year',
style={'textAlign': 'center', 'width': '80%', 'padding': 3, 'font-size': 20}
)),
html.Div([
#TASK 2.3: Add a division for output display
html.Div(id='output-container',
className='chart-grid',
style={'display': 'flex'})])
])
#TASK 2.4: Creating Callbacks
# Define the callback function to update the input container based on the selected statistics
@app.callback(
Output(component_id='select-year', component_property='disabled'),
Input(component_id='dropdown-statistics', component_property='value'))
def update_input_container(selected_statistics):
if selected_statistics =='Yearly Statistics':
return False
else:
return True
#Callback for plotting
# Define the callback function to update the input container based on the selected statistics
@app.callback(
Output(component_id='output-container', component_property='children'),
[Input(component_id='dropdown-statistics',component_property='value'),
Input(component_id='select-year', component_property='value')])
def update_output_container(selected_statistics, input_year):
if selected_statistics == 'Recession Period Statistics':
#TASK 2.5: Create and display graphs for Recession Report Statistics
#Plot 1 Automobile sales fluctuate over Recession Period (year wise)
recession_data = data[data['Recession'] == 1]
yearly_data = data[data['Year'] == input_year]
yearly_rec = recession_data.groupby('Year')['Automobile_Sales'].mean().reset_index()
R_chart1 = dcc.Graph(
figure=px.line(yearly_rec,
x='Year',
y='Sales Volume',
title="Average Automobile Sales fluctuation over Recession Period"))
#Plot 2 Calculate the average number of vehicles sold by vehicle type
average_sales = data.groupby('Vehicle_Type')['Automobile_Sales'].mean().reset_index()
R_chart2 = dcc.Graph(
figure=px.bar(average_sales,
x='Vehicle Type',
y='Sales Volume',
title='Average Number of Vehicles Sold by Vehicle Type'))
# Plot 3 Pie chart for total expenditure share by vehicle type during recession
exp_rec= recession_data.groupby('Vehicle_Type')['Advertising_Expenditure'].sum().reset_index()
R_chart3 = dcc.Graph(figure=px.pie(exp_rec,
values='Advertising_Expenditure',
names='Vehicle_Type',
title="Total Expendiure Share by Vehicle Type during Recessions"))
# Plot 4 bar chart for the effect of unemployment rate on vehicle type and sales
un_sales = data.groupby(['Vehicle_Type', 'unemployment_rate'])['Automobile_Sales'].mean().reset_index()
R_chart4 = dcc.Graph(
figure=px.bar(un_sales,
x='Unemployment Rate',
y='Sales Volume',
title='The Effect of Unemployment Rate on Vehicle Type and Sales'))
return[html.Div(className='chart-grid', children=[html.Div(children=R_chart1),html.Div(children=R_chart2)], style={'display': 'flex'}),
html.Div(className='chart-grid', children=[html.Div(children=R_chart3),html.Div(children=R_chart4)], style={'display': 'flex'})]
elif (input_year and selected_statistics =='Yearly Statistics'):
yearly_data = data[data['Year'] == input_year]
#plot 1 Yearly Automobile sales using line chart for the whole period.
yas= data.groupby('Year')['Automobile_Sales'].sum().reset_index()
Y_chart1 = dcc.Graph(
figure=px.line(yas,
x='Year',
y='Sales Volume',
title='Yearly Automobile Sales'))
# Plot 2 Total Monthly Automobile sales using line chart.
mas=data.groupby('Month')['Automobile_Sales'].sum().reset_index()
Y_chart2 = dcc.Graph(
figure=px.line(mas,
x='Month',
y='Sales Volume',
title='Total Monthly Automobile Sales'))
# Plot bar chart for average number of vehicles sold during the given year
avr_vdata=yearly_data.groupby('Year')['Automobile_Sales'].mean().reset_index()
Y_chart3 = dcc.Graph(
figure=px.bar(avr_vdata,
x='Year',
y='Sales Volume',
title='Average Vehicles Sold by Vehicle Type in the year {}'.format(input_year)))
# Total Advertisement Expenditure for each vehicle using pie chart
exp_data=yearly_data.groupby('Vehicle_Type')['Advertising_Expenditure'].sum().reset_index()
Y_chart4 = dcc.Graph(
figure=px.pie(exp_data,
values='Advertising_Expenditure',
names='Vehicle_Type',
title="Total Advertisement Expenditure for Each Vehicle Type"))
#TASK 2.6: Returning the graphs for displaying Yearly data
return [html.Div(className='chart-grid', children=[html.Div(children=Y_chart1),html.Div(children=Y_chart2)], style={'display': 'flex'}),
html.Div(className='chart-grid', children=[html.Div(children=Y_chart3),html.Div(children=Y_chart4)], style={'display': 'flex'})]
else:
return None
# Run the Dash app
if __name__ == '__main__':
app.run_server(debug=True)
I checked all syntax errors and now I can't see any. Maybe I need a fresh eye to look. I checked the data: everything is OK, correctly loaded and formatted. Also I tried to add html.Div and Output. After that I can see empty graphs and a new error: Callback error updating ..chart1.figure...chart2.figure...chart3.figure...chart4.figure..
html.Div(style={'display': 'flex', 'justify-content': 'center'},
children=[html.Div(dcc.Graph(id='chart1'), style={'border': 'ridge', 'padding': '10px', 'backgroundColor': '#00008B'}),
html.Div(dcc.Graph(id='chart2'), style={'border': 'ridge', 'padding': '10px', 'backgroundColor': '#00008B'})]),
html.Div(style={'display': 'flex', 'justify-content': 'center'},
children=[html.Div(dcc.Graph(id='chart3'), style={'border': 'ridge', 'padding': '10px', 'backgroundColor': '#00008B'}),
html.Div(dcc.Graph(id='chart4'), style={'border': 'ridge', 'padding': '10px', 'backgroundColor': '#00008B'})])
...
@app.callback([Output(component_id='chart1', component_property='figure'),
Output(component_id='chart2', component_property='figure'),
Output(component_id='chart3', component_property='figure'),
Output(component_id='chart4', component_property='figure')],
[Input(component_id='dropdown-statistics',component_property='value'),
Input(component_id='select-year', component_property='value')])
...
return [html.Div(className='chart-grid', children=[html.Div(children=R_chart1),html.Div(children=R_chart2)], style={'display': 'flex'}),
html.Div(className='chart-grid', children=[html.Div(children=R_chart3),html.Div(children=R_chart4)], style={'display': 'flex'})]
elif (input_year and selected_statistics =='Yearly Statistics'):
yearly_data = data[data['Year'] == input_year]
...
return [html.Div(className='chart-grid', children=[html.Div(children=Y_chart1),html.Div(children=Y_chart2)], style={'display': 'flex'}),
html.Div(className='chart-grid', children=[html.Div(children=Y_chart3),html.Div(children=Y_chart4)], style={'display': 'flex'})]
Upvotes: 0
Views: 499
Reputation: 1
So, thanks to staff's help, I was able to fix the errors.
Change options to options=dropdown_options:
dcc.Dropdown (id='dropdown-statistics', options=dropdown_options, value='Select Statistics', placeholder='Select a report type', style={'textAlign': 'center', 'width': '80%', 'padding': 3, 'font-size': 20}) ]),
I deleted yearly_data line after recession_data.
There were mismatch in keywords in charts between 'Automobile_Sales' and 'Sales Volume'. I changed all of them.
In 'yas' I changed sum() to mean ():
yas= data.groupby('Year')['Automobile_Sales'].mean().reset_index()
I deleted line with 'mas':
Y_chart2 = dcc.Graph( figure=px.line(yearly_data, x='Month', y='Automobile_Sales', labels={'Month': 'Month', 'Automobile_Sales': 'Automobile Sales'}, title='Total Monthly Automobile Sales'))
I used 'Vehicle_Type' instead of 'Year' in Y_chart3:
avr_vdata=yearly_data.groupby('Vehicle_Type')['Automobile_Sales'].mean().reset_index() Y_chart3 = dcc.Graph( figure=px.bar(avr_vdata, x='Vehicle_Type', y='Automobile_Sales', labels={'Vehicle_Type': 'Vehicle Type', 'Automobile_Sales': 'Automobile Sales'}, title='Average Vehicles Sold by Vehicle Type in the year {}'.format(input_year)))
Upvotes: 0