Skip to main content

🌦️ nus-campus-weather

Python package for the NUS Campus Meteorological Network dataset — hourly observations from 40 automatic weather stations across the National University of Singapore (NUS) main campus, Singapore, for the full calendar year 2025.

Dataset repo: nus-campus-weather-paper
PyPI: pip install nus-campus-weather


📦 Installation

From PyPI:

pip install nus-campus-weather

From source:

git clone https://github.com/City-Syntax/nus-campus-weather.git
cd nus-campus-weather
pip install -e .

Dependencies: pandas, numpy, matplotlib, seaborn
Optional (for map backgrounds): contextily


🚀 Quick Start

import nus_campus_weather as ncw

# Just use it — the dataset auto-downloads from Zenodo on first call
# (~120 MB, one-time), then cached for future use.
df = ncw.load_station("WS01")
fig = ncw.plot_climatology()

Optional — explicit fetch

ncw.fetch_dataset()   # download/cache now instead of on first load

Optional — bring your own copy

If you have a local clone of the dataset repo (useful for development or offline work), point the loader at it:

ncw.set_data_dir("/path/to/nus-campus-weather-paper")
# Or via env var:
# export NUS_WEATHER_DATA="/path/to/nus-campus-weather-paper"

The auto-fetch caches to your platform cache dir (~/Library/Caches/nus_campus_weather/ on macOS, ~/.cache/nus_campus_weather/ on Linux, %LOCALAPPDATA%\nus_campus_weather\ on Windows). Override with the NUS_WEATHER_CACHE environment variable.

Dataset version

ncw.DATASET_VERSION   # '1.1.0'
ncw.DATASET_DOI       # '10.5281/zenodo.23535609'

📂 Loading Data

Single station

# Raw sensor data
df = ncw.load_station("WS01")

# Gap-filled data (includes _flag columns)
df = ncw.load_station("WS01", imputed=True)

Each CSV has columns: Datetime, Latitude, Longitude, Elevation (m), Type, and six meteorological variables (plus Rain Tot (mm) at WS02, WS16, WS35). Imputed files add a _flag column per variable:

Flag Meaning
0 Original observation
1 Stage 1 linear interpolation (short gaps)
2 Stage 2 XGBoost spatial regression
3 Not measured / not imputed (left empty)

Observed values only

# Gap-filled file, but every filled value (flag 1-3) returned as NaN
df  = ncw.load_station("WS01", imputed=True, observed_only=True)
wsp = ncw.load_all(variable="WindSpeed Ave (m/s)", imputed=True, observed_only=True)

⚠️ Wind: gap-filled wind speed and direction have little skill at intra-campus scale. Use observed_only=True (or filter flag == 0) for wind analyses; the package warns if filled wind values are loaded.

All 40 stations

# Wide format — one column per station (8760 rows × 40 cols)
temp = ncw.load_all(variable="AirTemp Ave (C)", imputed=True)

# Long format — all stations stacked
long_df = ncw.load_all(imputed=True)

Station metadata

meta = ncw.station_metadata()
# Returns a DataFrame indexed by station (WS01..WS40) with columns:
# lat, lon, elevation_m, type (Ground / Roof / Roof-3axis)

📊 Plot Functions

All plot functions use the data directory set via set_data_dir() and save figures to a figures/ subfolder within it.

Function Output
ncw.plot_completeness() Completeness bubble map and monthly heatmap (cf. paper Fig. 4)
ncw.plot_climatology() Diurnal × seasonal climatology (cf. paper Fig. 6)
ncw.plot_radials() Annual radial climatology, five variables (cf. paper Fig. 9)
ncw.plot_imputation_examples() Representative gap-fill examples (cf. paper Fig. 10)
ncw.plot_completeness()
ncw.plot_climatology()
ncw.plot_radials()
ncw.plot_imputation_examples()

🗂️ Dataset Variables

Column Units Notes
AirTemp Ave (C) °C Ground stations 2–3 m above ground; 8 rooftop stations
RelHum Ave (%) %
AtmPress Ave (hPa) hPa
GlobalRad Ave (W/m2) W m⁻² Global horizontal irradiance at the sensor, including local shading
WindSpeed Ave (m/s) m s⁻¹ Hourly vector mean (magnitude of the mean wind vector)
WindDir Ave (degrees) ° Hourly vector mean, 0–360°
Rain Tot (mm) mm WS02, WS16, WS35 only

⚠️ Known issues

From dataset v1.1.0, faulty sensor values are removed by rule-based quality control; every removal is listed in data_quality_assessment/qc_log.csv of the dataset repository.

  • Global irradiance not available (flag 3, not imputed) at WS38 (no pyranometer, fully shaded site) and WS32, WS39 (pyranometers non-functional).
  • Global irradiance removed for some months at WS07, WS19, WS23 and WS26 (corrupted channel; spurious night-time readings).
  • WS17 — pressure removed for January–April (faulty sensor) and wind for 20–26 December (sensor malfunction); these gaps are filled like any other.
  • Wind speed/direction — spatially decorrelated at intra-campus scale; use only flag = 0 observations for wind analyses (observed_only=True).

📄 Citation

If you use this package or dataset, please cite:

Lim, J. et al. An hourly meteorological dataset from a high-density 40-station campus weather network in tropical Singapore. Scientific Data (under review).

Dataset: Zenodo, https://doi.org/10.5281/zenodo.20477760 (all versions)


📜 Licence

Code (this package): MIT — see LICENSE.
Dataset: CC BY 4.0 — see the dataset repository.

Metadata

Release files for nus-campus-weather 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nus-campus-weather 1.2.0
File Size Uploaded Provenance Actions
nus_campus_weather-1.2.0.tar.gz 20.0 kB Without provenance Details for nus_campus_weather-1.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for nus-campus-weather 1.2.0
File Interpreter ABI Platform Actions
nus_campus_weather-1.2.0-py3-none-any.whl Python 3 none any Details for nus_campus_weather-1.2.0-py3-none-any.whl

Total release size: 39.3 kB

Release files / nus_campus_weather-1.2.0.tar.gz

Download URL nus_campus_weather-1.2.0.tar.gz
Size 20.0 kB
Tags Source
SHA-256 checksum
How to use checksums
cf87524bfd00934ef21003333e50d83828703cbb1238769d18695e21dbe2ad93
BLAKE2b-256 checksum
How to use checksums
076b4b7bded5809ab50d82ad85d04a8c30b8c6744f458f0b4e38a108d04182ef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release files / nus_campus_weather-1.2.0-py3-none-any.whl

Download URL nus_campus_weather-1.2.0-py3-none-any.whl
Size 19.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4a5840985c7428d060797c0eb029701aefc8e43798ef0ecd0040699281f90eef
BLAKE2b-256 checksum
How to use checksums
0ac08a66a38a076945241948f2857af59a4f5567fa4221f593f766b6c68d79b2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Security for nus-campus-weather 1.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page