0
# Climate Normals
1
2
The Normals class provides access to climate normals (30-year averages) that represent typical weather conditions for specific locations and time periods. Climate normals are essential for establishing baseline conditions, detecting climate change, and providing context for current weather events.
3
4
## Capabilities
5
6
### Climate Normals Initialization
7
8
Create a climate normals dataset for weather stations or geographic points with standard 30-year reference periods.
9
10
```python { .api }
11
class Normals:
12
def __init__(self, loc: Union[pd.DataFrame, Point, list, str], start: int = None, end: int = None) -> None:
13
"""
14
Initialize climate normals data retrieval.
15
16
Parameters:
17
- loc: Union[pd.DataFrame, Point, list, str]
18
- pd.DataFrame: Station data from Stations.fetch()
19
- Point: Geographic point for automatic station selection
20
- list: List of station IDs
21
- str: Single station ID
22
- start: int, optional start year of 30-year period
23
- end: int, optional end year of 30-year period (must be start + 29)
24
25
Note: If start/end not specified, returns all available normal periods.
26
Valid periods must be exactly 30 years and end in year divisible by 10.
27
"""
28
```
29
30
### Data Normalization
31
32
Ensure complete monthly coverage for all stations and reference periods.
33
34
```python { .api }
35
def normalize(self):
36
"""
37
Normalize the DataFrame to include all 12 months.
38
Fills missing months with NaN values for complete time series.
39
40
Returns:
41
Normals object with normalized monthly data
42
"""
43
```
44
45
### Data Retrieval
46
47
Fetch climate normals data with computed average temperature.
48
49
```python { .api }
50
def fetch(self) -> pd.DataFrame:
51
"""
52
Fetch climate normals DataFrame.
53
Automatically computes tavg from tmin and tmax.
54
55
Returns:
56
pandas.DataFrame with monthly climate normals
57
"""
58
```
59
60
## Data Columns
61
62
Climate normals include the following monthly average parameters:
63
64
```python { .api }
65
# Temperature measurements (°C)
66
tavg: float # Average temperature (computed from tmin/tmax)
67
tmin: float # Average minimum temperature
68
tmax: float # Average maximum temperature
69
70
# Precipitation
71
prcp: float # Average precipitation amount (mm)
72
73
# Wind measurements
74
wspd: float # Average wind speed (km/h)
75
76
# Atmospheric pressure
77
pres: float # Average sea level pressure (hPa)
78
79
# Solar radiation
80
tsun: float # Average sunshine duration (hours)
81
82
# Index levels (multi-index DataFrame)
83
month: int # Month number (1-12)
84
start: int # Start year of normal period
85
end: int # End year of normal period
86
station: str # Station ID (for multi-station queries)
87
```
88
89
## Usage Examples
90
91
### Basic Climate Normals
92
93
```python
94
from meteostat import Point, Normals
95
96
# Get climate normals for Paris
97
paris = Point(48.8566, 2.3522, 35)
98
99
# Get 1991-2020 climate normals
100
normals = Normals(paris, 1991, 2020)
101
climate_data = normals.fetch()
102
103
print("Paris climate normals (1991-2020):")
104
print(climate_data[['tavg', 'tmin', 'tmax', 'prcp']])
105
```
106
107
### Compare Different Normal Periods
108
109
```python
110
from meteostat import Point, Normals
111
import pandas as pd
112
113
# Compare old vs new climate normals for New York
114
nyc = Point(40.7128, -74.0060, 10)
115
116
# Get different 30-year periods
117
old_normals = Normals(nyc, 1981, 2010).fetch()
118
new_normals = Normals(nyc, 1991, 2020).fetch()
119
120
# Compare temperature changes
121
temp_comparison = pd.DataFrame({
122
'1981-2010': old_normals['tavg'],
123
'1991-2020': new_normals['tavg']
124
})
125
temp_comparison['Change'] = temp_comparison['1991-2020'] - temp_comparison['1981-2010']
126
127
print("Temperature change between normal periods (°C):")
128
print(temp_comparison)
129
```
130
131
### Regional Climate Normals
132
133
```python
134
from meteostat import Stations, Normals
135
136
# Get climate normals for multiple stations in Japan
137
japan_stations = Stations().region('JP').inventory('monthly', True).fetch(5)
138
139
# Get current climate normals
140
normals = Normals(japan_stations, 1991, 2020)
141
japan_climate = normals.fetch()
142
143
# Analyze regional temperature patterns
144
regional_temps = japan_climate.groupby('month')[['tavg', 'tmin', 'tmax']].mean()
145
print("Regional climate normals for Japan:")
146
print(regional_temps)
147
```
148
149
### Seasonal Climate Analysis
150
151
```python
152
from meteostat import Point, Normals
153
154
# Analyze seasonal climate for Denver, Colorado
155
denver = Point(39.7392, -104.9903, 1609)
156
157
# Get climate normals
158
normals = Normals(denver, 1991, 2020)
159
climate = normals.fetch()
160
161
# Define seasons and calculate seasonal averages
162
climate['season'] = climate.index.map({
163
12: 'Winter', 1: 'Winter', 2: 'Winter',
164
3: 'Spring', 4: 'Spring', 5: 'Spring',
165
6: 'Summer', 7: 'Summer', 8: 'Summer',
166
9: 'Fall', 10: 'Fall', 11: 'Fall'
167
})
168
169
seasonal_normals = climate.groupby('season').agg({
170
'tavg': 'mean',
171
'prcp': 'sum', # Total seasonal precipitation
172
'tsun': 'sum' # Total seasonal sunshine
173
})
174
175
print("Seasonal climate normals for Denver:")
176
print(seasonal_normals)
177
```
178
179
### Climate Normal Anomalies
180
181
```python
182
from datetime import datetime
183
from meteostat import Point, Monthly, Normals
184
185
# Calculate current year anomalies vs climate normals
186
stockholm = Point(59.3293, 18.0686, 28)
187
188
# Get climate normals and current year data
189
normals = Normals(stockholm, 1991, 2020).fetch()
190
current_year = Monthly(stockholm, datetime(2020, 1, 1), datetime(2020, 12, 31)).fetch()
191
192
# Calculate temperature anomalies
193
monthly_normals = normals.set_index(normals.index.droplevel(['start', 'end']))['tavg']
194
current_temps = current_year['tavg']
195
196
# Align indices for comparison
197
anomalies = current_temps - monthly_normals
198
199
print("2020 Temperature anomalies vs 1991-2020 normals (°C):")
200
print(anomalies)
201
```
202
203
### All Available Normal Periods
204
205
```python
206
from meteostat import Point, Normals
207
208
# Get all available climate normal periods
209
location = Point(51.5074, -0.1278) # London
210
211
# Don't specify start/end to get all periods
212
all_normals = Normals(location)
213
all_climate = all_normals.fetch()
214
215
# See available periods
216
periods = all_climate.index.get_level_values('end').unique()
217
print(f"Available normal periods ending in: {sorted(periods)}")
218
219
# Compare trends across periods
220
period_comparison = all_climate.groupby(['end', 'month'])['tavg'].mean().unstack('month')
221
print("\nTemperature trends across normal periods:")
222
print(period_comparison)
223
```
224
225
## Standard Reference Periods
226
227
Climate normals are calculated for standard 30-year periods:
228
229
```python { .api }
230
# Standard WMO reference periods
231
current_period = (1991, 2020) # Current WMO standard
232
previous_period = (1981, 2010) # Previous WMO standard
233
older_period = (1971, 2000) # Historical reference
234
235
# Period validation rules
236
valid_period_length = 30 # Must be exactly 30 years
237
end_year_divisible_by = 10 # End year should end in 0
238
```
239
240
## Data Processing Methods
241
242
Climate normals objects inherit standard processing methods:
243
244
```python { .api }
245
# Data retrieval
246
def fetch(self) -> pd.DataFrame: ...
247
def count(self) -> int: ...
248
249
# Data processing
250
def convert(self, units: dict): ...
251
252
# Utility methods
253
def clear_cache(self): ...
254
```
255
256
## Multi-Index Structure
257
258
Climate normals DataFrames use a multi-level index:
259
260
```python
261
# Index levels for multi-station queries
262
index_levels = ['station', 'start', 'end', 'month']
263
264
# Index levels for single station
265
single_station_levels = ['start', 'end', 'month']
266
267
# Index levels when period is specified
268
period_specified_levels = ['month']
269
```
270
271
## Applications in Climate Science
272
273
### Climate Change Detection
274
```python
275
# Compare different 30-year periods to detect long-term changes
276
temp_change = new_normals['tavg'] - old_normals['tavg']
277
significant_change = temp_change[abs(temp_change) > 0.5] # >0.5°C change
278
```
279
280
### Weather Extremes Assessment
281
```python
282
# Determine if current conditions are unusual vs climate normal
283
current_temp = 25.5 # Current July temperature
284
july_normal = normals.loc[7, 'tavg'] # July climate normal
285
anomaly = current_temp - july_normal # Temperature anomaly
286
```
287
288
### Agricultural Planning
289
```python
290
# Use normals for growing season analysis
291
growing_season = normals[normals['tavg'] > 5] # Months above 5°C
292
frost_free_days = len(growing_season)
293
```
294
295
### Energy Demand Modeling
296
```python
297
# Calculate heating/cooling degree days from normals
298
heating_degree_days = (18.3 - normals['tavg']).clip(lower=0).sum()
299
cooling_degree_days = (normals['tavg'] - 18.3).clip(lower=0).sum()
300
```