Mapping location of air quality sensing in India

In this notebook, I'll show a quick example of how to use Folium (which internally uses LeafletJS) for visualising the location of air quality monitors in India. The purpose of this notebook is eductional in nature.

Standard Imports

In [1]:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
%matplotlib inline

Downloading data from OpenAQ for 2018-04-06

In [2]:
!wget --no-check-certificate https://openaq-data.s3.amazonaws.com/2018-04-06.csv -P /Users/nipun/Downloads/
--2018-06-21 18:13:34--  https://openaq-data.s3.amazonaws.com/2018-04-06.csv
Resolving openaq-data.s3.amazonaws.com (openaq-data.s3.amazonaws.com)... 52.216.83.40
Connecting to openaq-data.s3.amazonaws.com (openaq-data.s3.amazonaws.com)|52.216.83.40|:443... connected.
WARNING: cannot verify openaq-data.s3.amazonaws.com's certificate, issued by ‘CN=DigiCert Baltimore CA-2 G2,OU=www.digicert.com,O=DigiCert Inc,C=US’:
  Unable to locally verify the issuer's authority.
HTTP request sent, awaiting response... 200 OK
Length: 133839107 (128M) [text/csv]
Saving to: ‘/Users/nipun/Downloads/2018-04-06.csv’

2018-04-06.csv      100%[===================>] 127.64M  1.29MB/s    in 3m 25s  

2018-06-21 18:17:02 (637 KB/s) - ‘/Users/nipun/Downloads/2018-04-06.csv’ saved [133839107/133839107]

In [3]:
import pandas as pd
df = pd.read_csv("/Users/nipun/Downloads/2018-04-06.csv")
df = df[(df.country=='IN')&(df.parameter=='pm25')].dropna().groupby("location").mean()
In [4]:
df
Out[4]:
value latitude longitude
location
Adarsh Nagar, Jaipur - RSPCB 79.916667 26.902909 75.836853
Anand Kala Kshetram, Rajamahendravaram - APPCB 42.750000 16.987287 81.736318
Ardhali Bazar, Varanasi - UPPCB 103.666667 25.350599 82.908307
Asanol Court Area, Asanol - WBPCB 56.833333 23.685297 86.945968
Ashok Nagar, Udaipur - RSPCB 114.750000 24.588617 73.632140
Bandra, Mumbai - MPCB 60.000000 19.041847 72.865513
Bhopal Chauraha, Dewas - MPPCB 159.416667 22.968259 76.064118
Bollaram Industrial Area, Hyderabad - TSPCB 62.400000 17.540891 78.358528
Burari Crossing, New Delhi - IMD 245.583333 28.725650 77.201157
CRRI Mathura Road, New Delhi - IMD 265.666667 28.551200 77.273574
Central School, Lucknow - CPCB 116.166667 26.882100 80.930275
Central University, Hyderabad - TSPCB 66.500000 17.460103 78.334361
Chandrapur, Chandrapur - MPCB 68.000000 19.645324 77.634523
Civil Line, Jalandhar - PPCB 135.833333 31.321907 75.578914
Collectorate, Jodhpur - RSPCB 321.750000 26.268249 73.019385
DTU, New Delhi - CPCB 214.333333 28.750050 77.111261
GM Office, Brajrajnagar - OSPCB 97.166667 21.800500 83.839698
GVM Corporation, Visakhapatnam - APPCB 57.416667 17.720000 83.300000
Gangapur Road, Nashik - MPCB 127.750000 20.007328 73.776243
Golden Temple, Amritsar - PPCB 83.000000 31.620000 74.876512
ICRISAT Patancheru, Hyderabad - TSPCB 69.166667 17.434236 78.417032
IDA Pashamylaram, Hyderabad - TSPCB 66.083333 17.531689 78.218939
IGI Airport Terminal - 3, New Delhi - IMD 130.666667 28.562776 77.118005
IGSC Planetarium Complex, Patna - BSPCB 134.833333 25.594100 85.137600
IHBAS, Dilshad Garden,New Delhi - CPCB 212.583333 28.680275 77.201157
IIT, Chennai - CPCB 37.333333 13.005219 80.239812
ITO, New Delhi - CPCB 220.500000 28.631694 77.249439
Indira Colony Vistar, Pali - RSPCB 206.250000 25.771061 73.340227
Karve Road Pune, Pune - MPCB 138.416667 18.501174 73.816553
Lajpat Nagar, Moradabad - UPPCB 105.800000 28.825341 78.721301
... ... ... ...
Punjab Agricultural University, Ludhiana - PPCB 82.666667 30.902800 75.808600
Pusa, New Delhi - IMD 112.000000 28.610304 77.099694
R K Puram, New Delhi - DPCC 103.600000 28.564610 77.167010
RIICO Ind. Area III, Bhiwadi, Rajasthan - RSPCB 340.500000 28.194909 76.862296
RIMT University, Mandi Gobindgarh - PPCB 132.750000 30.649961 76.331442
Sanathnagar, Hyderabad - TSPCB 90.333333 17.455946 78.433215
Sanjay Palace, Agra - UPPCB 166.666667 27.198658 78.005981
Secretariat, Amaravati - APPCB 47.200000 16.515083 80.518167
Sector - 125, Noida, UP - UPPCB 84.400000 28.544761 77.323126
Sector - 62, Noida, UP - IMD 154.416667 28.624548 77.357710
Sector- 16A, Faridabad, Haryana - HSPCB 264.250000 28.408842 77.309908
Sector-2 Industrial Area, Pithampur - MPPCB 101.166667 22.624758 75.675238
Sector-6, Panchkula - HSPCB 96.416667 30.705778 76.853181
Sector-D Industrial Area, Mandideep - MPPCB 125.416667 23.108440 77.511428
Shadipur, New Delhi - CPCB 213.833333 28.651478 77.147311
Shastri Nagar, Jaipur - RSPCB 100.083333 26.950293 75.730943
Shrinath Puram, Kota - RSPCB 120.916667 25.143890 75.821256
Sirifort, New Delhi - CPCB 222.250000 28.550425 77.215938
Talkatora District Industries Center, Lucknow - CPCB 163.833333 26.833997 80.891736
Tirumala, Tirupati - APPCB 52.833333 13.670000 79.350000
US Diplomatic Post: Chennai 19.958333 13.087840 80.278470
US Diplomatic Post: Hyderabad 55.458333 17.384050 78.456360
US Diplomatic Post: Kolkata 48.458333 22.562630 88.363040
US Diplomatic Post: Mumbai -165.083333 19.072830 72.882610
US Diplomatic Post: New Delhi 46.625000 28.635760 77.224450
Vasundhara, Ghaziabad, UP - UPPCB 223.333333 28.660335 77.357256
Vikas Sadan, Gurgaon, Haryana - HSPCB 280.250000 28.450124 77.026305
Vindhyachal STPS, Singrauli - MPPCB 144.000000 24.108970 82.645580
Ward-32 Bapupara, Siliguri - WBPCB 195.000000 26.688305 88.412668
Zoo Park, Hyderabad - TSPCB 82.500000 17.349694 78.451437

79 rows × 3 columns

Downloading World GeoJson file

In [6]:
!wget --no-check-certificate https://raw.githubusercontent.com/python-visualization/folium/master/examples/data/world-countries.json
--2018-06-21 18:18:42--  https://raw.githubusercontent.com/python-visualization/folium/master/examples/data/world-countries.json
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.36.133
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.36.133|:443... connected.
WARNING: cannot verify raw.githubusercontent.com's certificate, issued by ‘CN=DigiCert SHA2 High Assurance Server CA,OU=www.digicert.com,O=DigiCert Inc,C=US’:
  Unable to locally verify the issuer's authority.
HTTP request sent, awaiting response... 200 OK
Length: 252515 (247K) [text/plain]
Saving to: ‘world-countries.json’

world-countries.jso 100%[===================>] 246.60K   161KB/s    in 1.5s    

2018-06-21 18:18:45 (161 KB/s) - ‘world-countries.json’ saved [252515/252515]

Creating india.json correspdonding to Indian data

In [7]:
import json
e = json.load(open('world-countries.json','r'))
json.dump(e['features'][73], open('india.json','w'))
In [8]:
import folium

folium_map = folium.Map(width = '60%',height=800,location=[20, 77],
                        zoom_start=5,
                        tiles="Stamen Terrain",min_lat=7, max_lat=35, min_lon=73, max_lon=90)
for x in df.iterrows():
    name = x[0]
    lat, lon = x[1]['latitude'], x[1]['longitude']
    folium.CircleMarker([lat, lon], radius=5, color='#000000',fill_color='#D3D3D3' , fill_opacity=1).add_to(folium_map)

folium.GeoJson('india.json').add_to(folium_map)
folium_map
Out[8]:

There you go!