PVGIS — usage#
All examples go through the EarthLens facade with
data_source="pvgis" (alias "solar-pv"). The backend needs no credentials.
download() returns a long-format pandas.DataFrame and also writes it to
path as CSV (or Parquet — see below).
Pick a tool with variables=#
variables is a single-element list naming the product / tool:
variables |
Tool | What you get |
|---|---|---|
["seriescalc"] |
hourly series | Radiation (+ PV power) hour-by-hour over the year window |
["tmy"] |
typical meteorological year | One synthetic 8760-hour year of meteo variables |
from earthlens.earthlens import EarthLens
series = EarthLens(
data_source="pvgis",
variables=["seriescalc"],
start="2020-01-01",
end="2020-12-31",
point=(45.0, 8.0),
path="pvgis_out",
).download()
# series.columns -> time, G(i), H_sun, T2m, WS10m, Int, lat, lon, product
start / end set the seriescalc year window (startyear / endyear); the
tmy tool ignores the window (it is a multi-year synthesis).
Single point vs. a bbox grid#
- A single point — pass
point=(lat, lon). It wins over anylat_lim/lon_lim(including the whole-Earth defaults the facade injects), so the request is exactly that one coordinate and one keyless GET. - A bounding box — pass
lat_lim/lon_lim(oraoi=). The box is sampled to a(lat, lon)grid atspacing_deg(default0.1°); each grid point is one request.
grid = EarthLens(
data_source="pvgis",
variables=["seriescalc"],
start="2020-01-01",
end="2020-12-31",
lat_lim=[45.0, 45.5],
lon_lim=[8.0, 8.5],
spacing_deg=0.25, # 3x3 = 9 points -> 9 GETs
path="pvgis_grid",
).download()
Mind the request count
A bbox at a fine spacing_deg explodes into many keyless GETs, throttled to
≤30 req/s. The backend warns past a soft threshold and raises a
ValueError past max_points (default 400). Coarsen spacing_deg, shrink
the box, or raise max_points= deliberately if you really want a large grid.
PV-system knobs#
For seriescalc, switch on PV-power modelling and tune the array with keyword
arguments forwarded verbatim to the PVGIS query (they merge over the catalog
defaults):
| kwarg | PVGIS meaning |
|---|---|
pvcalculation=1 |
return PV system power P (W) |
peakpower=1 |
installed peak power (kWp) |
loss=14 |
system losses (%) |
angle=35 |
panel tilt (°) |
aspect=0 |
azimuth (° from south; 0 = south) |
raddatabase="PVGIS-SARAH3" |
radiation database (PVGIS-SARAH3 / PVGIS-ERA5 / PVGIS-NSRDB, region-dependent) |
pv = EarthLens(
data_source="pvgis",
variables=["seriescalc"],
start="2020-01-01",
end="2020-12-31",
point=(45.0, 8.0),
pvcalculation=1,
peakpower=1,
loss=14,
angle=35,
aspect=0,
path="pvgis_pv",
).download()
# now includes a 'P' column (PV system power, W)
Output format#
output_format="csv" (default) or "parquet" selects the on-disk table; the
Parquet path needs pyarrow. The written file is pvgis_<tool>.<ext> under
path.
Why aggregate= is rejected#
PVGIS returns an already-resolved hourly / TMY series, so there is no gridded
reduction to apply. The facade rejects a non-None aggregate= for this
tabular backend with NotImplementedError. Resample the returned DataFrame
in pandas (df.set_index("time").resample("1D").mean()) for a coarser cadence.
Coverage caveat#
PVGIS is not global — high latitudes and open sea are excluded. A
single out-of-coverage point= raises a ValueError naming the coordinate; an
out-of-coverage point inside a bbox grid is skipped with a warning while the
in-coverage points are kept.