In this Notebook we are going to calculate the density of Airbnb's per neighbourhood using Geoviews. Geoviews is built on Holoviews and adds a family of geographic plot types based on the Cartopy library.
In [1]:
%%HTML
<style>
.container{width:75% !important;}
.text_cell_rendered_html{width:20% !important;}
</style>
In [2]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from matplotlib.pylab import rcParams
rcParams['figure.figsize'] = 15, 6
In [3]:
import xarray as xr
import numpy as np
import pandas as pd
import holoviews as hv
import geoviews as gv
import geoviews.feature as gf
import cartopy
from cartopy import crs as ccrs
from bokeh.tile_providers import STAMEN_TONER
from bokeh.models import WMTSTileSource
hv.notebook_extension('bokeh')
In [4]:
from bokeh.models import (
GeoJSONDataSource,
HoverTool,
LinearColorMapper
)
from bokeh.plotting import figure
from bokeh.palettes import Viridis6
from bokeh.io import output_notebook, show
output_notebook()
In [5]:
data = pd.read_csv("data/listings/08042017/listings.csv", low_memory=False)
num_hogares = pd.read_csv("data/num_hogares/NumHogaresYFamilias2011.csv", sep=";", thousands='.')
In [6]:
num_hogares.head()
Out[6]:
In [7]:
num_hogares.columns = num_hogares.columns.str.lstrip() #get rid of trailing spaces
def drop_digits(in_str): #sorry for this... I'm just too lazy sometimes
digit_list = "1234567890"
for char in digit_list:
in_str = in_str.str.replace(char, "")
return in_str
num_hogares.Barrio = drop_digits(num_hogares.Barrio)
num_hogares.Barrio = num_hogares.Barrio.str.replace(".", "")
#count the number of listings for each neighbourhood
n_airbnbs_barri= data.neighbourhood_cleansed.value_counts()
#make shure that Series contains neighbourhoods that are in census
n_airbnbs_barri = n_airbnbs_barri[n_airbnbs_barri.index.isin(num_hogares.Barrio)]
num_hogares = num_hogares[num_hogares.Barrio.isin(n_airbnbs_barri.index)]
num_hogares.index = num_hogares.Barrio
num_hogares.drop("Barrio", axis=1)[:2]
num_hogares = num_hogares.NumHogares
#num_hogares.drop(["Can Peguera", "Baró de Viver", "Torre Baró", "Vallbona"], inplace=True)#outliers
In [8]:
#calculate the density
density = n_airbnbs_barri/num_hogares
In [9]:
n_airbnbs = pd.DataFrame(n_airbnbs_barri)
n_households = pd.DataFrame(num_hogares)
In [10]:
#Add total number of airbnbs and households to df
n_airbnbs['N_Barri'] = n_airbnbs.index
n_households['N_Barri']= n_households.index
density = pd.DataFrame({"N_Barri":density.index, "value":density.values})
density = density.merge(n_airbnbs, how='left', on='N_Barri')
density = density.merge(n_households, how='left', on='N_Barri')
density.columns = ['N_Barri','value','n_airbnb','n_households']
density.head()
Out[10]:
In [11]:
barri_json_path = r"data/divisiones_administrativas/barris/barris_geo.json"
with open(barri_json_path, 'r') as f:
geo_source = GeoJSONDataSource(geojson=f.read())
TOOLS = "pan,wheel_zoom,box_zoom,reset,hover,save"
p = figure(title="Neighbourhoods", tools=TOOLS, x_axis_location=None,
y_axis_location=None, width=800, height=800)
p.grid.grid_line_color = None
p.patches('xs', 'ys', fill_alpha=0.7,
line_color='white', line_width=1, source=geo_source)
hover = p.select_one(HoverTool)
hover.point_policy = "follow_mouse"
hover.tooltips = [("Neighbourhood", "@N_Barri")]
show(p)
In [12]:
shapefile = "data/divisiones_administrativas/barris/shape/barris_geo.shp"
shapes = cartopy.io.shapereader.Reader(shapefile)
density_hv = hv.Dataset(density)
density_hv.data.dropna(inplace=True)
In [13]:
%%opts Overlay [width=1000 height=1000 xaxis=None yaxis=None]
%%output filename="holoviewsmap"
gv.Shape.from_records(shapes.records(), density_hv, on='N_Barri', value='value',
index=['N_Barri','n_airbnb','n_households'], #hack to make them appear at the hoovertool
crs=ccrs.PlateCarree(), group="Densitat Airbnb Barcelona per nombre d'hogars",
drop_missing=False)
%%opts Shape (cmap='Reds') [tools=['hover'] width=1000 height=1000 colorbar=True toolbar='above' xaxis=None yaxis=None]
Out[13]:
In [ ]:
In [ ]: