PVGIS — introduction#
earthlens ships a single pvgis backend that fetches solar-radiation and
photovoltaic (PV) time series from the European Commission JRC
Photovoltaic Geographical Information System (PVGIS)
5.3 non-interactive REST API. A request resolves to a per-coordinate hourly
pandas.DataFrame, so this is a tabular backend — not a raster, not a grid
of pixels.
Two tools ship in the MVP:
seriescalc— hourly solar-radiation / PV-power time series over a chosen year window (global in-plane irradiance, sun height, air temperature, wind; PV system power when the PV knobs are set).tmy— a Typical Meteorological Year: an hourly multi-year synthesis of temperature, humidity, horizontal / beam / diffuse irradiance, infrared, wind, and surface pressure.
This page orients the backend. For the hands-on download walkthrough see Usage and the product ids on the Available datasets page; the rendered API is the Reference page.
How it works#
PVGIS 5.3 is a keyless REST API (https://re.jrc.ec.europa.eu/api/v5_3/<tool>,
GET, outputformat=json). The backend hits it directly with requests —
there is no SDK, no authentication, and no pyramids / array dependency (pure
requests + pandas). A request samples the location(s) — a single
point=(lat, lon), or a bounding box expanded to a point grid at spacing_deg
— issues one keyless GET per point, parses each JSON response into a
long-format frame tagged with lat / lon / product, and concatenates them.
from earthlens.earthlens import EarthLens
df = EarthLens(
data_source="pvgis", # alias: "solar-pv"
variables=["seriescalc"],
start="2020-01-01",
end="2020-12-31",
point=(45.0, 8.0), # northern Italy
).download()
# -> a per-coordinate hourly pandas.DataFrame
Three things that shape the backend#
-
Output is a per-point time series, not a grid. PVGIS already returns the resolved hourly / TMY series, so there is no gridded reduction to apply. The
EarthLensfacade rejects a non-Noneaggregate=for thistabularbackend withNotImplementedError. (Resample the returnedDataFramein pandas if you want a coarser cadence.) -
A bbox becomes many keyless GETs — throttled and capped. A bounding box is sampled to a
(lat, lon)grid atspacing_deg(default0.1°) and each point is one request. The backend throttles to the documented 30 requests per second limit and retries an HTTP429with exponential backoff. Before fetching it warns once the grid passes a soft threshold and raises aValueErrorpast a hard cap (max_points, default 400) — so a country-scale box never silently fires thousands of calls. Shrink the box or coarsenspacing_deg. -
PVGIS is not global. Coverage spans Europe, Africa, most of Asia, and the Americas, but excludes high latitudes and open sea. An out-of-coverage point returns an HTTP 4xx with a JSON
message: for a multi-point bbox the point is skipped with a warning (the in-coverage points are kept); for a single explicit point a clearValueErrornaming the coordinate is raised. A skipped point reflects whatever error PVGIS returned for it (most often out-of-coverage, but the warning quotes the actualmessage).
Attribution#
PVGIS data is free to reuse with attribution:
PVGIS © European Union, 2001–2024 — data from the JRC Photovoltaic Geographical Information System (PVGIS), https://re.jrc.ec.europa.eu/pvg_tools/.
The backend logs this citation once on a successful download().