Access and analyze historical weather and climate data with Python.
—
The Stations class provides comprehensive functionality for selecting and filtering weather stations from the global Meteostat network. It enables location-based queries, regional filtering, inventory checks, and distance-based sorting.
Load the complete database of weather stations worldwide. The constructor automatically fetches and caches the station list.
class Stations:
def __init__(self) -> None:
"""
Initialize with all available weather stations.
Automatically loads and caches the global station database.
"""Find weather stations near a specific geographic location, optionally filtered by maximum distance radius.
def nearby(self, lat: float, lon: float, radius: int = None) -> "Stations":
"""
Filter and sort stations by distance from coordinates.
Parameters:
- lat: float, latitude in decimal degrees
- lon: float, longitude in decimal degrees
- radius: int, optional maximum distance in meters
Returns:
Stations object with filtered and distance-sorted stations
"""Filter stations by country and optionally by state/region using ISO country codes and regional identifiers.
def region(self, country: str, state: str = None) -> "Stations":
"""
Filter stations by country and optional state/region.
Parameters:
- country: str, ISO country code (e.g., 'US', 'CA', 'DE')
- state: str, optional state/region code
Returns:
Stations object filtered by geographic region
"""Select stations within rectangular geographical boundaries defined by top-left and bottom-right coordinates.
def bounds(self, top_left: tuple, bottom_right: tuple) -> "Stations":
"""
Filter stations within geographical boundaries.
Parameters:
- top_left: tuple, (latitude, longitude) of northwest corner
- bottom_right: tuple, (latitude, longitude) of southeast corner
Returns:
Stations object with stations within specified bounds
"""Filter stations based on data availability for specific time periods and measurement frequencies.
def inventory(self, freq: str, required: Union[datetime, tuple, bool] = True) -> "Stations":
"""
Filter stations by data inventory availability.
Parameters:
- freq: str, data frequency ('hourly', 'daily', 'monthly')
- required: Union[datetime, tuple, bool]
- True: require any data at specified frequency
- datetime: require data on specific date
- tuple: require data across entire period (start, end)
Returns:
Stations object with stations having required data availability
"""Apply unit conversions to station metadata (elevation, coordinates).
def convert(self, units: dict) -> "Stations":
"""
Convert station metadata to different units.
Parameters:
- units: dict, mapping of column names to conversion functions
e.g., {'elevation': units.feet, 'distance': units.feet}
Returns:
Stations object with converted units
"""Access the filtered station data as pandas DataFrames with optional sampling and limiting.
def count(self) -> int:
"""
Return number of stations in current selection.
Returns:
int, count of selected stations
"""
def fetch(self, limit: int = None, sample: bool = False) -> pd.DataFrame:
"""
Fetch station data as DataFrame.
Parameters:
- limit: int, optional maximum number of stations to return
- sample: bool, whether to randomly sample when limiting
Returns:
pandas.DataFrame with station metadata and availability information
"""
def clear_cache(self):
"""Clear cached station data files."""from meteostat import Stations
# Get stations within 50km of New York City
stations = Stations()
stations = stations.nearby(40.7128, -74.0060, 50000)
# Get the 10 closest stations
nearby_stations = stations.fetch(10)
print(nearby_stations[['name', 'distance', 'elevation']])# Get all stations in Germany
german_stations = Stations().region('DE')
# Get stations in California, USA
ca_stations = Stations().region('US', 'CA')
print(f"German stations: {german_stations.count()}")
print(f"California stations: {ca_stations.count()}")from datetime import datetime
# Find stations with daily data for 2020
start = datetime(2020, 1, 1)
end = datetime(2020, 12, 31)
stations_with_data = Stations().nearby(51.5074, -0.1278).inventory('daily', (start, end))
print(f"Stations with 2020 daily data: {stations_with_data.count()}")The DataFrame returned by fetch() contains the following columns:
# Station identification
id: str # Unique station identifier
name: str # Station name
wmo: str # WMO station ID (if available)
icao: str # ICAO station code (if available)
# Geographic information
latitude: float # Latitude in decimal degrees
longitude: float # Longitude in decimal degrees
elevation: float # Elevation in meters above sea level
timezone: str # IANA timezone identifier
country: str # ISO country code
region: str # State/region code
# Data availability periods
hourly_start: datetime # First available hourly observation
hourly_end: datetime # Last available hourly observation
daily_start: datetime # First available daily observation
daily_end: datetime # Last available daily observation
monthly_start: datetime # First available monthly observation
monthly_end: datetime # Last available monthly observation
# Computed fields (when using nearby())
distance: float # Distance from query point in meters (when using nearby())Install with Tessl CLI
npx tessl i tessl/pypi-meteostat