Can i have a dropdown, where its value is a csv file, so when i hit that item the pd dataframe chnages to the value of that item

from dash import Dash, dcc, html, Input, Output
import plotly.graph_objects as gp
import pandas as pd

app = Dash(__name__)

fig = gp.Figure()

app.layout = html.Div(
    [
        dcc.Dropdown(
            options=[
                {
                    "label": "2014",
                    "value": "https://github.com/Trevor-Duane/dash/blob/main/2014.json",
                },
                {
                    "label": "2015",
                    "value": "https://github.com/Trevor-Duane/dash/blob/main/2015.csv",
                },
            ],
            value="https://github.com/Trevor-Duane/dash/blob/main/2014.json",
            id="data-select",
        ),
        html.Br(),
        # dash_table.DataTable(id="my-table-promises", page_size=10),
        dcc.Graph(
            id='population-graph',
            figure=fig
            ),
    ]
)

app.clientside_callback(
    """
    async function(value) {
        console.log(value)
    const response = await fetch(value);
    const data = await response.json();
    return data;
    console.log(data)
    }
    """,
    Output("population-graph", "data"),
    Input("data-select", "value"),
)

data = pd.read_csv('change-this-value-through dropdown')
# print(data)

y_age = data['Age']
x_M = data['Male']
x_F = data['Female'] * -1

# Creating instance of the figure
fig = gp.Figure()
  
# Adding Male data to the figure
fig.add_trace(gp.Bar(y= y_age, x = x_M, 
                     name = 'Male', 
                     orientation = 'h'))

# Adding Female data to the figure
fig.add_trace(gp.Bar(y = y_age, x = x_F,
                     name = 'Female', orientation = 'h'))
  
# Updating the layout http://tendasuites.com/gallery/out for our graph
fig.update_layout(title = 'Population Pyramid of Uganda-2015',
                 title_font_size = 22, barmode = 'relative',
                 bargap = 0.0, bargroupgap = 0,
                 xaxis = dict(tickvals = [-600000, -400000, -200000,
                                          0, 200000, 400000, 600000],
                                
                              ticktext = ['6k', '4k', '2k', '0', 
                                          '2k', '4k', '6k'],
                                
                              title = 'Population in Thousands',
                              title_font_size = 14)
                 )
  
fig.show()

if __name__ == "__main__":
    app.run_server(debug=True)
True)

Hello, I had worked with a similar thing before, if you have the CSV file, then yes you can easily do that. For my case, I had my keywords contained in a separate list and created a dropdown.

Code for initial dropdown:

# twitter profiles name
user_names = [
    'AcalaNetwork',
    'ParallelFi',
    'MoonbeamNetwork',
    'BitDotCountry',
    'ShidenNetwork',
    'bifrost_finance',
    'Kiltprotocol',
    'CrustNetwork',
    'EquilibriumDeFi',
    'NodleNetwork',
    'polkadex',
    'centrifuge',
    'integri_t_e_e',
    'hydra_dx',
    'PhalaNetwork',
    'RmrkApp',
    'ComposableFin',
    'Picasso_Network',
    'efinityio',
    'ZeitgeistPM',
    'MangataFinance'
]
# Dropdown selector
user_dropdown = html.Div(
    [
        dcc.Dropdown(
            id='fig_dropdown',
            options=[
                {'label': x, 'value': x} for x in user_names
            ],
            value='AcalaNetwork',
            searchable=True,
            clearable=False,
            style={
                'marginLeft': '20px',
                'marginRight': '80px',
                'align': 'center'
            }
        )
    ]
)

So in the callback I just specified the CSV file path and based on the selected value from the dropdown I read that particular CSV file

Code for dropdown callback:

# Callbacks
@twitter_app.callback(
    [
        Output('date-range', 'min_date_allowed'),
        Output('date-range', 'max_date_allowed'),
        Output('date-range', 'start_date'),
        Output('date-range', 'end_date'),
        Output('local', 'data'),
    ],
    Input('fig_dropdown', 'value')
)
def update_output(value):
    if value:
        filepath = "../data/processed_data/processed_sentiment_"
        currfile = filepath + value + "_tweets.csv"
        df = pd.read_csv(currfile, engine='python')
        df['user_created_at'] =  pd.to_datetime(df['user_created_at'], infer_datetime_format=True)
        df['tweet_created_at'] =  pd.to_datetime(df['tweet_created_at'], infer_datetime_format=True)
        df['date_only'] = df['tweet_created_at'].dt.date

        # creating a copy of df
        return (
            df['date_only'].min(), 
            df['date_only'].max(), 
            df['date_only'].min(), 
            df['date_only'].max(),
            df.to_dict('records')
        )
    else:
        raise dash.exceptions.PreventUpdate

The last code contains a chained callback to plot all the graphs

@twitter_app.callback(
    Output('follower-count', 'children'),
    Output('following-count', 'children'),
    Output('tweet-trend', 'figure'),
    Output('pie-chart', 'figure'),
    Input('date-range', 'start_date'),
    Input('date-range', 'end_date'),
    State('local', 'data')
)
def update_plot(start_date, end_date, data):
    df = pd.DataFrame(data)
    mask = (
        (df.date_only >= start_date)
        & (df.date_only <= end_date)
    )
    # Filtered data as per start_date, end_date 
    filtered_df = df.loc[mask, :]
    sentiment_label(filtered_df)
    
    # returing the plots
    return (
        f"Followers count: {filtered_df['user_followers_count'].to_list()[0]}",
        f"Followings count: {filtered_df['user_tweet_count'].to_list()[0]}",
        tweet_trend_chart(filtered_df),
        pie_chart(filtered_df)
    )

Hope this answers your query

Thanks,
Saurabh

Ooh, thank you very much, let me try to go through it and i will update you, thank you please

1 Like