In this Notebook we explain how to implement Python codes to plot choropleth maps of territorial income distribution and other demographic indicators in the city of Barcelona obtained from Barcelona open data repository using Python's Folium library.
The first dataset that we are going to analyze is the Renta Familiar Disponible (RFD) index dataset, this dataset contains the Disposable Family Income Index by Neighborhood, the most recent one is from year 2017.
import folium
import pandas as pd
import numpy as np
renta = pd.read_csv("2017_distribucio_territorial_renda_familiar.csv")
renta['NOM'] = renta['Nom_Barri'] # add new column for later ploting the choropleth map
renta['NOM'][renta['NOM']=='el Poble Sec'] = 'el Poble-sec' # make sure to be consistent with JSON file
renta
/var/folders/03/gv3k10bj7135k97m7mbkq26h0000gn/T/ipykernel_8504/3333412267.py:7: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy renta['NOM'][renta['NOM']=='el Poble Sec'] = 'el Poble-sec' # make sure to be consistent with JSON file
| Any | Codi_Districte | Nom_Districte | Codi_Barri | Nom_Barri | Població | Índex RFD Barcelona = 100 | NOM | |
|---|---|---|---|---|---|---|---|---|
| 0 | 2017 | 1 | Ciutat Vella | 1 | el Raval | 47986 | 71.2 | el Raval |
| 1 | 2017 | 1 | Ciutat Vella | 2 | el Barri Gòtic | 16240 | 106.1 | el Barri Gòtic |
| 2 | 2017 | 1 | Ciutat Vella | 3 | la Barceloneta | 15101 | 79.6 | la Barceloneta |
| 3 | 2017 | 1 | Ciutat Vella | 4 | Sant Pere, Santa Caterina i la Ribera | 22923 | 99.4 | Sant Pere, Santa Caterina i la Ribera |
| 4 | 2017 | 2 | Eixample | 5 | el Fort Pienc | 32048 | 106.5 | el Fort Pienc |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 68 | 2017 | 10 | Sant Martí | 69 | Diagonal Mar i el Front Marítim del Poblenou | 13710 | 150.1 | Diagonal Mar i el Front Marítim del Poblenou |
| 69 | 2017 | 10 | Sant Martí | 70 | el Besòs i el Maresme | 22893 | 60.4 | el Besòs i el Maresme |
| 70 | 2017 | 10 | Sant Martí | 71 | Provençals del Poblenou | 20649 | 102.3 | Provençals del Poblenou |
| 71 | 2017 | 10 | Sant Martí | 72 | Sant Martí de Provençals | 26187 | 67.4 | Sant Martí de Provençals |
| 72 | 2017 | 10 | Sant Martí | 73 | la Verneda i la Pau | 28725 | 57.0 | la Verneda i la Pau |
73 rows × 8 columns
renta.nlargest(3, 'Índex RFD Barcelona = 100')
| Any | Codi_Districte | Nom_Districte | Codi_Barri | Nom_Barri | Població | Índex RFD Barcelona = 100 | NOM | |
|---|---|---|---|---|---|---|---|---|
| 20 | 2017 | 4 | Les Corts | 21 | Pedralbes | 12117 | 248.8 | Pedralbes |
| 23 | 2017 | 5 | Sarrià-Sant Gervasi | 24 | les Tres Torres | 16660 | 215.8 | les Tres Torres |
| 22 | 2017 | 5 | Sarrià-Sant Gervasi | 23 | Sarrià | 25106 | 193.6 | Sarrià |
renta.nsmallest(3, 'Índex RFD Barcelona = 100')
| Any | Codi_Districte | Nom_Districte | Codi_Barri | Nom_Barri | Població | Índex RFD Barcelona = 100 | NOM | |
|---|---|---|---|---|---|---|---|---|
| 54 | 2017 | 8 | Nou Barris | 55 | Ciutat Meridiana | 10369 | 38.6 | Ciutat Meridiana |
| 11 | 2017 | 3 | Sants-Montjuïc | 12 | la Marina del Prat Vermell | 1151 | 40.0 | la Marina del Prat Vermell |
| 55 | 2017 | 8 | Nou Barris | 56 | Vallbona | 1379 | 40.9 | Vallbona |
https://opendata-ajuntament.barcelona.cat/data/en/dataset/20170706-districtes-barris provides json files with detail of administrative units of the city of Barcelona : districts, neighbourhoods, area of interest, basic statistical areas (AEB) and census areas. Today, Barcelona contains 10 different districts and 73 neighborhoods. In this article we employ neighborhood datas.
'''
import json
with open('0301100100_UNITATS_ADM_POLIGONS.json', 'r') as f:
data_o = json.load(f)
# Neighborhood datas are located from 11 to 84 therefore we only get these slice of data
data_o['features'] = data_o['features'][11:84]
for n in range(73):
data_o['features'][n]['properties']['Índex RFD Barcelona = 100']= renta['Índex RFD Barcelona = 100'].iloc[n]
'''
According to https://opendata-ajuntament.barcelona.cat/ca/faqs , the coordinates in this json file use Spatial Reference System EPSG 25831, we need to transfom this system into EPSG 4326, which is the more standard reference system that we use nowadays. The simplest way to transform coordinates systems in Python is to use pyproj, i.e. the Python interface to PROJ.4 library.
'''
from pyproj import Transformer
def trans(coordinate):
transformer = Transformer.from_crs("epsg:25831", "epsg:4326")
x2,y2 = transformer.transform(coordinate[0],coordinate[1])
return [y2, x2]
for n in range(73):
for i in range(len(data['features'][n]['geometry']['coordinates'][0])):
data['features'][n]['geometry']['coordinates'][0][i] = trans(data['features'][n]['geometry']['coordinates'][0][i])
if len(data['features'][n]['geometry']['coordinates'])>1:
for j in range(len(data['features'][n]['geometry']['coordinates'][1])):
data['features'][n]['geometry']['coordinates'][1][j] = trans(data['features'][n]['geometry']['coordinates'][1][j])
print(n)
# Once we transformed the coordinates we save the it as bcn_distric.json to avoid trasforming it again
data_json = json.dumps(data)
with open("bcn_neighborhood.json", "w") as outfile:
outfile.write(data_json)
'''
import json
from copy import deepcopy
with open('bcn_neighborhood.json', 'r') as f:
data = json.load(f)
for n in range(73):
data['features'][n]['properties']['Índex RFD Barcelona = 100']= renta['Índex RFD Barcelona = 100'].iloc[n]
BCN_map = folium.Map(location=[41.39, 2.17], zoom_start=12) # in location we must add the city's coordinates
choropleth = folium.Choropleth(geo_data=data, # GeoJson Coordinates
data=renta, # The table which contains the values we are analysing
columns=['NOM', 'Índex RFD Barcelona = 100'],
key_on='feature.properties.NOM', # We chose the key we need in the GeoJson file
fill_color='YlOrRd',
fill_opacity=0.7,
line_opacity=0.4,
legend_name='BCN income by neighborhood').add_to(BCN_map)
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['NOM', 'Índex RFD Barcelona = 100'],
aliases=['Neiboorhood','RFD index']))
BCN_map
BCN_map.save("choropleth maps/bcn_renta_2017.html")
To better differentiate neigborhoods with above average RFD index with neigborhoods with below average RFD, we can plot again choropleth map with 2 different color scales as illustrated in following codes.
low_neighborhoods = deepcopy(data)
high_neighborhoods = deepcopy(data)
index1=0
index2=0
while index1< len(low_neighborhoods['features']):
if low_neighborhoods['features'][index1]['properties']['Índex RFD Barcelona = 100']>=100:
low_neighborhoods['features'].pop(index1)
else: index1+=1
while index2< len(high_neighborhoods['features']):
if high_neighborhoods['features'][index2]['properties']['Índex RFD Barcelona = 100']<100:
high_neighborhoods['features'].pop(index2)
else: index2+=1
print('Numebr of neighborhoods with below average RFD index:', len(low_neighborhoods['features']))
print('Numebr of neighborhoods with equal or above average RFD index:', len(high_neighborhoods['features']))
Numebr of neighborhoods with below average RFD index: 49 Numebr of neighborhoods with equal or above average RFD index: 24
BCN_map = folium.Map(location=[41.39, 2.17], zoom_start=12) # in location we must add the city's coordinates
choropleth = folium.Choropleth(geo_data=low_neighborhoods, # GeoJson Coordinates
data= renta[renta['Índex RFD Barcelona = 100']<100], # The table which contains the values we are analysing
columns=['NOM', 'Índex RFD Barcelona = 100'],
key_on='feature.properties.NOM', # We chose the key we need in the GeoJson file
fill_color='PuRd',
fill_opacity=0.7,
line_opacity=0.4,
legend_name='Below average RFD index').add_to(BCN_map)
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['NOM', 'Índex RFD Barcelona = 100'],
aliases=['Neiboorhood','RFD index']))
choropleth = folium.Choropleth(geo_data=high_neighborhoods, # GeoJson Coordinates
data=renta[renta['Índex RFD Barcelona = 100']>=100], # The table which contains the values we are analysing
columns=['NOM', 'Índex RFD Barcelona = 100'],
key_on='feature.properties.NOM', # We chose the key we need in the GeoJson file
fill_color='YlGn',
legend_name='Equal or above average RFD index').add_to(BCN_map)
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['NOM', 'Índex RFD Barcelona = 100'],
aliases=['Neiboorhood','RFD index']))
BCN_map
BCN_map.save("choropleth maps/bcn_renta_2017_2.html")
renta_07 = pd.read_csv("2007_distribucio_territorial_renda_familiar.csv")
renta_07 = renta_07.iloc[:-1] # this file contains an extra null row so here we exclude that row
renta_07['NOM'] = renta_07['Nom_Barri']
renta_07['NOM'][renta_07['NOM']=='el Poble Sec'] = 'el Poble-sec'
renta_07['Índex RFD Barcelona = 100'] = renta_07['Índex RFD Barcelona = 100'].astype('float64')
renta_07['RFD change'] = (renta['Índex RFD Barcelona = 100']-renta_07['Índex RFD Barcelona = 100'])/renta_07['Índex RFD Barcelona = 100']*100
for n in range(73):
data['features'][n]['properties']['RFD change']= renta_07['RFD change'].iloc[n]
data['features'][n]['properties']['Índex RFD Barcelona = 100']= renta_07['Índex RFD Barcelona = 100'].iloc[n]
renta_07
/var/folders/03/gv3k10bj7135k97m7mbkq26h0000gn/T/ipykernel_8504/4290161235.py:4: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy renta_07['NOM'][renta_07['NOM']=='el Poble Sec'] = 'el Poble-sec'
| Any | Codi_Districte | Nom_Districte | Codi_Barri | Nom_Barri | Població | Índex RFD Barcelona = 100 | NOM | RFD change | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 2007 | 1 | Ciutat Vella | 1 | el Raval | 46595 | 64.7 | el Raval | 10.046368 |
| 1 | 2007 | 1 | Ciutat Vella | 2 | el Barri Gòtic | 27946 | 86.5 | el Barri Gòtic | 22.658960 |
| 2 | 2007 | 1 | Ciutat Vella | 3 | la Barceloneta | 15921 | 66.7 | la Barceloneta | 19.340330 |
| 3 | 2007 | 1 | Ciutat Vella | 4 | Sant Pere, Santa Caterina i la Ribera | 22572 | 80.2 | Sant Pere, Santa Caterina i la Ribera | 23.940150 |
| 4 | 2007 | 2 | Eixample | 5 | el Fort Pienc | 31521 | 107.9 | el Fort Pienc | -1.297498 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 68 | 2007 | 10 | Sant Martí | 69 | Diagonal Mar i el Front Marítim del Poblenou | 9775 | 101.1 | Diagonal Mar i el Front Marítim del Poblenou | 48.466864 |
| 69 | 2007 | 10 | Sant Martí | 70 | el Besòs i el Maresme | 22652 | 61.7 | el Besòs i el Maresme | -2.106969 |
| 70 | 2007 | 10 | Sant Martí | 71 | Provençals del Poblenou | 18731 | 85.7 | Provençals del Poblenou | 19.369895 |
| 71 | 2007 | 10 | Sant Martí | 72 | Sant Martí de Provençals | 26261 | 81.5 | Sant Martí de Provençals | -17.300613 |
| 72 | 2007 | 10 | Sant Martí | 73 | la Verneda i la Pau | 29452 | 74.8 | la Verneda i la Pau | -23.796791 |
73 rows × 9 columns
renta_07.nlargest(3, 'Índex RFD Barcelona = 100')
| Any | Codi_Districte | Nom_Districte | Codi_Barri | Nom_Barri | Població | Índex RFD Barcelona = 100 | NOM | RFD change | |
|---|---|---|---|---|---|---|---|---|---|
| 23 | 2007 | 5 | Sarrià-Sant Gervasi | 24 | les Tres Torres | 15325 | 215.3 | les Tres Torres | 0.232234 |
| 20 | 2007 | 4 | Les Corts | 21 | Pedralbes | 11413 | 193.6 | Pedralbes | 28.512397 |
| 25 | 2007 | 5 | Sarrià-Sant Gervasi | 26 | Sant Gervasi - Galvany | 46454 | 187.0 | Sant Gervasi - Galvany | 2.727273 |
renta_07.nsmallest(3, 'Índex RFD Barcelona = 100')
| Any | Codi_Districte | Nom_Districte | Codi_Barri | Nom_Barri | Població | Índex RFD Barcelona = 100 | NOM | RFD change | |
|---|---|---|---|---|---|---|---|---|---|
| 57 | 2007 | 9 | Sant Andreu | 58 | Baró de Viver | 2397 | 44.5 | Baró de Viver | 54.831461 |
| 46 | 2007 | 8 | Nou Barris | 47 | Can Peguera | 2143 | 49.8 | Can Peguera | 3.413655 |
| 55 | 2007 | 8 | Nou Barris | 56 | Vallbona | 1267 | 51.6 | Vallbona | -20.736434 |
low_neighborhoods = deepcopy(data)
high_neighborhoods = deepcopy(data)
index1=0
index2=0
while index1< len(low_neighborhoods['features']):
if low_neighborhoods['features'][index1]['properties']['Índex RFD Barcelona = 100']>=100:
low_neighborhoods['features'].pop(index1)
else: index1+=1
while index2< len(high_neighborhoods['features']):
if high_neighborhoods['features'][index2]['properties']['Índex RFD Barcelona = 100']<100:
high_neighborhoods['features'].pop(index2)
else: index2+=1
print('Numebr of neighborhoods with below average RFD index:', len(low_neighborhoods['features']))
print('Numebr of neighborhoods with equal or above average RFD index:', len(high_neighborhoods['features']))
Numebr of neighborhoods with below average RFD index: 50 Numebr of neighborhoods with equal or above average RFD index: 23
BCN_map = folium.Map(location=[41.39, 2.17], zoom_start=12) # in location we must add the city's coordinates
choropleth = folium.Choropleth(geo_data=low_neighborhoods, # GeoJson Coordinates
data= renta_07[renta_07['Índex RFD Barcelona = 100']<100], # The table which contains the values we are analysing
columns=['NOM', 'Índex RFD Barcelona = 100'],
key_on='feature.properties.NOM', # We chose the key we need in the GeoJson file
fill_color='PuRd',
fill_opacity=0.7,
line_opacity=0.4,
legend_name='Below average RFD index 2007').add_to(BCN_map)
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['NOM', 'Índex RFD Barcelona = 100'],
aliases=['Neiboorhood','RFD index']))
choropleth = folium.Choropleth(geo_data=high_neighborhoods, # GeoJson Coordinates
data=renta_07[renta_07['Índex RFD Barcelona = 100']>=100], # The table which contains the values we are analysing
columns=['NOM', 'Índex RFD Barcelona = 100'],
key_on='feature.properties.NOM', # We chose the key we need in the GeoJson file
fill_color='YlGn',
legend_name='Equal or above average RFD index 2007').add_to(BCN_map)
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['NOM', 'Índex RFD Barcelona = 100'],
aliases=['Neiboorhood','RFD index']))
BCN_map
BCN_map.save("choropleth maps/bcn_renta_2007.html")
Population map:
for n in range(73):
data['features'][n]['properties']['Població']= int(renta_07['Població'].iloc[n])
BCN_map = folium.Map(location=[41.39, 2.17], zoom_start=12) # in location we must add the city's coordinates
choropleth = folium.Choropleth(geo_data=data, # GeoJson Coordinates
data=renta_07, # The table which contains the values we are analysing
columns=['NOM', 'Població'],
key_on='feature.properties.NOM', # We chose the key we need in the GeoJson file
fill_color='YlOrRd',
fill_opacity=0.7,
line_opacity=0.4,
legend_name='BCN population').add_to(BCN_map)
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['NOM', 'Població'],
aliases=['Neiboorhood','Population']))
BCN_map
negative_neighborhoods = deepcopy(data) #
postive_neighborhoods = deepcopy(data) #
index1=0
index2=0
while index1< len(negative_neighborhoods['features']):
if negative_neighborhoods['features'][index1]['properties']['RFD change']>=0:
negative_neighborhoods['features'].pop(index1)
else: index1+=1
while index2< len(postive_neighborhoods['features']):
if postive_neighborhoods['features'][index2]['properties']['RFD change']<0:
postive_neighborhoods['features'].pop(index2)
else: index2+=1
print('Numebr of neighborhoods with negative RFD change:', len(negative_neighborhoods['features']))
print('Numebr of neighborhoods with positive RFD change:', len(postive_neighborhoods['features']))
Numebr of neighborhoods with negative RFD change: 46 Numebr of neighborhoods with positive RFD change: 27
BCN_map = folium.Map(location=[41.39, 2.17], zoom_start=12) # in location we must add the city's coordinates
choropleth = folium.Choropleth(geo_data=negative_neighborhoods, # GeoJson Coordinates
data=renta_07[renta_07['RFD change']<0], # The table which contains the values we are analysing
columns=['NOM', 'RFD change'],
key_on='feature.properties.NOM', # We chose the key we need in the GeoJson file
fill_color='PuRd',
fill_opacity=0.7,
line_opacity=0.4,
legend_name='Negative RFD change %').add_to(BCN_map)
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['NOM', 'RFD change'],
aliases=['Neiboorhood','RFD change %']))
choropleth = folium.Choropleth(geo_data=postive_neighborhoods, # GeoJson Coordinates
data=renta_07[renta_07['RFD change']>=0], # The table which contains the values we are analysing
columns=['NOM', 'RFD change'],
key_on='feature.properties.NOM', # We chose the key we need in the GeoJson file
fill_color='YlGn',
legend_name='Positive RFD change %').add_to(BCN_map)
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['NOM', 'RFD change'],
aliases=['Neiboorhood','RFD change %']))
BCN_map
BCN_map.save("choropleth maps/bcn_renta_change.html")
Disposable household income in euros per capita in the city of Barcelona
renta_15 = pd.read_csv("2015_renda_disponible_llars.csv")
renta_15
| Any | Codi_Districte | Nom_Districte | Codi_Barri | Nom_Barri | Import_€_Any | |
|---|---|---|---|---|---|---|
| 0 | 2015 | 1 | Ciutat Vella | 1 | el Raval | 10896 |
| 1 | 2015 | 1 | Ciutat Vella | 2 | el Barri Gòtic | 14456 |
| 2 | 2015 | 1 | Ciutat Vella | 3 | la Barceloneta | 14714 |
| 3 | 2015 | 1 | Ciutat Vella | 4 | Sant Pere, Santa Caterina i la Ribera | 15154 |
| 4 | 2015 | 2 | Eixample | 5 | el Fort Pienc | 20817 |
| ... | ... | ... | ... | ... | ... | ... |
| 68 | 2015 | 10 | Sant Martí | 69 | Diagonal Mar i el Front Marítim del Poblenou | 23274 |
| 69 | 2015 | 10 | Sant Martí | 70 | el Besòs i el Maresme | 12474 |
| 70 | 2015 | 10 | Sant Martí | 71 | Provençals del Poblenou | 18642 |
| 71 | 2015 | 10 | Sant Martí | 72 | Sant Martí de Provençals | 17613 |
| 72 | 2015 | 10 | Sant Martí | 73 | la Verneda i la Pau | 16022 |
73 rows × 6 columns
renta_15 = pd.read_csv("2015_renda_disponible_llars.csv")
renta_15['NOM'] = renta_15['Nom_Barri']
renta_15['NOM'][renta_15['NOM']=='el Poble Sec'] = 'el Poble-sec'
for n in range(73):
data['features'][n]['properties']['Import_€_Any']= int(renta_15['Import_€_Any'].iloc[n])
renta_15
/var/folders/03/gv3k10bj7135k97m7mbkq26h0000gn/T/ipykernel_8504/579969240.py:3: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy renta_15['NOM'][renta_15['NOM']=='el Poble Sec'] = 'el Poble-sec'
| Any | Codi_Districte | Nom_Districte | Codi_Barri | Nom_Barri | Import_€_Any | NOM | |
|---|---|---|---|---|---|---|---|
| 0 | 2015 | 1 | Ciutat Vella | 1 | el Raval | 10896 | el Raval |
| 1 | 2015 | 1 | Ciutat Vella | 2 | el Barri Gòtic | 14456 | el Barri Gòtic |
| 2 | 2015 | 1 | Ciutat Vella | 3 | la Barceloneta | 14714 | la Barceloneta |
| 3 | 2015 | 1 | Ciutat Vella | 4 | Sant Pere, Santa Caterina i la Ribera | 15154 | Sant Pere, Santa Caterina i la Ribera |
| 4 | 2015 | 2 | Eixample | 5 | el Fort Pienc | 20817 | el Fort Pienc |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 68 | 2015 | 10 | Sant Martí | 69 | Diagonal Mar i el Front Marítim del Poblenou | 23274 | Diagonal Mar i el Front Marítim del Poblenou |
| 69 | 2015 | 10 | Sant Martí | 70 | el Besòs i el Maresme | 12474 | el Besòs i el Maresme |
| 70 | 2015 | 10 | Sant Martí | 71 | Provençals del Poblenou | 18642 | Provençals del Poblenou |
| 71 | 2015 | 10 | Sant Martí | 72 | Sant Martí de Provençals | 17613 | Sant Martí de Provençals |
| 72 | 2015 | 10 | Sant Martí | 73 | la Verneda i la Pau | 16022 | la Verneda i la Pau |
73 rows × 7 columns
BCN_map = folium.Map(location=[41.39, 2.17], zoom_start=12) # in location we must add the city's coordinates
choropleth = folium.Choropleth(geo_data=data, # GeoJson Coordinates
data=renta_15, # The table which contains the values we are analysing
columns=['NOM', 'Import_€_Any'],
key_on='feature.properties.NOM', # We chose the key we need in the GeoJson file
fill_color='YlOrRd',
fill_opacity=0.7,
line_opacity=0.4,
legend_name='Disposable household income per capita year 2015').add_to(BCN_map)
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['NOM', 'Import_€_Any'],
aliases=['Neiboorhood','Euros_Any €']))
BCN_map
BCN_map.save("choropleth maps/disposable_income_15.html")
renta_19 = pd.read_csv("2019_renda_disponible_llars.csv")
renta_19['NOM'] = renta_19['Nom_Barri']
renta_19['NOM'][renta_19['NOM']=='el Poble Sec'] = 'el Poble-sec'
for n in range(73):
data['features'][n]['properties']['Euros_Any']= int(renta_19['Euros_Any'].iloc[n])
renta_19
/var/folders/03/gv3k10bj7135k97m7mbkq26h0000gn/T/ipykernel_8504/3458952715.py:3: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy renta_19['NOM'][renta_19['NOM']=='el Poble Sec'] = 'el Poble-sec'
| Any | Codi_Districte | Nom_Districte | Codi_Barri | Nom_Barri | Euros_Any | NOM | |
|---|---|---|---|---|---|---|---|
| 0 | 2019 | 1 | Ciutat Vella | 1 | el Raval | 12142 | el Raval |
| 1 | 2019 | 1 | Ciutat Vella | 2 | el Barri Gòtic | 16732 | el Barri Gòtic |
| 2 | 2019 | 1 | Ciutat Vella | 3 | la Barceloneta | 16322 | la Barceloneta |
| 3 | 2019 | 1 | Ciutat Vella | 4 | Sant Pere, Santa Caterina i la Ribera | 18075 | Sant Pere, Santa Caterina i la Ribera |
| 4 | 2019 | 2 | Eixample | 5 | el Fort Pienc | 23137 | el Fort Pienc |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 68 | 2019 | 10 | Sant Martí | 69 | Diagonal Mar i el Front Marítim del Poblenou | 25589 | Diagonal Mar i el Front Marítim del Poblenou |
| 69 | 2019 | 10 | Sant Martí | 70 | el Besòs i el Maresme | 12787 | el Besòs i el Maresme |
| 70 | 2019 | 10 | Sant Martí | 71 | Provençals del Poblenou | 20080 | Provençals del Poblenou |
| 71 | 2019 | 10 | Sant Martí | 72 | Sant Martí de Provençals | 18637 | Sant Martí de Provençals |
| 72 | 2019 | 10 | Sant Martí | 73 | la Verneda i la Pau | 16820 | la Verneda i la Pau |
73 rows × 7 columns
BCN_map = folium.Map(location=[41.39, 2.17], zoom_start=12) # in location we must add the city's coordinates
choropleth = folium.Choropleth(geo_data=data, # GeoJson Coordinates
data=renta_19, # The table which contains the values we are analysing
columns=['NOM', 'Euros_Any'],
key_on='feature.properties.NOM', # We chose the key we need in the GeoJson file
fill_color='YlOrRd',
fill_opacity=0.7,
line_opacity=0.4,
legend_name='Disposable household income per capita year 2019').add_to(BCN_map)
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['NOM', 'Euros_Any'],
aliases=['Neiboorhood','Euros_Any €']))
BCN_map
BCN_map.save("choropleth maps/disposable_income_19.html")
Demographic indicators. Immigration registration rate (‰ inhabitants) of the city of Barcelona. This rate is the relation between registrations due to immigration in one year and the population of the same year per thousand inhabitants. Column 'Nombre' represents the number of Immigration registration per thousand inhabitants. https://opendata-ajuntament.barcelona.cat/data/en/dataset/est-demo-taxa-immigracio
immigration_20 = pd.read_csv("2020_taxa_immigracio.csv")
immigration_20['NOM'] = immigration_20['Nom_Barri']
immigration_20['NOM'][immigration_20['NOM']=='el Poble Sec'] = 'el Poble-sec'
for n in range(73):
data['features'][n]['properties']['Nombre']= immigration_20['Nombre'].iloc[n]
immigration_20
/var/folders/03/gv3k10bj7135k97m7mbkq26h0000gn/T/ipykernel_8504/3056993680.py:3: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy immigration_20['NOM'][immigration_20['NOM']=='el Poble Sec'] = 'el Poble-sec'
| Any | Codi_Districte | Nom_Districte | Codi_Barri | Nom_Barri | Taxa_mil_hab | Nombre | NOM | |
|---|---|---|---|---|---|---|---|---|
| 0 | 2020 | 1 | Ciutat Vella | 1 | el Raval | Taxa per mil habitants | 83.2 | el Raval |
| 1 | 2020 | 1 | Ciutat Vella | 2 | el Barri Gòtic | Taxa per mil habitants | 128.3 | el Barri Gòtic |
| 2 | 2020 | 1 | Ciutat Vella | 3 | la Barceloneta | Taxa per mil habitants | 87.2 | la Barceloneta |
| 3 | 2020 | 1 | Ciutat Vella | 4 | Sant Pere, Santa Caterina i la Ribera | Taxa per mil habitants | 89.1 | Sant Pere, Santa Caterina i la Ribera |
| 4 | 2020 | 2 | Eixample | 5 | el Fort Pienc | Taxa per mil habitants | 56.1 | el Fort Pienc |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 68 | 2020 | 10 | Sant Martí | 69 | Diagonal Mar i el Front Marítim del Poblenou | Taxa per mil habitants | 39.1 | Diagonal Mar i el Front Marítim del Poblenou |
| 69 | 2020 | 10 | Sant Martí | 70 | el Besòs i el Maresme | Taxa per mil habitants | 68.6 | el Besòs i el Maresme |
| 70 | 2020 | 10 | Sant Martí | 71 | Provençals del Poblenou | Taxa per mil habitants | 34.4 | Provençals del Poblenou |
| 71 | 2020 | 10 | Sant Martí | 72 | Sant Martí de Provençals | Taxa per mil habitants | 32.5 | Sant Martí de Provençals |
| 72 | 2020 | 10 | Sant Martí | 73 | la Verneda i la Pau | Taxa per mil habitants | 29.1 | la Verneda i la Pau |
73 rows × 8 columns
BCN_map = folium.Map(location=[41.39, 2.17], zoom_start=12) # in location we must add the city's coordinates
choropleth = folium.Choropleth(geo_data=data, # GeoJson Coordinates
data=immigration_20, # The table which contains the values we are analysing
columns=['NOM', 'Nombre'],
key_on='feature.properties.NOM', # We chose the key we need in the GeoJson file
fill_color='YlOrRd',
fill_opacity=0.7,
line_opacity=0.4,
legend_name='Immigration registration rate').add_to(BCN_map)
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['NOM', 'Nombre'],
aliases=['Neiboorhood','Immigration rate']))
BCN_map
BCN_map.save("choropleth maps/immigration_rate_20.html")
Demographic indicators. Birth rate (‰ inhabitants) of the city of Barcelona available at: https://opendata-ajuntament.barcelona.cat/data/en/dataset/est-demo-taxa-natalitat
birthrate_20 = pd.read_csv("2020_taxa_natalitat.csv")
birthrate_20['NOM'] = birthrate_20['Nom_Barri']
birthrate_20['NOM'][birthrate_20['NOM']=='el Poble Sec'] = 'el Poble-sec'
birthrate_20 = birthrate_20.rename(columns={"Nombre": "Birth_rate"})
for n in range(73):
data['features'][n]['properties']['Birth_rate']= birthrate_20['Birth_rate'].iloc[n]
birthrate_20
/var/folders/03/gv3k10bj7135k97m7mbkq26h0000gn/T/ipykernel_8504/2588264616.py:3: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy birthrate_20['NOM'][birthrate_20['NOM']=='el Poble Sec'] = 'el Poble-sec'
| Any | Codi_Districte | Nom_Districte | Codi_Barri | Nom_Barri | Taxa_mil_hab | Birth_rate | NOM | |
|---|---|---|---|---|---|---|---|---|
| 0 | 2020 | 1 | Ciutat Vella | 1 | el Raval | Taxa per mil habitants | 9.7 | el Raval |
| 1 | 2020 | 1 | Ciutat Vella | 2 | el Barri Gòtic | Taxa per mil habitants | 6.0 | el Barri Gòtic |
| 2 | 2020 | 1 | Ciutat Vella | 3 | la Barceloneta | Taxa per mil habitants | 5.7 | la Barceloneta |
| 3 | 2020 | 1 | Ciutat Vella | 4 | Sant Pere, Santa Caterina i la Ribera | Taxa per mil habitants | 5.6 | Sant Pere, Santa Caterina i la Ribera |
| 4 | 2020 | 2 | Eixample | 5 | el Fort Pienc | Taxa per mil habitants | 5.4 | el Fort Pienc |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 68 | 2020 | 10 | Sant Martí | 69 | Diagonal Mar i el Front Marítim del Poblenou | Taxa per mil habitants | 8.6 | Diagonal Mar i el Front Marítim del Poblenou |
| 69 | 2020 | 10 | Sant Martí | 70 | el Besòs i el Maresme | Taxa per mil habitants | 7.2 | el Besòs i el Maresme |
| 70 | 2020 | 10 | Sant Martí | 71 | Provençals del Poblenou | Taxa per mil habitants | 7.4 | Provençals del Poblenou |
| 71 | 2020 | 10 | Sant Martí | 72 | Sant Martí de Provençals | Taxa per mil habitants | 6.0 | Sant Martí de Provençals |
| 72 | 2020 | 10 | Sant Martí | 73 | la Verneda i la Pau | Taxa per mil habitants | 6.1 | la Verneda i la Pau |
73 rows × 8 columns
BCN_map = folium.Map(location=[41.39, 2.17], zoom_start=12) # in location we must add the city's coordinates
choropleth = folium.Choropleth(geo_data=data, # GeoJson Coordinates
data=birthrate_20, # The table which contains the values we are analysing
columns=['NOM', 'Birth_rate'],
key_on='feature.properties.NOM', # We chose the key we need in the GeoJson file
fill_color='YlOrRd',
fill_opacity=0.7,
line_opacity=0.4,
legend_name='Birth rate').add_to(BCN_map)
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['NOM', 'Birth_rate'],
aliases=['Neiboorhood','Birth rate']))
BCN_map
BCN_map.save("choropleth maps/birth_rate_20.html")
Life expecatancy obtained from: https://opendata-ajuntament.barcelona.cat/data/es/dataset/est-sp-esp-vida
life_expectancy = pd.read_excel("Life_expectancy.xlsx")
life_expectancy['NOM'] = renta['NOM']
for n in range(73):
data['features'][n]['properties']['Life_expectancy']= life_expectancy['Life_expectancy'].iloc[n]
life_expectancy
| Barrios | Life_expectancy | NOM | |
|---|---|---|---|
| 0 | 1 1. el Raval | 81.6 | el Raval |
| 1 | 1 2. el Barri Gòtic | 82.5 | el Barri Gòtic |
| 2 | 1 3. la Barceloneta | 80.5 | la Barceloneta |
| 3 | 1 4. Sant Pere, Santa Caterina i la Ribera | 83.5 | Sant Pere, Santa Caterina i la Ribera |
| 4 | 2 5. el Fort Pienc | 84.7 | el Fort Pienc |
| ... | ... | ... | ... |
| 68 | 10 69. Diagonal Mar i el Front Marítim del... | 85.9 | Diagonal Mar i el Front Marítim del Poblenou |
| 69 | 10 70. el Besòs i el Maresme | 84.5 | el Besòs i el Maresme |
| 70 | 10 71. Provençals del Poblenou | 85.1 | Provençals del Poblenou |
| 71 | 10 72. Sant Martí de Provençals | 85.8 | Sant Martí de Provençals |
| 72 | 10 73. la Verneda i la Pau | 84.7 | la Verneda i la Pau |
73 rows × 3 columns
life_expectancy.nsmallest(3, 'Life_expectancy')
| Barrios | Life_expectancy | NOM | |
|---|---|---|---|
| 55 | 8 56. Vallbona | 78.1 | Vallbona |
| 52 | 8 53. la Trinitat Nova | 79.6 | la Trinitat Nova |
| 11 | 3 12. la Marina del Prat Vermell - Zona Fr... | 79.8 | la Marina del Prat Vermell |
life_expectancy.nlargest(3, 'Life_expectancy')
| Barrios | Life_expectancy | NOM | |
|---|---|---|---|
| 20 | 4 21. Pedralbes | 87.7 | Pedralbes |
| 66 | 10 67. la Vila Olímpica del Poblenou | 87.4 | la Vila Olímpica del Poblenou |
| 19 | 4 20. la Maternitat i Sant Ramon | 86.7 | la Maternitat i Sant Ramon |
BCN_map = folium.Map(location=[41.39, 2.17], zoom_start=12) # in location we must add the city's coordinates
choropleth = folium.Choropleth(geo_data=data, # GeoJson Coordinates
data=life_expectancy, # The table which contains the values we are analysing
columns=['NOM', 'Life_expectancy'],
key_on='feature.properties.NOM', # We chose the key we need in the GeoJson file
fill_color='YlOrRd',
fill_opacity=0.7,
line_opacity=0.4,
legend_name='Life_expectancy').add_to(BCN_map)
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['NOM', 'Life_expectancy'],
aliases=['Neiboorhood','Life expectancy 2015-2019']))
BCN_map
BCN_map.save("choropleth maps/life_expectancy_19.html")
List of hospitals and centres of primary health service of the city of Barcelona: https://opendata-ajuntament.barcelona.cat/data/en/dataset/sanitat-hospitals-atencio-primaria
from folium.plugins import MarkerCluster
# generate the clusters of datas
hospitals = pd.read_csv("opendatabcn_sanitat_hospitals-i-centres-atencio-primaria.csv")
hospitals_cluster = folium.Map(location=[41.39, 2.17], zoom_start=12)
hospitals_cluster.add_child(MarkerCluster(hospitals[['geo_epgs_4326_x', 'geo_epgs_4326_y']], popups = hospitals['name'].tolist()))
hospitals_cluster
hospitals_cluster.save("choropleth maps/hospitals_cluster.html")