Search code examples
pythonpandasplotlyplotly-dashdashboard

Choropleth Plotly Graph not appearing on Dash


I have a csv file with various states, and their scores for some particular dates. It is being plotted correctly in the VSCode Notebook but when I try to display it on Dash, the default map is appearing but there's no colour coding. I have tried changing the dataset and even the display options but it's still the same. Anyone else facing this?

I am attaching my entire Dash code below for reference

#importing libraries
import dash
from dash import Dash, dcc, html, Input, Output
import plotly.express as px
import pandas as pd


app = Dash(__name__)

#-- Import and clean data (importing csv into pandas)
df = pd.read_csv("C:\Data Science\Jupyter_Workspace\Twitter_Sentiment\Data\JSONLs\\final_df.csv")
#print(df[:5]) #printing out a sample to verify if it's correct or not

# Importing the GeoJSON File
import geojson
with open("C:\Data Science\Jupyter_Workspace\Twitter_Sentiment\Dash Deployment\states_india.geojson") as f:
    india_states = geojson.load(f)


# ------------------------------------------------------------------------------
# App layout
app.layout = html.Div([

    html.H1("Sentiment Timeline for Covid-19 in India 2021-22", style={'text-align': 'center'}),

    dcc.Dropdown(id="selected_date",
                 options=[
                     {"label": "March 20, 2020", "value": 20200320},
                     {"label": "March 25, 2020", "value": 20200325},
                     {"label": "March 27, 2020", "value": 20200327},
                     {"label": "March 30, 2020", "value": 20200330}],
                 multi=False,
                 value=20200320,
                 style={'width': "40%"}
                 ),

    html.Div(id='output_container', children=[]),
    html.Br(),

    dcc.Graph(id='sentiment_map', figure={})
])


# ------------------------------------------------------------------------------
# Connect the Plotly graphs with Dash Components
@app.callback(
    [Output(component_id='output_container', component_property='children'),
     Output(component_id='sentiment_map', component_property='figure')],
    [Input(component_id='selected_date', component_property='value')]
)
def update_graph(date_selected):
    print(date_selected)
    print(type(date_selected))

    container = "The date chosen by user was: {}".format(date_selected)

    dff = df.copy()
    dff = dff[dff["date"] == date_selected]

    # Plotly Express
    fig = px.choropleth_mapbox(
        data_frame = dff, 
        locations = 'state', 
        geojson = india_states,
        range_color=(-1, 1),
        color = 'vader_score', 
        mapbox_style = "carto-positron",
        color_continuous_scale = px.colors.diverging.RdBu, 
        color_continuous_midpoint = 0,
        center = {'lat': 24, 'lon': 78}, 
        zoom = 2.85, 
        labels = {'vader_score': 'Sentiment Score'},
        title = "Sentiment Map"
        )

    return container, fig


# --------------------------------
if __name__ == '__main__':
    app.run_server(debug=True)

Solution

  • data sourcing

    • using publicly available geojson for geometry
    • generating a data frame of sentiment data for dates in dash app
    • NB state column corresponds to ID in geojson
    import requests
    import pandas as pd
    import numpy as np
    import plotly.express as px
    
    # fmt off
    india_states = requests.get("https://raw.githubusercontent.com/Subhash9325/GeoJson-Data-of-Indian-States/master/Indian_States").json()
    df = pd.DataFrame({"name":['Andaman and Nicobar', 'Andhra Pradesh', 'Arunachal Pradesh',
           'Assam', 'Bihar', 'Chandigarh', 'Chhattisgarh',
           'Dadra and Nagar Haveli', 'Daman and Diu', 'Delhi', 'Goa',
           'Gujarat', 'Haryana', 'Himachal Pradesh', 'Jammu and Kashmir',
           'Jharkhand', 'Karnataka', 'Kerala', 'Lakshadweep',
           'Madhya Pradesh', 'Maharashtra', 'Manipur', 'Meghalaya', 'Mizoram',
           'Nagaland', 'Orissa', 'Puducherry', 'Punjab', 'Rajasthan',
           'Sikkim', 'Tamil Nadu', 'Tripura', 'Uttar Pradesh', 'Uttaranchal',
           'West Bengal'],
                      "state":[ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
           18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
           35]})
    df = pd.concat([df.assign(date=d, vader_score=np.random.uniform(-1,1,len(df))) for d in [20200320, 20200325, 20200327, 20200330]])
    # fmt on
    

    dash app

    # importing libraries
    import dash
    from dash import Dash, dcc, html, Input, Output
    import plotly.express as px
    import pandas as pd
    from jupyter_dash import JupyterDash
    
    # app = Dash(__name__)
    app = JupyterDash(__name__)
    
    # ------------------------------------------------------------------------------
    # App layout
    app.layout = html.Div(
        [
            html.H1(
                "Sentiment Timeline for Covid-19 in India 2021-22",
                style={"text-align": "center"},
            ),
            dcc.Dropdown(
                id="selected_date",
                options=[
                    {"label": "March 20, 2020", "value": 20200320},
                    {"label": "March 25, 2020", "value": 20200325},
                    {"label": "March 27, 2020", "value": 20200327},
                    {"label": "March 30, 2020", "value": 20200330},
                ],
                multi=False,
                value=20200320,
                style={"width": "40%"},
            ),
            html.Div(id="output_container", children=[]),
            html.Br(),
            dcc.Graph(id="sentiment_map", figure={}),
        ]
    )
    
    
    # ------------------------------------------------------------------------------
    # Connect the Plotly graphs with Dash Components
    @app.callback(
        [
            Output(component_id="output_container", component_property="children"),
            Output(component_id="sentiment_map", component_property="figure"),
        ],
        [Input(component_id="selected_date", component_property="value")],
    )
    def update_graph(date_selected):
        print(date_selected)
        print(type(date_selected))
    
        container = "The date chosen by user was: {}".format(date_selected)
    
        dff = df.copy()
        dff = dff[dff["date"] == date_selected]
    
        # Plotly Express
        fig = px.choropleth_mapbox(
            data_frame=dff,
            locations="state",
            geojson=india_states,
            featureidkey="properties.ID_1",
            range_color=(-1, 1),
            color="vader_score",
            mapbox_style="carto-positron",
            color_continuous_scale=px.colors.diverging.RdBu,
            color_continuous_midpoint=0,
            center={"lat": 24, "lon": 78},
            zoom=2.85,
            labels={"vader_score": "Sentiment Score"},
            title="Sentiment Map",
        )
    
        return container, fig
    
    
    # --------------------------------
    if __name__ == "__main__":
        #     app.run_server(debug=True)
        app.run_server(mode="inline")