A custom HURDAT2 data parser.
Project description
hurdat2py is a research-focused Python interface for the NOAA HURDAT2 Dataset. It automates data retrieval and parsing, giving you immediate access to clean, analysis-ready data.
Table of Contents
Installation
pip install hurdat2py
Quick Start
1. Initialize the Database
- You can specify a path to a local download of the Hurdat2 dataset.
import hurdat2py
hd2 = hurdat2py.Hurdat2("path_to_file.txt")
- If no path is specified, it will automatically download the latest data from https://www.nhc.noaa.gov/data/hurdat/ (~7MB) and save it locally.
- Note: The cached file will be overwritten after 30 days to ensure the latest file is available.
import hurdat2py
# Initialize for Atlantic (default)
hd2_atl = hurdat2py.Hurdat2()
# Initialize for Northeast/Central Pacific
hd2_pac = hurdat2py.Hurdat2(basin='nepac')
2. Create Storm or Season objects
- Allows for easy access to storm or season data.
# Storm obect:
storm = hd2['bob', 1991]
# or
storm = hd2['al031991']
# Season object:
season = hd2[1991]
- See The Storm Object or The Season Object for more info.
API Reference
1. The Database (Hurdat2)
The main entry point. Handles downloading, caching, and parsing the raw text data.
| Method | Description | Example |
|---|---|---|
hurdat2py.Hurdat2() |
Initializes the database. Downloads latest available data if local cache is missing/expired. Kwargs: basin ( 'atl' or 'nepac') Specifies which HURDAT2 database to load. Default is 'atl'. |
hd2 = hurdat2py.Hurdat2(basin='nepac') |
db['name', year] |
Get Storm (by Name)*. Returns a Storm object. Case-insensitive. *This method will not work for storms named UNNAMED. |
storm = hd2['bob', 1991] |
db[atcfid] |
Get Storm (by ID). Returns a Storm object using ATCFID. |
storm = hd2['al031991'] |
db[year] |
Get Season. Returns a Season object for the specified year. |
season = hd2[1991] |
rank_seasons_by_ace() |
Returns a sorted list of seasons by Accumulated Cyclone Energy (float). |
top5 = hd2.rank_seasons_by_ace()[:5] |
2. The Storm Object
Represents a single tropical cyclone.
| Method/Attribute | Description | Example |
|---|---|---|
name |
Operational name (e.g., "Bob") (str). |
print(storm.name) |
atcfid |
ATCF ID (e.g., "AL031991") (str). |
print(storm.atcfid) |
year |
The year the storm formed (int). |
print(storm.year) |
ace |
Accumulated Cyclone Energy (10^-4 kn^2) (float). |
print(storm.ace) |
peak_wind |
Maximum sustained wind speed (knots) (int). |
print(storm.peak_wind) |
peak_status |
Highest tropical classification the storm achieved (MH, HU, TS, SS, TD, SD) (str). |
print(storm.peak_status) |
min_pressure |
Minimum central pressure (mb) (int). |
print(storm.min_pressure) |
landfalls |
Number of landfalls recorded* (int). *Note: not every landfall is recorded in the Hurdat2 dataset. |
print(storm.landfalls) |
lats/lons |
Raw list of latitude/longitude points. | ax.plot(storm.lons, storm.lats) |
duration_total duration_tc duration_ts duration_hurricane duration_major |
Duration of the system in hours, while at specified status (float) |
print(storm.duration_tc) |
distance_total distance_tc distance_ts distance_hurricane distance_major |
Distance* the system travelled in Nautical Miles, while at specified status (float) *Note: Distances calculated using the Haversine Formula. |
print(storm.distance_major) |
info() |
Prints quick overview of the storm. | storm.info() |
stats() |
Prints statistics and detailed information about the storm. | storm.stats() |
plot() |
Plots storm track, colored by Saffir-Simpson intensity. Plot aesthetic is inspired by the tropycal package. | storm.plot() |
plot_intensity() |
Plots the storm's windspeed over time, colored by Saffir-Simpson intensity. Kwargs: zoom ( bool) Crops into the intensity curve. landfalls ( bool) Plots landfall times on intensity curve. |
storm.plot_intensity(zoom=True, landfalls=False) |
to_dataframe() |
Exports track data (date, time, lat, lon, wind, pressure) to a Pandas DataFrame. | df = storm.to_dataframe() |
3. The Season Object
Represents a full year of activity.
| Method/Attribute | Description | Example |
|---|---|---|
year |
Returns the year of the season (int) |
print(season.year) |
storms |
List of Storm objects within the season. |
print(season.storms) |
total_storms |
Number of storms in the season (int). Effectively len(season.storms) |
print(season_total_storms) |
tropical_storms |
Number of tropical storms in the season (int). |
print(season.tropical_storms) |
hurricanes |
Number of hurricanes in the season (int). |
print(season.hurricanes) |
major_hurricanes |
Number of major hurricanes in the season (int). |
print(season.major_hurricanes) |
ace |
Total Accumulated Cyclone Energy for the season (float). |
print(season.ace) |
stats() |
Prints statistics and detailed information about the season. | season.stats() |
plot() |
Plots all storm tracks for the season, colored by Saffir-Simpson intensity. Plot aesthetic is inspired by the tropycal package. Kwargs: labels ( bool) Adds labels for each storm track. |
season.plot(labels=True) |
to_dataframe() |
Exports track data (date, time, lat, lon, wind, pressure) for all storms in the season to a Pandas DataFrame. | df = season.to_dataframe() |
Roadmap
Future planned updates:
- Statistics Improvements: Implement new statistics functionality for
StormandSeasonobjects.- Expected: Summer 2026
- Improved Plotting Functionality: Add/improve plotting functions.
- Expected: Summer 2026
- Wind Radius Implementation: Add support for and methods utilizing wind radius data included with modern records in the Hurdat2 dataset.
- Expected: Summer 2027
Changelog
See CHANGELOG.md file for the full version history.
Attribution & Data Sources
Data
- This package processes data from the National Hurricane Center (NHC) HURDAT2 Database.
- Landsea, C. W. and J. L. Franklin, 2013: Atlantic Hurricane Database Uncertainty and Presentation of a New Database Format. Mon. Wea. Rev., 141, 3576-3592.
Acknowledgements
-
Inspiration: This work was inspired by the great hurdat2parser package. There are many technical capabilities of hurdat2parser that we do not seek to replicate. We recommend you choose whichever package best suites your needs.
-
Plotting Style: The map visualization aesthetic in this package was inspired by the excellent tropycal package. While
hurdat2pyis a standalone implementation, we aimed to match their clear, publication-ready visual style.
License
MIT License. See LICENSE file for details.
Disclaimer
hurdat2py is maintained for personal research and is not an official NOAA product.
Python® and the Python logo are registered trademarks of the Python Software Foundation. hurdat2py is an independent open-source project and is not affiliated with or endorsed by the Python Software Foundation.
Copyright
hurdat2py
Copyright © 2026 Andy McKeen
License: MIT
GitHub: https://github.com/andy-theia/hurdat2py
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hurdat2py-0.3.6.tar.gz.
File metadata
- Download URL: hurdat2py-0.3.6.tar.gz
- Upload date:
- Size: 19.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7024d5d53978a98a5f60b304a7b5515e220cec2c190a8074f2f4575acb232808
|
|
| MD5 |
0ad8939959c79bc5bf69a6f933c66a12
|
|
| BLAKE2b-256 |
43f560f48ecb67c16b96f51ce69933c753c90aa8f97136e2c0c7e6db4f932606
|
File details
Details for the file hurdat2py-0.3.6-py3-none-any.whl.
File metadata
- Download URL: hurdat2py-0.3.6-py3-none-any.whl
- Upload date:
- Size: 17.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
749e7e2b455c3e4f0d01bd029439feff875e885892f00720f017a459a16dab28
|
|
| MD5 |
df83c5fc0253e9326d0e155126c77b8e
|
|
| BLAKE2b-256 |
94e1cb3af88ac0c4a19efde9ce7ca1b0a668b77d138dc4b6f6800e1255ef17e9
|