# Python 3.5+ only!
import asyncio
from aiohttp import ClientSession
import json, geojson, os, time
import pandas as pd
from datetime import datetime, timedelta
from mapboxgl.viz import *
from mapboxgl.utils import *
# Get Data from the USGS API
data = []
async def fetch(url, headers, params, session):
async with session.get(url, headers=headers, params=params) as resp:
tempdata = await resp.json()
data.append(tempdata)
return tempdata
async def bound_fetch(sem, url, headers, params, session):
# Getter function with semaphore.
async with sem:
await fetch(url, headers, params, session)
async def get_quakes(param_list, headers):
# Store tasks to run
tasks = []
# create instance of Semaphore
sem = asyncio.Semaphore(1000)
# Generate URL from parameters
endpoint = '/query'
url = '{base_url}{endpoint}'.format(base_url=base_url, endpoint=endpoint)
async with ClientSession() as session:
for i in range(len(param_list)):
task = asyncio.ensure_future(bound_fetch(sem, url, headers, param_list[i], session))
tasks.append(task)
responses = await asyncio.gather(*tasks)
return responses
def create_params(starttime, endtime, minmagnitude):
return {
'format': 'geojson',
'starttime': starttime,
'endtime': endtime,
'minmagnitude': minmagnitude
}
# Default parameters
base_url = 'https://earthquake.usgs.gov/fdsnws/event/1'
HEADERS = {
'user-agent': ('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) '
'AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/45.0.2454.101 Safari/537.36'),
}
# Make a list of data to get in a date range
api_args = []
startdate = '2012-01-01'
date = datetime.strptime(startdate, "%Y-%m-%d")
for i in range(1000):
low = datetime.strftime(date + timedelta(days=i*10), "%Y-%m-%d")
high = datetime.strftime(date + timedelta(days=(i+1)*10), "%Y-%m-%d")
api_args.append(create_params(low, high, 2))
#Run api queries for all queries generated
loop = asyncio.get_event_loop()
future = asyncio.ensure_future(get_quakes(api_args, HEADERS))
temp = loop.run_until_complete(future)
#Collect results into a Pandas dataframe
keep_props = ['felt', 'mag', 'magType', 'place', 'time', 'tsunami', 'longitude', 'latitude']
df = pd.DataFrame(columns=keep_props, index=[0])
features = []
for fc in data:
for f in fc['features']:
feature = {}
for k in f['properties']:
if k in keep_props:
feature[k] = f['properties'][k]
feature['longitude'] = f['geometry']['coordinates'][0]
feature['latitude'] = f['geometry']['coordinates'][1]
feature['timestamp'] = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(feature['time']/1000))
features.append(feature)
df = pd.DataFrame.from_dict(features)
print(df.shape)
df.head(1)
(198772, 9)
felt | latitude | longitude | mag | magType | place | time | timestamp | tsunami | |
---|---|---|---|---|---|---|---|---|---|
0 | NaN | -17.861 | -178.639 | 5.0 | mb | Fiji region | 1329694388230 | 2012-02-19 15:33:08 | 0 |
Set a MAPBOX_ACCESS_TOKEN environment variable, or copy your token to use this notebook.
If you do not have a Mapbox access token, sign up for an account at https://www.mapbox.com/
If you already have an account, you can grab your token at https://www.mapbox.com/account/
token = os.getenv('MAPBOX_ACCESS_TOKEN')
# Generate a geojson file from the dataframe
df_to_geojson(df, filename='points.geojson', precision=4, lon='longitude', lat='latitude',
properties=['mag','timestamp'])
{'feature_count': 198772, 'filename': 'points.geojson', 'type': 'file'}
# Create a graduated circle visualization using quantile breaks and a custom color palette
measure = 'mag'
color_palette = ['#66C3F9','#88A8E4','#9C8DC9','#A474A8','#A25E87','#974B66','#853D49','#6F3230']
color_breaks = [round(df[measure].quantile(q=x*0.1), 2) for x in range(3,11)]
color_stops = create_color_stops(color_breaks, colors=color_palette)
radius_breaks = [round(df[measure].quantile(q=x*0.1), 2) for x in range(3,11)]
radius_stops = create_radius_stops(radius_breaks, 1, 10)
viz = GraduatedCircleViz('https://dl.dropbox.com/s/h4xjjlc9ggnr88b/earthquake-points-180223.geojson', #'points.geojson',
color_property = measure,
color_stops = color_stops,
radius_property = measure,
radius_stops = radius_stops,
opacity=0.75,
below_layer='waterway-label',
zoom=2,
center= [-95, 37],
access_token=token)
viz.show()