Build your own COVID 19 Tracker with Dash, plotly , python part-2 : add cities info
Published: 2020-07-07 19:48:15

 🤩[full code on github](https://github.com/abderrahmaneMustapha/my-data-science-path/tree/master/projects/covid)🤩

🙄in the previous [post!](https://dev.to/abderrahmanemustapha/build-your-covid-19-tracker-with-dash-plotly-python-part-1-represent-data-in-choropleth-km6) we talked about how to represent our data in a choropleth 

🤠in this post, we talk about how can we add a sidebar which contains the city's data(total cases, recovered, deaths) for each country

## Coding part 💻
now lets get and save the citys  data add this  lines of code to data.py

```python

#covid19Dash/data.py
### get countries data
get_api_data(
        'https://www.trackcorona.live/api/cities', # API link
        'data', #field name
        'cities', #file name
)
         
```

by running **python data.py** our cities.csv file will look like this one below

```csv
,location,country_code,latitude,longitude,confirmed,dead,recovered,updated
0,Winterswijk,nl,51.977038,6.7454136,6,,,2020-05-19 21:01:51.948949+00:00
1,"Marion County, Tennessee",us,35.0928512,-85.64348700000001,33,1.0,,2020-05-19 21:00:19.712447+00:00
2,Juruá,br,-3.5811865,-66.4271499,3,0.0,,2020-05-19 21:02:48.021462+00:00
3,"Franklin County, Alabama",us,34.3967457,-87.6186379,344,4.0,,2020-05-19 21:00:19.712447+00:00
4,Capim Grosso,br,-11.3801768,-40.0068953,12,3.0,,2020-05-19 21:02:40.089219+00:00
5,Catende,br,-8.6679698,-35.7218229,17,6.0,,2020-05-19 21:02:40.738953+00:00
6,"Hale County, Alabama",us,32.7859102,-87.6186379,91,2.0,,2020-05-19 21:00:19.712447+00:00
7,Serra do Ramalho,br,-13.5413338,-43.5774778,3,0.0,,2020-05-19 21:02:58.150643+00:00
8,Cordeirópolis,br,-22.4818598,-47.4593897,29,0.0,,2020-05-19 21:02:41.588760+00:00
9,Lagoa Seca,br,-7.1549934,-35.8537249,10,1.0,,2020-05-19 21:02:48.193946+00:00
10,Ponta Porã,br,-22.523123,-55.7242526,6,0.0,,2020-05-19 21:02:53.805951+00:00
11,Tiaret,dz,35.3673553,1.3220322,148,148.0,9.0,2020-05-19 21:01:46.336022+00:00
12,Serra do Salitre,br,-19.110579,-46.6793595,1,0.0,,2020-05-19 21:02:58.158068+00:00
13,Serra,br,-20.1228954,-40.3054099,1381,82.0,,2020-05-19 21:02:58.164867+00:00
```

👀now let's display this data on a sidebar like this one
![create a COVID 19 tracker by toumi abderrahmane final result ] (https://live.staticflickr.com/65535/50087196953_8625bff1eb_h.jpg)

the first thing that we need to do here is to  create a function which is going to find a list of cities by country  you can put this function on the data.py file so now add this lines of code to the data.py file

```python 
def search_country_csv(data,query):
    data = data.set_index('country_code')
    return data.loc[tuple([query]), :].reset_index()


def country(name="dz"):

    cities_list  = search_country_csv(open_csv('data/cities.csv'), name.lower())
    return cities_list.sort_values(by='confirmed', ascending=False)
```

 we have a list of cities sorted by confirmed cases😁

let's go to the app.py file, create our list  and add the data to it
first you should replace the the app.py code from the last post by this one (the code start with app.layout = html.Div(children=[
     dcc.Graph(......)

```python
# earth graph
app.layout = html.Div(children=[
    html.Div(children=[

        #earth graph
        dcc.Graph(
            id='earth-graph',
            className="col-md-8",
            figure = earth() ,
            config={
        'displayModeBar': False
                }                       
        ),
        #end of earth graph

        #cities for each country
         html.Div(
            
            className="col-md-3 row",
            children=[
                #cities list
            html.H4(children="Algeria Citys", id="citys-title", className="col-12 text-center"),
                html.Ul(children=[
                    html.Li(children=[
                        #add info to the side bar
                        city['location'],
                        #order last
                        html.Div(children=[
                        # data containers
                            html.Div(children=[ 
                                html.P(children="Total",className="small-text"),
                                html.Span(children=city['confirmed'], className="badge badge-warning"),
                            ],  className="ml-1 mr-1 d-flex flex-column align-items-center"),
                            html.Div(children=[
                                html.P(children="Deaths",className="small-text"),
                                html.Span(children=city['dead'], className="badge badge-danger"),
                                ],className="ml-1 mr-1 d-flex flex-column align-items-center"),
                            html.Div(children=[
                                html.P(children="Recovered",className="small-text"), 
                                html.Span(children=city['recovered'], className="badge badge-success")
                            ],className="ml-1 mr-1 d-flex flex-column align-items-center"),
                        #end of data containers                    
                    ], className="d-flex flex-row justify-content-between align-items-center")
                ], className="list-group-item d-flex flex-column justify-content-center align-items-center") for _ , city in country().iterrows()] # the country function get data from csv for a specific country , here we loop over the cities and create a rows of all the citys each row contains the number of confirmed , deaths and recovered cases  and the name of the city of course
                
                ,className="list-group", id="cities-data")
                #end of cities list
            ]
         )
        # end of cities for each country

    ], className="row")  , 
     # end of earth graph  
], className="container-fluid")
```

in order to make things work perfectly, we need to add bootstrap  in the top of app.py file so here is how we can do this

```python 
external_stylesheets = [
    {
        'href': 'https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css',
        'rel': 'stylesheet',
        'integrity': 'key here', # add the key here
        'crossorigin': 'anonymous'
    }
]
```
 and do not forget to import the function in the data.py that we created to extract cities from the CSV file, add these lines of code  in the of app.py file

```python 
from data import earth_data,country_data, country

```

🌎🌏last this that we need to do is to update the sidebar when we click on a specific country on the map, to do that let's add a callback, check [this if you want to know more about flask callbacks] (https://flask.palletsprojects.com/en/1.1.x/patterns/deferredcallbacks/#:~:text=Patterns%20for%20Flask%20%C2%BB-,Deferred%20Request%20Callbacks,is%20no%20response%20object%20yet.)

here is the code that you need to add
```python
################# CALL BACKS °°°°°°°°°°°°°°°°°°°°°°°°°°

#update sidbar onclick

#side bar call back start
@app.callback(
    Output('cities-data', 'children'),
    [Input('earth-graph', 'clickData')])
def display_hover_data(clickData):
    name = clickData['points'][0]['customdata'][0] #get country name
    return  [html.Li(children=[
             #add info to the side bar
              city['location'],
              #order last
              html.Div(children=[

                    # data containers
                    html.Div(children=[ 
                        html.P(children="Total", className="small-text"),
                        html.Span(children=city['confirmed'], className="badge badge-warning"),
                    ],className="ml-1 mr-1 d-flex flex-column align-items-center" ),
                    html.Div(children=[
                        html.P(children="Deaths", className="small-text"),
                        html.Span(children=city['dead'], className="badge badge-danger"),
                        ],className="ml-1 mr-1 d-flex flex-column align-items-center"),
                    html.Div(children=[
                        html.P(children="Recovered", className="small-text"), 
                        html.Span(children=city['recovered'], className="badge badge-success")
                    ],className="ml-1 mr-1 d-flex flex-column align-items-center"),
                    #end of data containers
                   
                ], className="d-flex flex-row justify-content-between align-items-center")
              

            ], className="list-group-item d-flex flex-column justify-content-center align-items-center") for _ , city in country(name).iterrows()]
#side bar call back end

```
finally, this is just a simple application to share what I learned about python dash  framework 

in the end run 
```shell
python app.py 
```
and you will see this
![create a COVID 19 tracker by toumi abderrahmane final result ] (https://live.staticflickr.com/65535/50087196953_8625bff1eb_h.jpg) 



# For further exploration
 im using csv files to store my data if you want something better check [omniscidb](https://www.omnisci.com/platform/omniscidb)

if you have some problems with this you can check the [full code on github](https://github.com/abderrahmaneMustapha/my-data-science-path/tree/master/projects/covid)