In [162]:
import os
import folium
import pandas as pd
import numpy as np
from folium import plugins
import branca.colormap as cm
from tqdm import tqdm
import matplotlib.pyplot as plt
import json

Obtain data

In [120]:
import requests
import time
response = requests.get("http://opendata.paris.fr/api/records/1.0/download/?dataset=stations-velib-disponibilites-en-temps-reel&facet=banking&facet=bonus&facet=status&facet=contract_name&rows=-1")
txt = response.text
f = open('velib.csv', 'w+')
f.write(txt)
Out[120]:
188975
In [121]:
velibs = pd.read_csv('velib.csv', sep=";")
In [122]:
velibs.head()
Out[122]:
number name address position banking bonus status contract_name bike_stands available_bike_stands available_bikes last_update
0 5106 05106 - CUJAS 22 RUE CUJAS - 75005 PARIS 48.8481913486, 2.34183165485 True False OPEN Paris 19 16 3 2017-09-14T00:08:26+00:00
1 13028 13028 - GOUTHIERE 12 RUE GOUTHIERE - 75013 PARIS 48.820507, 2.351342 True False CLOSED Paris 33 0 0 2017-09-14T12:20:31+00:00
2 14114 14114 - PLACE DE CATALOGNE 4 RUE ALAIN - 75014 PARIS 48.8372933094, 2.31748293064 True True OPEN Paris 43 0 0 2017-09-22T09:17:22+00:00
3 35007 35007 - DELESSERT (PANTIN) 1 RUE BENJAMIN DELESSERT - 93500 PANTIN 48.8939437132, 2.41802965969 True False OPEN Paris 21 4 16 2017-09-22T11:05:00+00:00
4 16001 16001 - AVENUE DES PORTUGAIS 2 AVENUE DES PORTUGAIS - 75016 PARIS 48.8712137122, 2.29369213365 True True OPEN Paris 26 10 16 2017-09-22T12:24:25+00:00
In [123]:
velibs.shape
Out[123]:
(1226, 12)
In [124]:
velibs = velibs[velibs.status == 'OPEN']
In [125]:
velibs['arron'] = velibs['address'].map(lambda x: int(x.split()[-2][3:]) if x.split()[-2][:2] == '75' else np.NaN)
In [126]:
velibs.shape
Out[126]:
(1186, 13)
In [127]:
velibs.head()
Out[127]:
number name address position banking bonus status contract_name bike_stands available_bike_stands available_bikes last_update arron
0 5106 05106 - CUJAS 22 RUE CUJAS - 75005 PARIS 48.8481913486, 2.34183165485 True False OPEN Paris 19 16 3 2017-09-14T00:08:26+00:00 5.0
2 14114 14114 - PLACE DE CATALOGNE 4 RUE ALAIN - 75014 PARIS 48.8372933094, 2.31748293064 True True OPEN Paris 43 0 0 2017-09-22T09:17:22+00:00 14.0
3 35007 35007 - DELESSERT (PANTIN) 1 RUE BENJAMIN DELESSERT - 93500 PANTIN 48.8939437132, 2.41802965969 True False OPEN Paris 21 4 16 2017-09-22T11:05:00+00:00 NaN
4 16001 16001 - AVENUE DES PORTUGAIS 2 AVENUE DES PORTUGAIS - 75016 PARIS 48.8712137122, 2.29369213365 True True OPEN Paris 26 10 16 2017-09-22T12:24:25+00:00 16.0
5 9034 09034 - GODOT DE MAUROY 2 RUE GODOT DE MAUROY - 75009 PARIS 48.8699566816, 2.32659965711 True False OPEN Paris 22 1 21 2017-09-22T12:56:20+00:00 9.0

Number of bike stands

In [135]:
bike_stands_arron = velibs.groupby('arron')['bike_stands'].sum()
plt.bar(bike_stands_arron.index.astype(int), bike_stands_arron.values)
plt.show()
In [136]:
# https://github.com/codeforamerica/click_that_hood/raw/master/public/data/paris.geojson
state_geo = r'paris.json'

m = folium.Map(location=[48.856614, 2.3522219], zoom_start=13, tiles='Stamen Toner')
m.choropleth(geo_path=state_geo, 
             data=bike_stands_arron,
             columns=['arron', 'bike_stands'],
             key_on='properties.cartodb_id',
             fill_color='PuBu', 
             fill_opacity=0.9, line_opacity=0.2,
             legend_name='Number of bike stands',
             highlight=1)
m
Out[136]:

Available bikes

In [137]:
from colour import Color
red = Color("red")
colors = list(red.range_to(Color("green").hex,10))
def red(brightness):
    brightness = int(round(9 * brightness)) # convert from 0.0-1.0 to 0-255
    return colors[brightness]
In [138]:
red(0).hex
Out[138]:
'#f00'
In [139]:
velibs['lat'] = velibs['position'].apply(lambda x: float(x.split(",")[0]))
velibs['long'] = velibs['position'].apply(lambda x: float(x.split(",")[1]))
velibs['color'] = velibs.apply(lambda x: red(x['available_bikes']/float(x['bike_stands'])).hex, axis=1)
In [140]:
m = folium.Map(location=[48.856614, 2.3522219], zoom_start=13, tiles='Stamen Toner')

m.add_child(plugins.HeatMap(velibs[['lat','long', 'available_bikes']].values, radius = 20), name='Training location')
colormap = cm.LinearColormap(['blue', 'green',  'yellow', 'orange', 'red'],  index=[0, 0.25, 0.5, 0.75, 1.0]).scale(0,200)
colormap.caption = 'Number of velibs'
m.add_child(colormap)
m
Out[140]:
In [141]:
m = folium.Map(location=[48.856614, 2.3522219], zoom_start=13, tiles='Stamen Toner')

for k,v in velibs.iterrows():
    folium.CircleMarker(location=[v.position.split(",")[0], v.position.split(",")[1]], 
                        fill_color=red(v.available_bikes/float(v.bike_stands)).hex,
                        popup= str(v.available_bikes) + " / " + str(v.bike_stands),
                        radius=7).add_to(m)
In [19]:
m
Out[19]: