# Import necessary modules
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
34 Meteogram
A weather meteogram is a time-series graphical representation that displays detailed weather information for a specific location over a continuous period. This compact chart captures various meteorological variables such as air and soil temperature, wind speed and direction, precipitation, cloud cover, and atmospheric pressure. Each variable is typically plotted against time on the horizontal axis, allowing for a clear visual analysis of weather trends and patterns.
# Read data and display the first 5 rows
= '../datasets/kings_creek_2022_2023_daily.csv'
filename = pd.read_csv(filename, parse_dates=['datetime'])
df df.head()
datetime | pressure | tmin | tmax | tavg | rmin | rmax | prcp | srad | wspd | wdir | vpd | vwc_5cm | vwc_20cm | vwc_40cm | soiltemp_5cm | soiltemp_20cm | soiltemp_40cm | battv | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2022-01-01 | 96.837917 | -14.8 | -4.4 | -9.60 | 78.475475 | 98.012496 | 0.0 | 2.09808 | 5.483333 | 0.968820 | 0.027500 | 0.256750 | 0.307000 | 0.359000 | 2.995833 | 5.391667 | 7.425000 | 8714.833333 |
1 | 2022-01-02 | 97.994583 | -20.4 | -7.2 | -13.80 | 50.543218 | 84.935503 | 0.0 | 9.75636 | 2.216250 | 2.023276 | 0.072500 | 0.256000 | 0.307000 | 0.358292 | 2.562500 | 4.250000 | 6.691667 | 8890.041667 |
2 | 2022-01-03 | 97.843750 | -9.4 | 8.8 | -0.30 | 40.622240 | 82.662479 | 0.0 | 9.68076 | 2.749167 | 5.667358 | 0.261667 | 0.255167 | 0.307000 | 0.358000 | 2.454167 | 3.916667 | 6.208333 | 8924.833333 |
3 | 2022-01-04 | 96.418750 | 0.1 | 8.6 | 4.35 | 48.326316 | 69.401604 | 0.0 | 8.37900 | 5.805833 | 2.627163 | 0.363333 | 0.288958 | 0.319417 | 0.357125 | 2.495833 | 3.754167 | 5.841667 | 8838.291667 |
4 | 2022-01-05 | 97.462500 | -11.1 | -2.2 | -6.65 | 50.341455 | 76.828233 | 0.0 | 5.71716 | 4.206667 | 1.250533 | 0.126250 | 0.312833 | 0.337000 | 0.357333 | 1.687500 | 3.429167 | 5.566667 | 8848.083333 |
# Select data for January
= pd.to_datetime('2022-01-01')
start_date = pd.to_datetime('2023-01-01')
end_date = (df['datetime'] >= start_date) & (df['datetime'] < end_date)
idx = df[idx].copy().reset_index(drop=True)
df df.head()
datetime | pressure | tmin | tmax | tavg | rmin | rmax | prcp | srad | wspd | wdir | vpd | vwc_5cm | vwc_20cm | vwc_40cm | soiltemp_5cm | soiltemp_20cm | soiltemp_40cm | battv | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2022-01-01 | 96.837917 | -14.8 | -4.4 | -9.60 | 78.475475 | 98.012496 | 0.0 | 2.09808 | 5.483333 | 0.968820 | 0.027500 | 0.256750 | 0.307000 | 0.359000 | 2.995833 | 5.391667 | 7.425000 | 8714.833333 |
1 | 2022-01-02 | 97.994583 | -20.4 | -7.2 | -13.80 | 50.543218 | 84.935503 | 0.0 | 9.75636 | 2.216250 | 2.023276 | 0.072500 | 0.256000 | 0.307000 | 0.358292 | 2.562500 | 4.250000 | 6.691667 | 8890.041667 |
2 | 2022-01-03 | 97.843750 | -9.4 | 8.8 | -0.30 | 40.622240 | 82.662479 | 0.0 | 9.68076 | 2.749167 | 5.667358 | 0.261667 | 0.255167 | 0.307000 | 0.358000 | 2.454167 | 3.916667 | 6.208333 | 8924.833333 |
3 | 2022-01-04 | 96.418750 | 0.1 | 8.6 | 4.35 | 48.326316 | 69.401604 | 0.0 | 8.37900 | 5.805833 | 2.627163 | 0.363333 | 0.288958 | 0.319417 | 0.357125 | 2.495833 | 3.754167 | 5.841667 | 8838.291667 |
4 | 2022-01-05 | 97.462500 | -11.1 | -2.2 | -6.65 | 50.341455 | 76.828233 | 0.0 | 5.71716 | 4.206667 | 1.250533 | 0.126250 | 0.312833 | 0.337000 | 0.357333 | 1.687500 | 3.429167 | 5.566667 | 8848.083333 |
# Display number of missing values for each column.
sum() df.isna().
datetime 0
pressure 0
tmin 0
tmax 0
tavg 0
rmin 0
rmax 0
prcp 0
srad 0
wspd 1
wdir 28
vpd 2
vwc_5cm 0
vwc_20cm 0
vwc_40cm 0
soiltemp_5cm 0
soiltemp_20cm 0
soiltemp_40cm 0
battv 0
dtype: int64
# Replace missing values
'wspd'] = df['wspd'].interpolate(method='linear')
df['vpd'] = df['vpd'].interpolate(method='linear') df[
# Display the new number of missing values for each column.
sum() df.isna().
datetime 0
pressure 0
tmin 0
tmax 0
tavg 0
rmin 0
rmax 0
prcp 0
srad 0
wspd 0
wdir 28
vpd 0
vwc_5cm 0
vwc_20cm 0
vwc_40cm 0
soiltemp_5cm 0
soiltemp_20cm 0
soiltemp_40cm 0
battv 0
dtype: int64
Estimate some useful metrics
To characterize what happened during the entire year, let’s compute the annual rainfall, maximum wind speed, and maximum and minimum air temperature.
# Find and print total precipitation
= df['prcp'].sum().round(2)
P_total print(f'Total precipitation in 2023 was {P_total} mm')
Total precipitation in 2023 was 523.28 mm
# Find the total number of days with measurable precipitation
= (df['prcp'] > 0).sum()
P_hours print(f'There were {P_hours} days with precipitation')
There were 108 days with precipitation
# Find median air temperature. Print value.
= df['tavg'].median()
Tmedian print(f'Median air temperature was {Tmedian} Celsius')
Median air temperature was 13.65 Celsius
# Find value and time of minimum air temperature. Print value and timestamp.
= '%A, %B %d, %Y'
fmt = df['tmin'].argmin()
Tmin_idx = df.loc[Tmin_idx, 'tmin']
Tmin_value = df.loc[Tmin_idx, 'datetime']
Tmin_timestamp print(f'The lowest air temperature was {Tmin_value} on {Tmin_timestamp:{fmt}}')
The lowest air temperature was -22.4 on Thursday, December 22, 2022
# Find value and time of maximum air temperature. Print value and timestamp.
= df['tmax'].argmax()
Tmax_idx = df.loc[Tmax_idx, 'tmax']
Tmax_value = df.loc[Tmax_idx, 'datetime']
Tmax_timestamp print(f'The highest air temperature was {Tmax_value} on {Tmax_timestamp:{fmt}}')
The highest air temperature was 37.4 on Saturday, July 23, 2022
# Find max wind gust and time of occurrence. Print value and timestamp.
= df['wspd'].argmax()
Wmax_idx = df.loc[Wmax_idx, 'wspd']
Wmax_value = df.loc[Wmax_idx, 'datetime']
Wmax_timestamp print(f'The highest wind speed was {Wmax_value:.2f} m/s on {Wmax_timestamp:{fmt}}')
The highest wind speed was 8.15 m/s on Tuesday, April 12, 2022
Meteogram
# Create meteogram plot
# Define style
'ggplot')
plt.style.use(
# Define fontsize
= 14
font
# Create plot
=(14,30))
plt.figure(figsize
# Air temperature
9,1,1)
plt.subplot('Kings Creek Meteogram for 2022', size=20)
plt.title('datetime'], df['tmin'], color='navy')
plt.plot(df['datetime'], df['tmax'], color='tomato')
plt.plot(df['Air Temperature (°C)', size=font)
plt.ylabel(=font)
plt.yticks(size
# Relative humidity
9,1,2)
plt.subplot('datetime'], df['rmin'], color='navy')
plt.plot(df['datetime'], df['rmax'], color='tomato')
plt.plot(df['Relative Humidity (%)', size=font)
plt.ylabel(=font)
plt.yticks(size0,100)
plt.ylim(
# Atmospheric pressure
9,1,3)
plt.subplot('datetime'], df['pressure'], '-k')
plt.plot(df['Pressure (kPa)', size=font)
plt.ylabel(=font)
plt.yticks(size
# Vapor pressure deficit
9,1,4)
plt.subplot('datetime'], df['vpd'], '-k')
plt.plot(df['Vapor pressure deficit (kPa)', size=font)
plt.ylabel(=font)
plt.yticks(size
# Wind speed
9,1,5)
plt.subplot('datetime'], df['wspd'], '-k', label='Wind speed')
plt.plot(df['Wind Speed ($m \ s^{-1}$)', size=font)
plt.ylabel(='upper left')
plt.legend(loc=font)
plt.yticks(size
# Solar radiation
9,1,6)
plt.subplot('datetime'], df['srad'])
plt.plot(df['Solar radiation ($W \ m^{-2}$)', size=font)
plt.ylabel(=font)
plt.yticks(size
# Precipitation
9,1,7)
plt.subplot('datetime'], df['prcp'], color='navy')
plt.step(df['Precipitation (mm)', size=font)
plt.ylabel(=font)
plt.yticks(size0.01,35)
plt.ylim('datetime'].iloc[5], 30, f"Total = {P_total} mm", size=14)
plt.text(df[
# Soil temperature
9,1,8)
plt.subplot('datetime'], df['soiltemp_5cm'], '-k', label='5 cm')
plt.plot(df['datetime'], df['soiltemp_20cm'], '-g', label='20 cm')
plt.plot(df['datetime'], df['soiltemp_40cm'], '--r', label='40 cm')
plt.plot(df['Soil temperature (°C)', size=font)
plt.ylabel(=font)
plt.yticks(size'soiltemp_5cm'].min()-10, df['soiltemp_5cm'].max()+10)
plt.ylim(df[='minor')
plt.grid(which='upper left')
plt.legend(loc
# Soil moisture
9,1,9)
plt.subplot('datetime'], df['vwc_5cm'], '-k', label='5 cm')
plt.plot(df['datetime'], df['vwc_20cm'], '-g', label='20 cm')
plt.plot(df['datetime'], df['vwc_40cm'], '--r', label='40 cm')
plt.plot(df['Soil Moisture ($m^3 \ m^{-3}$)', size=font)
plt.ylabel(=font)
plt.yticks(size0, 0.5)
plt.ylim(='minor')
plt.grid(which='best')
plt.legend(loc
=0.2) # for space between columns wspace=0)
plt.subplots_adjust(hspace#plt.savefig('meteogram.svg', format='svg')
plt.show()