Python API for the Kansas Mesonet
Project description
ksmesopy
Python package for downloading and processing data from the Kansas Mesonet, an environmental monitoring network operated by Kansas State University.
Installation
pip install ksmesopy
pip install "ksmesopy[app]" # Use this to also install a GUI
Dependencies: numpy, pandas, matplotlib. The desktop app additionally requires guile.
Quick start
import ksmesopy as ms
# Download daily temperature and precipitation for one station
df = ms.request_data(
station="Manhattan",
start="2024-01-01",
end="2024-12-31",
interval="day",
variables=["TEMP2MAVG", "TEMP2MMIN", "TEMP2MMAX", "PRECIP"],
)
# Optional: rename columns to snake_case
df = ms.rename_columns(df)
# TIMESTAMP → timestamp, TEMP2MAVG → tair_2m_avg, PRECIP → precip, …
Desktop app
Run this in your terminal
ksmesopy-app
A GUI for selecting stations, date ranges, variables, and intervals, with a tabular view and time-series chart. Exports to CSV and PNG.
API reference
Stations
| Function | Returns | Description |
|---|---|---|
get_stations() |
DataFrame |
Full station metadata table |
get_stations(names_only=True) |
list[str] |
Sorted list of station names only |
get_stations_active() |
DataFrame |
Availability table: STATION, OBS_INTERVAL (s), START, END |
Data retrieval
| Function | Returns | Description |
|---|---|---|
request_data(station, start, end, interval, variables, *, verbose, sleep) |
DataFrame |
Download data for one station. interval is "day", "hour", or "5min". Daily timestamps are corrected from the Mesonet's next-day convention. |
request_data_multi(stations, start, end, interval, variables, *, verbose, sleep) |
dict[str, DataFrame] |
Same as above for a list of stations; returns one DataFrame per station. |
list_variables(interval=None) |
list[dict] |
Variable catalogue filtered by interval, or all variables if None. Each entry has keys api_name, snake_name, description, intervals. |
rename_columns(df, preset="snake") |
DataFrame |
Rename API column names to snake_case (e.g. TEMP2MAVG → tair_2m_avg). Pass a dict for a custom mapping. |
Soil processing
| Function | Returns | Description |
|---|---|---|
calibrate_vwc(df, vwc_cols=None) |
DataFrame |
Replace firmware VWC values with the KSU site-specific calibration. Requires SOILKA*CM and SOILEC*CM columns. Works on any subset of depths. |
compute_soil_water_storage(df) |
DataFrame |
Trapezoidal soil water storage in the top 50 cm (mm). Requires all four VWC depths; adds a STORAGE_MM column. Call calibrate_vwc() first for calibrated storage. |
Derived variables
| Function | Returns | Description |
|---|---|---|
growing_degree_days(tmin, tmax, base=10.0, ceiling=30.0) |
ndarray |
Daily GDD. Both tmin/tmax clipped to [base, ceiling] before averaging. |
heat_index(temp, rh) |
ndarray |
NOAA/NWS apparent temperature (°C). |
wind_chill(temp, wspd) |
ndarray |
NWS wind chill (°C); valid for temp ≤ 10 °C, wind ≥ 1.3 m s⁻¹. |
temperature_humidity_index(temp, rh) |
ndarray |
THI for livestock heat stress. Thresholds (dairy): <68 none · 68–72 mild · 72–80 moderate · 80–90 severe · >90 dangerous. |
Reference evapotranspiration
| Function | Returns | Description |
|---|---|---|
reference_et_penman_monteith(doy, lat, elev, tmin, tmax, srad, wspd, rhmin, rhmax, *, vpd, ea, wind_height) |
ndarray |
FAO-56 Penman-Monteith. Supply vapour pressure via ea=, vpd=, or rhmin=+rhmax=. srad in W m⁻², converted internally. |
reference_et_hargreaves(doy, lat, tmin, tmax, *, tmean) |
ndarray |
Hargreaves–Samani. Temperature only — no humidity, radiation, or wind needed. |
Both return ETo (mm day⁻¹) as an ndarray. Use extraterrestrial_radiation(doy, lat) if you also need Ra.
Atmospheric helpers
| Function | Output |
|---|---|
saturation_vapor_pressure(temp) |
es (kPa) |
actual_vapor_pressure(temp, rh) |
ea (kPa) |
vapor_pressure_deficit(temp, rh) |
VPD (kPa, ≥ 0) |
slope_saturation_vapor_pressure(temp) |
Δ (kPa °C⁻¹) |
atmospheric_pressure(elev) |
P (kPa) |
psychrometric_constant(elev) |
γ (kPa °C⁻¹) |
extraterrestrial_radiation(doy, lat) |
Ra (MJ m⁻² day⁻¹) |
net_radiation(srad_mj, tmin, tmax, ea, elev, doy, lat) |
Rn (MJ m⁻² day⁻¹) |
srad_to_mj(srad, period) |
energy (MJ m⁻²) |
All functions accept scalars or NumPy arrays.
Charts
Each function draws onto a Matplotlib Axes supplied by the caller, so panels compose freely inside any figure layout. All functions accept API column names (TEMP2MAVG) or snake_case names (tair_2m_avg) interchangeably, and return the axes they drew on so they can be further customised.
import matplotlib.pyplot as plt
import ksmesopy as ms
fig, axes = plt.subplots(5, 1, sharex=True, figsize=(12, 14))
ms.plot_temperature(axes[0], df, ["TEMP2MAVG", "TEMP2MMIN", "TEMP2MMAX"])
ms.plot_precip(axes[1], df, "PRECIP")
ms.plot_humidity(axes[2], df, "RELHUM2MAVG")
ms.plot_solar_radiation(axes[3], df, ["SRAVG", "Ra"]) # Ra drawn dashed
ms.plot_vwc(axes[4], df) # auto-detects VWC columns
plt.tight_layout()
plt.savefig("meteogram.png", dpi=150)
All functions accept API column names (TEMP2MAVG) or snake_case names (tair_2m_avg) interchangeably, and return the axes they drew on so they can be further customised.
| Function | Key behaviour |
|---|---|
plot_temperature(ax, df, variables, *, band, ylabel, legend) |
Shaded band when min/avg/max triplet detected (band=True); plain lines otherwise. Works for air and soil temperature. |
plot_precip(ax, df, variable, *, ylabel, color) |
Bar chart, bar width inferred from timestamp spacing. |
plot_humidity(ax, df, variables, *, ylabel, legend) |
Lines, y-axis fixed 0–100 %. |
plot_vpd(ax, df, variables, *, ylabel, legend) |
Filled area + line, y-axis starts at 0. |
plot_solar_radiation(ax, df, variables, *, ylabel, legend) |
Filled area for observed; dashed line for Ra columns (detected by name). |
plot_wind(ax, df, speed, direction, *, ylabel, legend) |
Speed as line; direction overlaid as scatter on a twin y-axis with N/E/S/W ticks. |
plot_vwc(ax, df, variables, *, ylabel, legend) |
Sequential colormap shallow→deep; auto-detects VWC columns if variables=None. |
plot_et(ax, df, variables, *, bar, ylabel, legend) |
Line by default; bar=True for daily totals. |
Variable catalogue
Intervals: D = daily only · H = hourly and daily · A = 5-min, hourly, and daily
Atmospheric
| API name | snake_case | Description | Unit | Intervals |
|---|---|---|---|---|
TEMP2MAVG |
tair_2m_avg |
Air temperature 2 m avg | °C | A |
TEMP2MMIN |
tair_2m_min |
Air temperature 2 m min | °C | D |
TEMP2MMAX |
tair_2m_max |
Air temperature 2 m max | °C | D |
TEMP10MAVG |
tair_10m_avg |
Air temperature 10 m avg | °C | A |
TEMP10MMIN |
tair_10m_min |
Air temperature 10 m min | °C | D |
TEMP10MMAX |
tair_10m_max |
Air temperature 10 m max | °C | D |
RELHUM2MAVG |
rh_2m_avg |
Relative humidity 2 m avg | % | A |
RELHUM2MMIN |
rh_2m_min |
Relative humidity 2 m min | % | D |
RELHUM2MMAX |
rh_2m_max |
Relative humidity 2 m max | % | D |
VPDEFAVG |
vpd_avg |
Vapor pressure deficit avg | kPa | A |
PRESSUREAVG |
pressure_avg |
Atmospheric pressure avg | kPa | A |
PRECIP |
precip |
Precipitation gauge 1 | mm | A |
PRECIP2 |
precip2 |
Precipitation gauge 2 | mm | A |
SRAVG |
srad |
Solar radiation avg | W m⁻² | A |
WSPD2MAVG |
wspd_2m_avg |
Wind speed 2 m avg | m s⁻¹ | A |
WSPD2MMAX |
wspd_2m_max |
Wind speed 2 m max | m s⁻¹ | H¹ |
WDIR2M |
wdir_2m |
Wind direction 2 m | ° | A |
WDIR2MSTD |
wdir_2m_std |
Wind direction 2 m std dev | ° | A |
WSPD10MAVG |
wspd_10m_avg |
Wind speed 10 m avg | m s⁻¹ | A |
WSPD10MMAX |
wspd_10m_max |
Wind speed 10 m max | m s⁻¹ | H¹ |
WDIR10M |
wdir_10m |
Wind direction 10 m | ° | A |
WDIR10MSTD |
wdir_10m_std |
Wind direction 10 m std dev | ° | A |
¹ Available at 5-min and daily only (not hourly).
Soil temperature — dedicated probes
| API name | snake_case | Description | Unit | Intervals |
|---|---|---|---|---|
SOILTMP5AVG |
tsoil_5cm |
Soil temperature 5 cm avg | °C | A |
SOILTMP5MIN |
tsoil_5cm_min |
Soil temperature 5 cm min | °C | D |
SOILTMP5MAX |
tsoil_5cm_max |
Soil temperature 5 cm max | °C | D |
SOILTMP10AVG |
tsoil_10cm |
Soil temperature 10 cm avg | °C | A |
SOILTMP10MIN |
tsoil_10cm_min |
Soil temperature 10 cm min | °C | D |
SOILTMP10MAX |
tsoil_10cm_max |
Soil temperature 10 cm max | °C | D |
Soil — CS655 sensors
| API name | snake_case | Description | Unit | Intervals |
|---|---|---|---|---|
SOILTMP5AVG655 |
tsoil_5cm_655 |
Soil temperature 5 cm | °C | A |
SOILTMP10AVG655 |
tsoil_10cm_655 |
Soil temperature 10 cm | °C | A |
SOILTMP20AVG655 |
tsoil_20cm_655 |
Soil temperature 20 cm | °C | A |
SOILTMP50AVG655 |
tsoil_50cm_655 |
Soil temperature 50 cm | °C | A |
SOILKA5CM |
ka_5cm |
Dielectric constant 5 cm | — | A |
SOILKA10CM |
ka_10cm |
Dielectric constant 10 cm | — | A |
SOILKA20CM |
ka_20cm |
Dielectric constant 20 cm | — | A |
SOILKA50CM |
ka_50cm |
Dielectric constant 50 cm | — | A |
SOILEC5CM |
ec_5cm |
Electrical conductivity 5 cm | dS m⁻¹ | A |
SOILEC10CM |
ec_10cm |
Electrical conductivity 10 cm | dS m⁻¹ | A |
SOILEC20CM |
ec_20cm |
Electrical conductivity 20 cm | dS m⁻¹ | A |
SOILEC50CM |
ec_50cm |
Electrical conductivity 50 cm | dS m⁻¹ | A |
VWC5CM |
vwc_5cm |
Volumetric water content 5 cm | m³ m⁻³ | A |
VWC10CM |
vwc_10cm |
Volumetric water content 10 cm | m³ m⁻³ | A |
VWC20CM |
vwc_20cm |
Volumetric water content 20 cm | m³ m⁻³ | A |
VWC50CM |
vwc_50cm |
Volumetric water content 50 cm | m³ m⁻³ | A |
VWC note: the Mesonet API returns VWC computed by the CS655 firmware equation. Call
calibrate_vwc()to replace those values with the KSU site-specific calibration. RequiresSOILKA*CMandSOILEC*CMto be fetched alongsideVWC*CM. Works for any subset of depths independently.
Notes
Precipitation. The Mesonet operates dual tipping-bucket rain gauges at most stations. request_data() returns both (PRECIP, PRECIP2); the desktop app merges them to the row-wise maximum automatically. For scripted use, merge manually:
df["PRECIP"] = df[["PRECIP", "PRECIP2"]].max(axis=1)
df.drop(columns="PRECIP2", inplace=True)
Daily timestamps. The Mesonet API stores each day's aggregated values at 00:00 of the following calendar day. request_data() corrects for this automatically; the returned TIMESTAMP always reflects the observation date.
Missing values. The API encodes missing observations as "M". These are converted to NaN on read. Periods before a station or sensor was installed are pre-filled with NaN rather than omitted.
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ksmesopy-0.2.0.tar.gz.
File metadata
- Download URL: ksmesopy-0.2.0.tar.gz
- Upload date:
- Size: 31.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fb4e431dc1acfa4f24b663a89701b26037d6c37f301cbf721c60ce6cb6832ba2
|
|
| MD5 |
d483589e3b5b7381a58748349fa21ffd
|
|
| BLAKE2b-256 |
859cb1f2a21cfc8fe6c15bf048cc5cb1e09ed378e35c8a4cee67aa66652e054a
|
Provenance
The following attestation bundles were made for ksmesopy-0.2.0.tar.gz:
Publisher:
publish.yml on soilwater/ksmesopy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ksmesopy-0.2.0.tar.gz -
Subject digest:
fb4e431dc1acfa4f24b663a89701b26037d6c37f301cbf721c60ce6cb6832ba2 - Sigstore transparency entry: 2051475279
- Sigstore integration time:
-
Permalink:
soilwater/ksmesopy@f121c98a8cf5cef2727c1d68231a983ab029251e -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/soilwater
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f121c98a8cf5cef2727c1d68231a983ab029251e -
Trigger Event:
push
-
Statement type:
File details
Details for the file ksmesopy-0.2.0-py3-none-any.whl.
File metadata
- Download URL: ksmesopy-0.2.0-py3-none-any.whl
- Upload date:
- Size: 31.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4f327807805fcaab89a69cfec0f2e5dfe54c4341db88c4e8972b411cbad194de
|
|
| MD5 |
3df9fb5d718c21a6d7f95284502dc1fa
|
|
| BLAKE2b-256 |
31b42369c5e05c13d93deda29a489228f0b1817d8f2a17695e729ece02a984b8
|
Provenance
The following attestation bundles were made for ksmesopy-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on soilwater/ksmesopy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ksmesopy-0.2.0-py3-none-any.whl -
Subject digest:
4f327807805fcaab89a69cfec0f2e5dfe54c4341db88c4e8972b411cbad194de - Sigstore transparency entry: 2051475716
- Sigstore integration time:
-
Permalink:
soilwater/ksmesopy@f121c98a8cf5cef2727c1d68231a983ab029251e -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/soilwater
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f121c98a8cf5cef2727c1d68231a983ab029251e -
Trigger Event:
push
-
Statement type: