Skip to main content

Mapping the World's Earthquakes with Python — A Beginner's Data Project

Copy of Interactive map of one month's earthquake data, plotted by magnitude. The Pacific Ring of Fire jumps out immediately.

The Earth is restless. In any given month, earthquakes rattle the planet — most too small to feel, but all carefully recorded by sensors around the globe. What if you could pull all of that data into Python and put it on a map in minutes? That is exactly what this project does.


There is something compelling about real, live data. It is one thing to practise Python with made-up lists and fictional datasets; it is another to write a handful of lines of code and get back information about actual geological events happening right now. This project is a great entry point into the world of APIs — the digital doorways that let your programs reach out to the internet and bring back structured information.

We are going to pull a month's worth of earthquake data from the US Geological Survey (USGS), load it into a Python DataFrame, and then plot it on an interactive map. No specialist hardware required — just Python and curiosity.

💡 This project was inspired by the "Fetching Current Weather Data" chapter in Automate the Boring Stuff with Python by Al Sweigart — a book well worth having on your shelf.

The full code is on GitHub: https://github.com/scottturneruon/earthquake.git


What is an API, and why does it matter here?

An Application Programming Interface (API) is a way for programs to talk to each other. In this case, the USGS provides a public API that serves up earthquake data as a JSON file — a structured text format that Python handles beautifully. You give the API a URL; it sends back data. No web scraping, no guesswork.

The USGS feed we are using covers all recorded earthquakes in the past 30 days. You can read more about the USGS and their data here: https://www.usgs.gov/about/about-us/who-we-are


What you will need

Before running the code, install the required libraries. You can drop these lines at the top of a Jupyter notebook cell and run them once:

!pip install plotly
!pip install geopandas
!pip install shapely
!pip install folium mapclassify

These give us the tools to handle geographic data and draw maps. The main libraries in play are:

  • requests — to fetch data from the USGS URL
  • json — to decode the response
  • pandas / json_normalize — to wrangle the nested JSON into a tidy table
  • geopandas, shapely, folium — to turn coordinates into map plots

Step 1: Fetching the data

The first section sets up the URL pointing to the USGS earthquake feed and makes a request to it:

import json, requests
import pandas as pd
from pandas import json_normalize

url = 'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson'

response = requests.get(url)
response.raise_for_status()

raise_for_status() is a useful safety net — if the request fails for any reason (no internet, server down), it will throw an error immediately rather than silently returning empty data. Good to include.


Step 2: Loading and normalising the JSON

The USGS response is formatted in JSON, but it is nested JSON — data within data within data. The json_normalize function flattens it out into a standard pandas DataFrame (see DataFrame for more details), with each earthquake as a row:

quakeData = json.loads(response.text)
df = json_normalize(quakeData['features'])

Once this runs, df holds a table with columns for things like magnitude, location description, time, and — crucially — coordinates. If you add df.head() after; you can see some of the entries.

Output of the first few earhquakes from the API


Step 3: Extracting coordinates and building a GeoDataFrame

The coordinates come back as a list of three numbers (longitude, latitude, depth). To plot them on a map, we need to split them out and convert them into geometry objects that geopandas understands:

from shapely.geometry import Point
from geopandas import GeoDataFrame

df['lon'] = pd.DataFrame(df['geometry.coordinates'].tolist())[0]
df['lat'] = pd.DataFrame(df['geometry.coordinates'].tolist())[1]

geometry = [Point(xy) for xy in zip(df.lon, df.lat)]
df = df.drop(['lon', 'lat'], axis=1)

gdf = GeoDataFrame(df, crs="EPSG:4326", geometry=geometry)

The EPSG:4326 part tells geopandas we are using standard latitude/longitude coordinates (the WGS84 system used by GPS). A GeoDataFrame is essentially a pandas DataFrame with an extra superpower: it knows about shapes and geography.


Step 4: Plotting the maps

Now for the satisfying part — drawing the results. There are two approaches here.

A simple static plot — quick and clean, coloured by magnitude:

gdf.plot("properties.mag", legend=True)

map showing earhquake locations but with the underlying map underneach

An interactive map using Folium — this one you can pan and zoom in a Jupyter notebook:

gdf.explore("properties.mag", legend=True)

Copy of Interactive map of one month's earthquake data, plotted by magnitude. The Pacific Ring of Fire jumps out immediately.



There is an interactive version, which you can see when you run the code (image above is a screenshot of it), it impressed me the first time I saw it — hover over any dot and you get the earthquake's details right there. It is a great reminder of just how active our planet is.


Where to go next

This project is a solid foundation, and there is plenty of room to take it further:

  • Filter by magnitude — use pandas to keep only earthquakes above a certain size (e.g. magnitude 4.0+) and see how the map changes
  • Add time-based analysis — the data includes timestamps; you could plot earthquakes by day of the month and look for any patterns
  • Compare feeds — the USGS offers different feeds (significant earthquakes only, 4.5+, etc.). Swap the URL and see the difference instantly
  • Connect it to a Raspberry Pi or micro:bit display — trigger an LED or a buzzer whenever a significant earthquake appears in the live feed. Now that would make for a genuinely interesting physical computing project
  • Chart the magnitude distribution — a simple histogram with matplotlib would tell you a lot about how earthquake sizes are distributed

The full code is available at: https://github.com/scottturneruon/earthquake.git

The USGS API is free, public, and updates regularly — meaning every time you run this code, you are looking at fresh data from the real world. That, to me, is what makes projects like this worth doing.


Have you tried this project or built something similar? Drop a comment below — I'd love to see where you take it.


All opinions in this blog are the Author's and should not in any way be seen as reflecting the views of any organisation the Author has any association with. Twitter @scottturneruon

Comments

Popular posts from this blog

Robot Software

In the previous blog posts for this 'series' "It is a good time...."  Post 1  looked at the hardware unpinning some of this positive rise in robots; Post 2  looked at social robots; Post 3  looked at a collection of small robots; Post 4 looked at further examples of small robots Robots, such as the forthcoming Buddy and JIBO, will be based some established open sourceand other technologies. Jibo will be based around various technologies including Electron and JavaScript (for more details see:  http://blog.jibo.com/2015/07/29/jibo-making-development-readily-accessible-to-all-developers/ ). Buddy is expected to be developed around tools for Unity3d, Arduino and OpenCV, and support Python, C++, C#, Java and JavaScript (for more details see http://www.roboticstrends.com/article/customize_your_buddy_companion_robot_with_this_software_development_kit ).  This post contin ues with some of the software being used with the smaller robots.  A number ...

Speech Recognition in Scratch 3 - turning Hello into Bonjour!

The Raspberry Pi Foundation recently released a programming activity Alien Language , with support Dale from Machine Learning for Kids , that is a brilliant use of Scratch 3 - Speech Recognition to control a sprite in an alien language. Do the activity, and it is very much worth doing, and it will make sense! I  would also recommend going to the  machinelearningforkids.co.uk   site anyway it is full of exciting things to do (for example loads of activities  https://machinelearningforkids.co.uk/#!/worksheets  ) . Scratch 3 has lots of extensions that are accessible through the Extension button in the Scratch 3 editor (see below) which add new fun new blocks to play with. The critical thing for this post is  Machine Learning for Kids  have created a Scratch 3 template with their own extensions for Scratch 3 within it  https://machinelearningforkids.co.uk/scratch3/ . One of which is a Speech to Text extension (see below). You must use this one ...

Scratch and web-cams in Scratch 3

Scratch 3 was launched on 2nd January 2019, so I wanted to know would Webcams still work with Scratch 3 as it did with Scratch 2. For example, in a previous post  Scratch, webcams, cats and explosions  the cat (Scratch) moved across the screen and a button burst when the object moved in the camera onto it.  Can the same thing be done in Scratch 3? The short answer is yes, but it is done slightly differently. The first change the video capture is not there in the blocks automatically; but is an extension that needs to be added. First, you need to add the extension blocks for video sensing. Go to the little icon at the bottom left of the screen (as shown below) this takes you to the extensions menu. Next, find the Video Sensing option and selected. The webcam, if enabled, with start automatically. A video sensing set of blocks is now in the list of block options.  The rest is very similar to doing this in Scratch 2. Moving ...