or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

climate-normals.mddaily-data.mddata-processing.mdgeographic-points.mdhourly-data.mdindex.mdmonthly-data.mdunit-conversions.mdweather-stations.md

climate-normals.mddocs/

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

```