3

I am trying to create a map showing the progressive lockdown measures globally using a date slider. So far I was able to create the map for a static date but my attempt at the slider doesn't work because it seems to only accept integers or floats instead of a date range (Date_slider = pnw.IntSlider(start=0,end=365,value=0)

Essentially, i want to create the map found here: https://www.bsg.ox.ac.uk/research/research-projects/coronavirus-government-response-tracker

import pandas as pd
import geopandas as gpd
import json
import matplotlib as mpl
import pylab as plt
from bokeh.io import output_file, show, output_notebook, export_png
from bokeh.models import ColumnDataSource, GeoJSONDataSource, LinearColorMapper, ColorBar
from bokeh.plotting import figure
from bokeh.palettes import brewer
import panel as pn
import panel.widgets as pnw
import descartes
output_notebook()
pn.extension()

Read shape file

shapefile = '/Users/sam/Desktop/ne_110m_admin_0_countries/ne_110m_admin_0_countries.shp'
gdf = gpd.read_file(shapefile)[['ADMIN', 'ADM0_A3', 'geometry']]
gdf.columns = ['country', 'country_code', 'geometry']
gdf = gdf.drop(gdf.index[159])

Read data

def get_dataset(name,key=None,Date=None):

df = pd.read_csv(r'/Users/sam/Desktop/Big Data Project/covid-stringency-index-2.csv')
        if Date is not None:
            df = df[df['Date'] == Date]
        #Merge dataframes gdf and df_2016.
        if key is None:
            key = df.columns[2]
        merged = gdf.merge(df, left_on = 'country', right_on = 'Entity', how = 'left')
        merged[key] = merged[key].fillna(0)    
        return merged, key

plot with matplotlib

datasetname='Lockdown Measures'
df,key = get_dataset(datasetname, Date='Jul 10, 2020')
fig, ax = plt.subplots(1, figsize=(14, 8))
df.plot(column=key, cmap='OrRd', linewidth=1.0, ax=ax, edgecolor='Black')
ax.axis('off')
ax.set_title('%s Jul 10, 2020' %datasetname, fontsize=25)
plt.tight_layout()
plt.savefig('test_map.png',dpi=150)

Output: https://i.stack.imgur.com/6GrbF.png

Plot with Bokeh

def get_geodatasource(gdf):    
    """Get getjsondatasource from geopandas object"""
    json_data = json.dumps(json.loads(gdf.to_json()))
    return GeoJSONDataSource(geojson = json_data)


def map_dash():
    """Map dashboard"""
    
    from bokeh.models.widgets import DataTable
    map_pane = pn.pane.Bokeh(width=600)
    data_select = pnw.Select(name='dataset',options=list(df))
    Date_slider = pnw.IntSlider(start=0,end=365,value=0)
    def update_map(event):
        gdf,key = get_dataset(name=data_select.value,Date=Date_slider.value)        
        map_pane.object = bokeh_plot_map(gdf, key)        
        return
    Date_slider.param.watch(update_map,'value')
    Date_slider.param.trigger('value')
    data_select.param.watch(update_map,'value')
    app = pn.Column(pn.Row(data_select,Date_slider),map_pane)
    return app

app = map_dash()
app
Sam
  • 61
  • 4
  • If you want to use `ipywidgets`, check out this answer: https://stackoverflow.com/a/50506926/6256241 – Qaswed Aug 18 '21 at 11:25

1 Answers1

0

You have to use a pn.widgets.DateRangeSlider(...)

https://panel.holoviz.org/reference/widgets/DateRangeSlider.html#widgets-gallery-daterangeslider

nghenzi
  • 26
  • 1
  • 4