Access and analyze historical weather and climate data with Python.
—
The Daily class provides access to daily weather summaries including temperature extremes, precipitation totals, wind averages, and sunshine duration. Historical daily data is available from 1781 for some locations, making it ideal for long-term climate analysis.
Create a daily time series for weather stations or geographic points with comprehensive historical coverage.
class Daily:
def __init__(self, loc: Union[pd.DataFrame, Point, list, str], start=datetime(1781, 1, 1, 0, 0, 0), end=datetime.combine(datetime.today().date() + timedelta(days=10), datetime.max.time()), model=True, flags=False) -> None:
"""
Initialize daily weather data retrieval.
Parameters:
- loc: Union[pd.DataFrame, Point, list, str]
- pd.DataFrame: Station data from Stations.fetch()
- Point: Geographic point for automatic station selection
- list: List of station IDs
- str: Single station ID
- start: datetime, start of time period (default: 1781-01-01)
- end: datetime, end of time period (default: 10 days from today)
- model: bool, whether to include model/reanalysis data (default: True)
- flags: bool, whether to include data source flags (default: False)
"""Calculate expected number of daily observations for the defined time period.
def expected_rows(self) -> int:
"""
Return expected number of daily rows for the date range.
Returns:
int, expected number of daily observations
"""Daily data includes the following aggregated meteorological parameters:
# Temperature measurements (°C)
tavg: float # Average temperature
tmin: float # Minimum temperature
tmax: float # Maximum temperature
# Precipitation
prcp: float # Total precipitation amount (mm)
# Snow and winter weather
snow: float # Snow depth (mm)
# Wind measurements
wdir: float # Prevailing wind direction (degrees, 0-360)
wspd: float # Average wind speed (km/h)
wpgt: float # Peak wind gust (km/h)
# Atmospheric pressure
pres: float # Average sea level pressure (hPa)
# Solar radiation
tsun: float # Total sunshine duration (minutes)
# Data quality flags (when flags=True)
tavg_flag: str # Average temperature data source flag
tmin_flag: str # Minimum temperature data source flag
tmax_flag: str # Maximum temperature data source flag
# ... (additional _flag columns for each parameter)from datetime import datetime
from meteostat import Point, Daily
# Set time period for 2020
start = datetime(2020, 1, 1)
end = datetime(2020, 12, 31)
# Create point for London, UK
london = Point(51.5074, -0.1278, 11)
# Get daily data
data = Daily(london, start, end)
daily_data = data.fetch()
print(f"Retrieved {len(daily_data)} daily observations")
print(daily_data[['tavg', 'tmin', 'tmax', 'prcp']].head())from datetime import datetime
from meteostat import Stations, Daily
# Get stations with long historical records
stations = Stations().region('GB').inventory('daily', True).fetch(5)
# Analyze temperature trends over 50 years
start = datetime(1970, 1, 1)
end = datetime(2020, 12, 31)
data = Daily(stations, start, end)
historical_data = data.fetch()
# Calculate annual averages
annual_temps = historical_data.groupby(historical_data.index.year)['tavg'].mean()
print("50-year temperature trend:")
print(annual_temps.head(10))from datetime import datetime
from meteostat import Point, Daily
import pandas as pd
# Analyze seasonal patterns for Chicago
chicago = Point(41.8781, -87.6298, 182)
# Get 10 years of data
start = datetime(2010, 1, 1)
end = datetime(2019, 12, 31)
data = Daily(chicago, start, end)
daily_data = data.fetch()
# Calculate seasonal averages
daily_data['season'] = daily_data.index.month.map({
12: 'Winter', 1: 'Winter', 2: 'Winter',
3: 'Spring', 4: 'Spring', 5: 'Spring',
6: 'Summer', 7: 'Summer', 8: 'Summer',
9: 'Fall', 10: 'Fall', 11: 'Fall'
})
seasonal_stats = daily_data.groupby('season').agg({
'tavg': 'mean',
'tmin': 'mean',
'tmax': 'mean',
'prcp': 'sum'
})
print("Seasonal climate summary for Chicago:")
print(seasonal_stats)from datetime import datetime
from meteostat import Stations, Daily
# Compare daily temperatures across multiple cities
city_stations = Stations().nearby(40.7128, -74.0060, 10000).fetch(1) # NYC
city_stations = city_stations.append(Stations().nearby(34.0522, -118.2437, 10000).fetch(1)) # LA
# Get summer 2020 data
start = datetime(2020, 6, 1)
end = datetime(2020, 8, 31)
data = Daily(city_stations, start, end)
city_data = data.fetch()
# Compare average temperatures by station
temp_comparison = city_data.groupby('station')[['tavg', 'tmin', 'tmax']].mean()
print("Summer 2020 temperature comparison:")
print(temp_comparison)from datetime import datetime
from meteostat import Point, Daily
# Analyze precipitation patterns for Seattle
seattle = Point(47.6062, -122.3321, 56)
# Get recent year of data
start = datetime(2020, 1, 1)
end = datetime(2020, 12, 31)
data = Daily(seattle, start, end)
daily_data = data.fetch()
# Precipitation statistics
rainy_days = (daily_data['prcp'] > 0).sum()
total_precip = daily_data['prcp'].sum()
max_daily_precip = daily_data['prcp'].max()
print(f"Seattle 2020 precipitation summary:")
print(f"Rainy days: {rainy_days}")
print(f"Total precipitation: {total_precip:.1f} mm")
print(f"Maximum daily precipitation: {max_daily_precip:.1f} mm")When flags=True, each meteorological parameter includes a corresponding source flag indicating data quality and origin:
# Source flag meanings for daily data
"A": str # High-quality daily observations from national weather services
"B": str # GHCN-D global historical climatology network data
"C": str # Aggregated from high-quality hourly observations
"D": str # ISD Lite aggregated observations
"E": str # SYNOP aggregated observations
"F": str # METAR aggregated aviation reports
"G": str # Model/reanalysis data (ERA5, GFS, etc.)Daily temperature processing follows meteorological standards:
Daily precipitation represents the total accumulation over the 24-hour period ending at the observation time (typically midnight local time).
# Analyze precipitation patterns
wet_days = daily_data[daily_data['prcp'] > 0.1] # Days with measurable precipitation
dry_spells = daily_data[daily_data['prcp'] == 0] # Dry daysDaily data objects inherit all time series processing methods:
# Data retrieval and analysis
def fetch(self) -> pd.DataFrame: ...
def count(self) -> int: ...
def coverage(self): ...
# Data processing
def normalize(self): ...
def interpolate(self, limit: int = 3): ...
def aggregate(self, freq: str, spatial: bool = False): ...
def convert(self, units: dict): ...
# Utility methods
def stations(self) -> pd.Index: ...
def clear_cache(self): ...Daily data can be aggregated to longer time periods:
# Aggregate to monthly values
monthly_data = daily_data.aggregate('MS') # Month start frequency
# Aggregate to annual values
annual_data = daily_data.aggregate('AS') # Year start frequency
# Custom aggregations with spatial averaging
regional_monthly = daily_data.aggregate('MS', spatial=True)Install with Tessl CLI
npx tessl i tessl/pypi-meteostat