Commit 2d56bf86 authored by ViktoriaO1's avatar ViktoriaO1

Update demo/map_img.png, demo/movie_comp.mov, README.md files

Deleted examples_analyticsClub/data/processed/.gitkeep, examples_analyticsClub/data/raw/.gitkeep, examples_analyticsClub/data/README.md, examples_analyticsClub/misc/.gitkeep, examples_analyticsClub/notebooks/Max_Muster/models_german/.ipynb_checkpoints/FastText-checkpoint.ipynb, examples_analyticsClub/notebooks/Max_Muster/models_german/.ipynb_checkpoints/Naive_Bayes-checkpoint.ipynb, examples_analyticsClub/notebooks/Max_Muster/models_german/Naive_Bayes.ipynb, examples_analyticsClub/notebooks/Templates/.ipynb_checkpoints/Template - Bayesian Optimization-checkpoint.ipynb, examples_analyticsClub/notebooks/Templates/.ipynb_checkpoints/Template - cross_validation-checkpoint.ipynb, examples_analyticsClub/notebooks/Templates/Template - Bayesian Optimization.ipynb, examples_analyticsClub/notebooks/Templates/Template - cross_validation.ipynb, examples_analyticsClub/notebooks/.gitkeep, examples_analyticsClub/reports/figures/.gitkeep, examples_analyticsClub/reports/.gitkeep, examples_analyticsClub/results/models/.gitkeep, examples_analyticsClub/results/outputs/.gitkeep, examples_analyticsClub/results/.gitkeep, examples_analyticsClub/scores/SVC/figures/SVC-clf__degree-2018-11-06_10-56.pdf, examples_analyticsClub/scores/SVC/figures/SVC-clf__degree-2018-11-06_15-21.pdf, examples_analyticsClub/scores/SVC/figures/SVC-clf__gamma-2018-11-06_10-56.pdf, examples_analyticsClub/scores/SVC/figures/SVC-clf__gamma-2018-11-06_15-21.pdf, examples_analyticsClub/scores/SVC/SVC.csv, examples_analyticsClub/scores/.gitkeep, examples_analyticsClub/src/utils/__pycache__/__init__.cpython-35.pyc, examples_analyticsClub/src/utils/__pycache__/__init__.cpython-36.pyc, examples_analyticsClub/src/utils/__pycache__/evaluation.cpython-36.pyc, examples_analyticsClub/src/utils/__pycache__/exploration.cpython-35.pyc, examples_analyticsClub/src/utils/__pycache__/exploration.cpython-36.pyc, examples_analyticsClub/src/utils/__init__.py, examples_analyticsClub/src/utils/evaluation.py, examples_analyticsClub/src/utils/exploration.py, examples_analyticsClub/src/__init__.py, examples_analyticsClub/src/main.py, examples_analyticsClub/environment.yml, nigeria_app/data/PiN_nigeria2018.xlsx, nigeria_app/data/choices.csv, nigeria_app/data/hh_data.csv, nigeria_app/data/ind_member_data.csv, nigeria_app/data/ind_waterloop_data.csv, nigeria_app/data/pin.csv, nigeria_app/data/readme.csv, nigeria_app/data/survey.csv, nigeria_app/deprecated_code_junk/PiN_calc.py, nigeria_app/deprecated_code_junk/basic_map.py, nigeria_app/funplotlib/plot.py, nigeria_app/scripts/PiN_calc.py, nigeria_app/scripts/__init__.py, nigeria_app/scripts/basic_map.py, nigeria_app/scripts/correlations.py, nigeria_app/scripts/draw_map.py, nigeria_app/scripts/file_locations.yml, nigeria_app/scripts/nigeria_maps.py, nigeria_app/scripts/pin_summary.py, nigeria_app/scripts/stat_plots.py, nigeria_app/scripts/worldpop_parser.py, nigeria_app/check_double_names.py, nigeria_app/main.py, video/map_img.png, video/movie_comp.mov files
parent 061cdfb1
![](video/map_img.png)
![](demo/map_img.png)
## Introduction
......
# Description of the data
\ No newline at end of file
# sample environment containing some libraries
channels:
- defaults
- conda-forge
- districtdatalabs
dependencies:
- python=3.6.8
- numpy=1.16.2
- scipy=1.1.0
- scikit-learn=0.20.2
- jupyter=1.0.0
- pandas=0.23.4
#- nltk=3.3.0 # for NLP
- ipykernel=4.10.0
- scikit-plot
- scikit-optimize
- pathlib
- tensorflow=1.10
- libiconv=1.15
- gdal 3.0.0
- xlrd=1.2.0
#- keras=2.2.2
- pip=18.0
#- pip:
# - xgboost
# - bayesian-optimization
not empty
\ No newline at end of file
not empty
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
not empty
\ No newline at end of file
not empty
\ No newline at end of file
not empty
\ No newline at end of file
This diff is collapsed.
"""
Created on Wed Nov 07 2018
@author: Analytics Club at ETH internal@analytics-club.org
Example structure of the main file
"""
from src.data_extraction import load_data, save_data, merging, xml2df
from src.preprocessing import text_process, anonymization, clean_up, detect_language
def extract_data(program, mode):
"""
function to extract data
"""
print('Starting data extraction ...')
print('Program {}, mode {}'.format(program, mode))
def preprocess(program, mode):
"""
function for preprocessing
"""
print("Doing preprocessing")
print('Program {}, mode {}'.format(program, mode))
def train(program, mode):
"""
function to train the model
"""
print('Program {}, mode {}'.format(program, mode))
print('Training the model...')
def predict(program, mode):
"""
function to do predictions
"""
print('Program {}, mode {}'.format(program, mode))
print('Do prediction...')
def test(program, mode):
"""
function to do tests
"""
print('Program {}, mode {}'.format(program, mode))
print('Doing tests...')
This diff is collapsed.
This diff is collapsed.
"""
File that checks for double settlement camp names whilst having multiple longitudes and latitudes
"""
import pandas as pd
settlements = pd.ExcelFile('/Users/Vicky/Documents/Documents/Studium/IMPACT_project/Data/reach_nga_msna_initial_sample.xlsx')
settlements = settlements.parse(0)
settlements.columns = settlements.iloc[0,:]
settlements = settlements.iloc[1:,:]
nonnan = settlements.dropna(axis=0,subset=['lon'])
print(nonnan['Sample Settlement_Camp'].unique().shape)
print(nonnan['lon'].unique().shape)
samples = nonnan[['lon','lat','Sample Settlement_Camp']].drop_duplicates().groupby('Sample Settlement_Camp').count()
s2 = samples[samples['lon']>1].index.to_list()
s3 = nonnan[nonnan['Sample Settlement_Camp'].isin(s2)]
s3.sort_values(by='Sample Settlement_Camp', inplace=True)
s4 = s3.sort_values(by='Sample Settlement_Camp')
s4cols = s4.columns
s4cols = s4.columns.to_list()
s5 = s4[['Sample Settlement_Camp','lon','lat', [col for col in s4cols if col not in ['Sample Settlement_Camp','lon','lat']]]]
cols = [col for col in s4cols if col not in ['Sample Settlement_Camp','lon','lat']]
s5 = s4[['Sample Settlement_Camp','lon','lat'] + [col for col in s4cols if col not in ['Sample Settlement_Camp','lon','lat']]]
# now inspect s5
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
,"REACH Nigeria
Multi-Sector Needs Assessment
July to September 2018 ",Unnamed: 1
0,Item,Description
1,Project Background,"Despite the increase in number of humanitarian actors responding to the crisis, massive humanitarian needs in north-eastern Nigeria continue to growas the humanitarian conditions of civilians displaced by the violent ninth year
conflict remain dire. The conflict between armed opposition groups (AOGs) and Nigerian and regional security forces has resulted in 2018 in 10.2 million people - remainees, IDPs, returnees and populations in hard-to-reach areas - in urgent need of life-saving assistance in Adamawa, Borno and Yobe, the three most affected states in north-eastern Nigeria. Information gaps subsist to be able to plan humanitarian action based on solid evidence and grounded in coordination efforts.
In this context, the United Nations Office for the Coordination of Humanitarian Affairs (UNOCHA) and its Inter-Sector Working Group (ISWG) tasked REACH with conducting a multi-sector needs assessment in all accessible areas of the three affected Northeastern states of Nigeria. This assessment was funded by the European Union Civil protection and Humanitarian Aid (ECHO)."
2,Target populations,"IDPs, Returnees, Non-Displaced/Host Communities"
3,Methodology ,"This MSNA covered all accessible locations in the three northeastern states of Nigeria (Adamawa, Borno, Yobe). The household survey has been implemented based on a cluster sampling - and the HH data collection was complemented by a Key Informants data collection mainly aiming at cross-checking population estimates and information on clusters visited. The sampling produced statistically generalisable results at the levels of analysis mentioned below in the section ""Weighting for analysis"". Unless stated otherwise, results at the lowest disaggregated level of analysis are statistically representative to a confidence level of 90% and a margin of error of 10%."
4,Data collection time period and geographic coverage,"Data collection took place in one round, beginning on the 25 June and ending on 6 August with a pilot study conducted before data collection begins in Maiduguri, Borno state. In total, the assessment covered 63 LGAs in 3 States (exceptions to this were the LGAs of Abadam and Marte in Borno state which were still at the time of data collection considered completely inaccessible)"
5,Weighting for analysis,"Results of the Nigeria MSNA are representative to the following levels of analysis:
1. per LGA, not per population group (lowest level of representative data)
2. per livelihood domains, per population group
3. per State, per population group
The respective weighting coefficients to perform analysis on the clean data can be found in the rightmost columns of the clean dataset"
6,Multi-Sector Needs Assessment weblink ,http://www.reachresourcecentre.info/countries/nigeria
7,Credit,"The Multi-Sector Needs Assessment was carried out by REACH Initiative through field staff and enumerators, and was funded by the European Civil protection and Humanitarian aid Operations (ECHO)"
8,Contact,"Eric Kramak (eric.kramak@reach-initiative.org), Betsy Dankenbring (betsy.dankenbring@reach-initiative.org), Ugo Semat (ugo.semat@reach-initiative.org)"
9,,
10,Sheets,Description
11,Clean HH Data,"Clean dataset from MSNA data collection in all locations assessed, post-data cleaning"
12,Individual HH member Data,"Clean dataset from MSNA data collection relating to loop on individual household members in all locations assessed, post-data cleaning"
13,Individual Water loop Data,"Clean dataset from MSNA data collection relating to loop on water information in all locations assessed, post-data cleaning"
14,Survey,KoBo form used for the mobile data collection
15,Choices,KoBo form choices used for the mobile data collection
This diff is collapsed.
This diff is collapsed.
from bokeh.plotting import output_file, figure, show, save
from bokeh.models import GeoJSONDataSource, LinearColorMapper, HoverTool, Panel,BoxSelectTool, PolySelectTool, ColumnDataSource
from bokeh.models.widgets import CheckboxGroup, CheckboxButtonGroup, PreText
from bokeh.tile_providers import get_provider
from bokeh.layouts import column, row, WidgetBox
from bokeh.palettes import brewer
from bokeh.io import curdoc
import pandas as pd
import json
import numpy as np
import sys
import geopandas as gpd
sys.path.append('/Users/Vicky/Documents/Documents/Studium/IMPACT_project')
from bokeh.tile_providers import get_provider
import PiN_calc
def map_tab(grid, output, nigeriajson, camp_gdf):
def subset_data(grid, state_list, mode='columndata'):
if mode =='jsondata':
subset = json.loads(nigeriajson)
subset['features'] = [feat for feat in subset['features'] if feat['properties']['NAME_1'] in (state_list)]
subset = json.dumps(subset)
if mode =='columndata':
grid_df = pd.DataFrame(grid.data)
grid_df = grid_df[grid_df['NAME_1'].isin(state_list)]
subset = ColumnDataSource(grid_df)
return subset
def detail_data(data):
data_col = ColumnDataSource(data)
data_col.remove('Coordinates')
return data_col
def draw_map():
output_file(output, 'Nigeria')
# Define a sequential multi-hue color palette.
palette = brewer['YlGnBu'][8]
# Reverse color order so that dark blue is highest obesity.
palette = palette[::-1]
color_mapper = LinearColorMapper(palette=palette, low=0, high=40)
# Update function takes three default parameters
def update(attr, old, new):
# Get the list of states for the graph
states_to_plot = [state_selection.labels[i] for i in
state_selection.active]
# Make a new geotif_dataset based on the selected states and the
# make_dataset function defined earlier
new_src = subset_data(grid, states_to_plot)
# Update the source used in the quad glpyhs
src.data.update(new_src.data)
def update_details(attr, old, new):
details_to_plot = [detail_selection.labels[i] for i in
detail_selection.active]
if 'ShowWards' in details_to_plot:
new_details = detail_data(camp_gdf)
else:
new_details = detail_data(gpd.GeoDataFrame(columns=camp_gdf.columns))
details.data.update(new_details.data)
#camps.data_source.data = new_details.data
states = list(grid.data['NAME_1'])
active_all = np.linspace(0, len(states)-1, len(states),dtype=int).tolist()
state_selection = CheckboxGroup(labels=states,
active=active_all)
state_selection.on_change('active', update)
detail_selection = CheckboxGroup(labels=["ShowWards"], active=[])
detail_selection.on_change('active', update_details)
details = detail_data(gpd.GeoDataFrame(columns=camp_gdf.columns))
# Initial states to plot = all
initial_states = [state_selection.labels[i] for i in state_selection.active]
src = subset_data(grid, initial_states)
# Hover tool
hover = HoverTool(tooltips=[('Region', '@NAME_1'), ('ID', '@ID_1')])
p = figure(title='Nigeria', toolbar_location='above', tools=[hover, "pan","wheel_zoom","tap","reset"])
p.add_tools(BoxSelectTool(dimensions="width"))
p.add_tools(PolySelectTool())
p.add_tile(get_provider('CARTODBPOSITRON'))
#p.add_tile('CARTODBPOSITRON')
#p.patches('x', 'y', fill_alpha=0.7,
# fill_color={'field': 'ID_1', 'transform': color_mapper},
# line_color='black', line_width=0.5, source=src)
p.circle(x='lon', y='lat', fill_color='red', line_color='red', source=details)
return p, state_selection, detail_selection
def show_camps(p):
def update(attr, old, new):
p.circle(x=camp_gdf['lon'], y=camp_gdf['lat'], fill_color='red', line_color='red')
def deactivate(attr, old, new):
pass # How do I deactivate this??
button = CheckboxGroup(labels=["Show wards"], active=[])
button.on_change('active',update)
return button
def pin_overview():
pin_stats = PreText(text="""hello, world! hello,hello""", width=200)
return pin_stats
def update_stats(pin_stats):
pin_stats.text = 'Hello, world'
def load_osm_tiles():
import geoviews as gv
import geoviews.feature as gf
from geoviews import dim, opts
import geoviews.tile_sources as gts
gv.extension('bokeh')
gv.Layout([ts.relabel(name) for name, ts in gts.tile_sources.items()]).opts(
'WMTS', xaxis=None, yaxis=None, width=225, height=225).cols(4)
nonan = table.dropna(subset=['Overall'])
population = gv.Dataset(nonan, kdims=['HeadofHouseholdAge'])
points = population.to(gv.Points, ['longitude', 'latitude'], ['Overall', 'HeadofHouseholdAge'])
(gts.OSM * points).opts(
opts.Points(width=600, height=350, tools=['hover'], size=np.sqrt(dim('Overall')) * 0.005,
color='Overall', cmap='viridis'))
#hh_data, ind_member_data, pin_vals = PiN_calc.provide_pin()
#hh_data, ind_member_data, pin_vals = PiN_calc.read_pin('/Users/Vicky/Documents/Documents/Studium/IMPACT_project/team-2/nigeria_app/data', get_rest = True)
p, state_selection, detail_selection = draw_map()
#checkbox = show_camps(p)
pin_stats = pin_overview()
widgets = column(pin_stats, detail_selection)
layout = row(state_selection, p, widgets)
#curdoc().add_root(layout)
show(layout)
tab = Panel(child=layout, title='Nigeria Map')
return tab
import nigeria_app.scripts.stat_plots as splt
import src.cleanup.cleanup as clp
if __name__ == '__main__':
clean = clp.clean_table()
"""
Bokeh app main file. This file launches the other tabs and also creates the general layout for the app.
Usage:
Navigate to the parent directory of the nigeria_app folder in your console and launch the app using the following
command "bokeh serve --show nigeria_app"
"""
# Pandas for data management
import sys
import os
import pandas as pd
import geopandas as gpd
from shapely.geometry import Point
import yaml
# Bokeh basics
from bokeh.io import curdoc
from bokeh.models.widgets import Tabs
from bokeh.models import ColumnDataSource
def read_file_locations():
with open('/Users/Vicky/Documents/Documents/Studium/IMPACT_project.nosync/team-2/nigeria_app/scripts/file_locations.yml', 'rb') as file:
files = yaml.load(file)
sys.path.append(files['cleanup_path'])
sys.path.append(files['project_path'])
return files
def get_geodata(files):
"""
:return:
"""
nigeria_path = files['nigeria_map_path']
nigeria = gpd.read_file(nigeria_path)
camps = pd.ExcelFile(files['initial_sample'])
camp = camps.parse(0)
camp.columns = camp.iloc[0]
camp = camp.reindex(camp.index.drop(0))
camp_no_nan = camp.dropna(subset=['lon', 'lat'])
camp_no_nan['Coordinates'] = list(zip(camp_no_nan['lon'], camp_no_nan['lat']))
camp_no_nan['Coordinates'] = camp_no_nan['Coordinates'].apply(Point)
camp_gdf = gpd.GeoDataFrame(camp_no_nan, geometry='Coordinates')
nigeriajson = nigeria.to_json()
return nigeria, nigeriajson, camp, camp_gdf
def get_data_clean(files):
"""
Navigates to correct location and uses cleanup object and functions to generate cleaned geotif_dataset
:return: cleaned geotif_dataset (clean table of pandas dataframes)
"""
import cleanup as clp
cur_dir = os.getcwd()
os.chdir(files['cleanup_path'])
clean = clp.clean_table()
os.chdir(cur_dir)
return clean
def getPolyCoords(row, geom, coord_type):
"""Returns the coordinates ('x' or 'y') of edges of a Polygon exterior"""
# Parse the exterior of the coordinate
try:
exterior = row[geom].exterior
if coord_type == 'x':
# Get the x coordinates of the exterior
return list(exterior.coords.xy[0])
elif coord_type == 'y':
# Get the y coordinates of the exterior
return list(exterior.coords.xy[1])
except AttributeError:
ex_list = [poly.exterior for poly in row[geom]]
if coord_type == 'x':
# Get the x coordinates of the exterior
return [list(ext.coords.xy[0]) for ext in ex_list]
elif coord_type == 'y':
# Get the y coordinates of the exterior
return [list(ext.coords.xy[1]) for ext in ex_list]
def convert_shp_to_columns(grid):
"""
Converts the grid shapefile to a columndatasource
:param grid: shapefile of polygons (multipolygons also ok) that is to be transformed into column format.
:return: grid in column format with x and y coords as polygons edges
"""
# 1. Calculate the x and y coordinates of the geometries into separate columns
grid['x'] = grid.apply(getPolyCoords, geom='geometry', coord_type='x', axis=1)
grid['y'] = grid.apply(getPolyCoords, geom='geometry', coord_type='y', axis=1)
# 2. Drop the geometry column because otherwise the datasource cannot handle it
g_df = grid.drop('geometry', axis=1).copy()
g_df.loc[:,'NAME_1'] = g_df['NAME_1'].str.replace(" ","")
# 3. Convert to the Bokeh ColumnDataSource object
gsource = ColumnDataSource(g_df)
return gsource
# ------------------- Loading in the data new version ---------------#
# Load filenames and locations
files = read_file_locations()
# Each tab is drawn by one script
# from scripts.basic_map import map_tab
from nigeria_maps import map_tab
from pin_summary import pin_tab
# Get geodata
nigeria, nigeriajson, camp, camp_gdf = get_geodata(files)
grid = convert_shp_to_columns(nigeria)
# Get household data cleaned with pin
clean = get_data_clean(files)
# ---------------------- Creating the tabs ... ------------------------#
tab1 = map_tab(grid, files)
#tab2 = pin_tab(hh_data, camp, pin)
#tab3 = corr_tab(table)
tabs = Tabs(tabs=[tab1])
curdoc().add_root(tabs)
This diff is collapsed.
from bokeh.plotting import output_file, figure, show, save
from bokeh.models import GeoJSONDataSource, LinearColorMapper, HoverTool, Panel,BoxSelectTool, PolySelectTool, ColumnDataSource
from bokeh.models.widgets import CheckboxGroup, CheckboxButtonGroup, PreText
from bokeh.tile_providers import get_provider
from bokeh.layouts import column, row, WidgetBox
from bokeh.palettes import brewer
from bokeh.io import curdoc
import pandas as pd
import json
import numpy as np
import sys
import geopandas as gpd
sys.path.append('/Users/Vicky/Documents/Documents/Studium/IMPACT_project')
from bokeh.tile_providers import get_provider
import PiN_calc
def map_tab(grid, output, nigeriajson, camp_gdf):
def subset_data(grid, state_list, mode='columndata'):
if mode =='jsondata':
subset = json.loads(nigeriajson)
subset['features'] = [feat for feat in subset['features'] if feat['properties']['NAME_1'] in (state_list)]
subset = json.dumps(subset)
if mode =='columndata':
grid_df = pd.DataFrame(grid.data)
grid_df = grid_df[grid_df['NAME_1'].isin(state_list)]
subset = ColumnDataSource(grid_df)
return subset
def detail_data(data):
data_col = ColumnDataSource(data)
data_col.remove('Coordinates')
return data_col
def draw_map():
output_file(output, 'Nigeria')
# Define a sequential multi-hue color palette.
palette = brewer['YlGnBu'][8]
# Reverse color order so that dark blue is highest obesity.
palette = palette[::-1]
color_mapper = LinearColorMapper(palette=palette, low=0, high=40)
# Update function takes three default parameters
def update(attr, old, new):
# Get the list of states for the graph
states_to_plot = [state_selection.labels[i] for i in
state_selection.active]
# Make a new geotif_dataset based on the selected states and the
# make_dataset function defined earlier
new_src = subset_data(grid, states_to_plot)
# Update the source used in the quad glpyhs
src.data.update(new_src.data)
def update_details(attr, old, new):
details_to_plot = [detail_selection.labels[i] for i in
detail_selection.active]
if 'ShowWards' in details_to_plot:
new_details = detail_data(camp_gdf)
else:
new_details = detail_data(gpd.GeoDataFrame(columns=camp_gdf.columns))
details.data.update(new_details.data)
#camps.data_source.data = new_details.data
states = list(grid.data['NAME_1'])
active_all = np.linspace(0, len(states)-1, len(states),dtype=int).tolist()
state_selection = CheckboxGroup(labels=states,
active=active_all)
state_selection.on_change('active', update)
detail_selection = CheckboxGroup(labels=["ShowWards"], active=[])
detail_selection.on_change('active', update_details)
details = detail_data(gpd.GeoDataFrame(columns=camp_gdf.columns))
# Initial states to plot = all
initial_states = [state_selection.labels[i] for i in state_selection.active]
src = subset_data(grid, initial_states)
# Hover tool
hover = HoverTool(tooltips=[('Region', '@NAME_1'), ('ID', '@ID_1')])
p = figure(title='Nigeria', toolbar_location='above', tools=[hover, "pan","wheel_zoom","tap","reset"])
p.add_tools(BoxSelectTool(dimensions="width"))
p.add_tools(PolySelectTool())
p.add_tile(get_provider('CARTODBPOSITRON'))
#p.add_tile('CARTODBPOSITRON')
#p.patches('x', 'y', fill_alpha=0.7,
# fill_color={'field': 'ID_1', 'transform': color_mapper},
# line_color='black', line_width=0.5, source=src)
p.circle(x='lon', y='lat', fill_color='red', line_color='red', source=details)
return p, state_selection, detail_selection
def show_camps(p):
def update(attr, old, new):
p.circle(x=camp_gdf['lon'], y=camp_gdf['lat'], fill_color='red', line_color='red')
def deactivate(attr, old, new):
pass # How do I deactivate this??
button = CheckboxGroup(labels=["Show wards"], active=[])
button.on_change('active',update)
return button
def pin_overview():
pin_stats = PreText(text="""hello, world! hello,hello""", width=200)
return pin_stats
def update_stats(pin_stats):
pin_stats.text = 'Hello, world'
def load_osm_tiles():
import geoviews as gv
import geoviews.feature as gf
from geoviews import dim, opts
import geoviews.tile_sources as gts
gv.extension('bokeh')
gv.Layout([ts.relabel(name) for name, ts in gts.tile_sources.items()]).opts(
'WMTS', xaxis=None, yaxis=None, width=225, height=225).cols(4)
nonan = table.dropna(subset=['Overall'])
population = gv.Dataset(nonan, kdims=['HeadofHouseholdAge'])
points = population.to(gv.Points, ['longitude', 'latitude'], ['Overall', 'HeadofHouseholdAge'])
(gts.OSM * points).opts(
opts.Points(width=600, height=350, tools=['hover'], size=np.sqrt(dim('Overall')) * 0.005,
color='Overall', cmap='viridis'))