dspassion
dspassion

Reputation: 39

Dash unable to work (Dropdown and bar chart)

I can't seem to make my dashboard and the main problem is in the dropdown and the plot (bar chart). I have tried most of the stuffs but I still can't figure out what's the problem. Does anyone know what's wrong with my code? The 'population' is basically the 'native country'.

I uploaded my data here: https://github.com/standatagithub/cpsdata/blob/main/cpsdata.csv

This is my code:

import dash
from jupyter_dash import JupyterDash  # pip install 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

df = pd.read_csv(r'C:\Users\mrsta\OneDrive\Desktop\cpsdata.csv')

app = JupyterDash()


#AppLayout
app.layout = html.Div([
    
            html.H1("Population in a city", style={'text-align': 'center'}),
    
            dcc.Dropdown(
                id='population-dropdown',
                options=[{'label': i, 'value': i} for i in list(df.Native_Country_of_Father.unique())],
                placeholder="Please select..",
                searchable=True
            ),
           
            dcc.Slider(
                id='year-slider',
                min=df['Year'].min(),
                max=df['Year'].max(),
                value=df['Year'].min(),
                step=None,
                marks={str(Year): str(Year) for Year in df['Year'].unique()}
            ),
    
            dcc.Graph(id='graph-with-slider'),
            
     
        ],
        style={'width': '48%', 'display': 'inline-block'})


#App CallBack

@app.callback(
    Output('graph-with-slider', 'figure'),
    [Input('year-slider', 'value'),
     Input('population-dropdown','value')])

#Figure Update

def update_figure(selected_year, selected_population):
    filtered_df = df[df['Native_Country_of_Father']] == selected_population
    filtered_df = filtered_df[filtered_df.Year == selected_year]
    traces = []
    for i in df.Native_Country_of_Father.unique():
        df_by_population = filtered_df[filtered_df['selected_population'] == i]
        traces.append(go.Bar(
             x=df_by_population['City'],
             y=df_by_population['Native_Country_of_Father'], #Numberofpopulation
             text=df_by_continent['City'],
             barmode='stack'),
            name=i
        )
                     
    return {
        'data': traces,
        'layout': go.Layout(
            margin={'l': 40, 'b': 40, 't': 10, 'r': 10},
            legend={'x': 0, 'y': 1},
            hovermode='closest'
        )
    }


if __name__ =='__main__':
    app.run_server(mode="external")

This is my dataframe and the error message I received:

enter image description here

enter image description here

Expanded first error message enter image description here

enter image description here

Expanded second error message enter image description here

enter image description here

This is how I think my output should look like. I crop and edited this image from multiple sources.

enter image description here

Upvotes: 1

Views: 2239

Answers (1)

r-beginners
r-beginners

Reputation: 35135

There were multiple factors that prevented it from working. The first is that the dropdowns do not appear. The reason for this is that the data contains nan and needs to be removed. The resulting list that was removed is dd_list. Next, the slider is changed to a range slider. The default value is the minimum and minimum of the year plus 1. Here it is 2005. Next, since we are looping through the graph without drawing the data all at once, we are graphing the filtered data frames. The bar chart type is grouped, but the expected output is not in group mode, so it is disabled. The return of the graph update function is rewritten to fig only. The graph is updated by changing the value on the right side of the slider. selected_yaer1 is the value on the right side. This specification was made to understand the return value of the slider. If the slider is used as it is, the code will need to be modified because the condition is that the slider must be greater than or equal to the start year and less than or equal to the end value. If the year selection is to be a single year, it will need to be changed to a drop-down or radio button.

import dash
from jupyter_dash import JupyterDash
from dash import html
from dash import dcc
import pandas as pd
import plotly.graph_objs as go
from dash.dependencies import Input, Output

url = 'https://raw.githubusercontent.com/standatagithub/cpsdata/main/cpsdata.csv'
df = pd.read_csv(url, sep=',')
dd_list = df.Native_Country_of_Father.dropna().unique()

app = JupyterDash()

#AppLayout
app.layout = html.Div([
    
            html.H1("Population in a city", style={'text-align': 'center'}),
    
            dcc.Dropdown(
                id='population-dropdown',
                options=[{'label': i, 'value': i} for i in dd_list],
                placeholder="Please select..",
                #value='United States',
                searchable=True
            ),
           
            dcc.RangeSlider(
                id='year-slider',
                min=df['Year'].min(),
                max=df['Year'].max(),
                value=[df['Year'].min(),df['Year'].min()+1],
                step=1,
                marks={str(Year): str(Year) for Year in df['Year'].unique()}
            ),
    
            dcc.Graph(id='graph-with-slider'),
            
     
        ],
        style={'width': '100%', 'display': 'inline-block'})


#App CallBack
@app.callback(
    Output('graph-with-slider', 'figure'),
    [Input('year-slider', 'value'),
     Input('population-dropdown','value')])

#Figure Update
def update_figure(selected_year, selected_population):
    print(selected_year, selected_population)
    filtered_df = df[df['Native_Country_of_Father'] == selected_population]
    filtered_df = filtered_df[filtered_df.Year == selected_year[1]]
    filtered_df = filtered_df.groupby('City').count().reset_index()
    print(filtered_df.head())
    traces = []
    #for i in dd_list:
    #    df_by_population = filtered_df[filtered_df['Native_Country_of_Father'] == i]
        #traces.append(
            #name=i
    fig = go.Figure(go.Bar(
        x=filtered_df['City'],
        y=filtered_df['Native_Country_of_Father'], #Numberofpopulation
        text=filtered_df['City'],
        #barmode='stack'
    ))
    fig.update_layout(
        margin={'l': 40, 'b': 40, 't': 10, 'r': 10},
        legend={'x': 0, 'y': 1},
        hovermode='closest'
    )  
                     
    return fig

if __name__ =='__main__':
    app.run_server(debug=True, mode="inline")

enter image description here

Upvotes: 2

Related Questions