AI Solar Panel

PVGIS in 20 Minutes: Getting a Trustworthy Baseline Yield

The headline number PVGIS gives you is the least useful thing on the page. It’s a single annual figure, averaged over a decade of weather, that tells you nothing about whether your battery will fill in February or whether your inverter is going to clip on a cold clear June afternoon. The useful thing is underneath: a per-hour time series you can join to your own consumption data and actually model against.

This is a run through the tool for a UK roof, focused on which inputs move the answer and which are noise, and on getting the 8,760 rows out the other end.

Before you open the tab

Four things. Get them wrong and everything downstream is decoration.

Latitude and longitude, to three decimals. Postcode centroids are fine for radiation (the satellite grid is roughly 5 km) but the calculated horizon uses terrain data at about 90 m resolution, so put the pin on your actual roof. Right-click in Google Maps, copy the coordinates.

Roof pitch in degrees. Most UK houses built after 1930 sit between 30° and 45°, with 35° to 40° being the common case. A spirit-level app held against a rafter in the loft will get you within two degrees, which is close enough.

Azimuth, converted to PVGIS’s convention. This is where people quietly ruin their estimate. PVGIS uses 0° for due south, negative for east, positive for west. Almost every other tool you’ve used, including most inverter apps, uses 180° for south. So if your roof faces a compass bearing of 160°, the PVGIS azimuth is -20, not 160. Subtract 180 from the compass bearing and you’re done.

Peak DC power in kWp. Panel wattage times panel count, divided by 1000. Sixteen 440 W panels is 7.04 kWp. Use the DC number, not the inverter rating.

The run itself

Go to re.jrc.ec.europa.eu/pvg_tools/en/, drop the pin, and stay on the Grid connected tab.

Worked example throughout: a semi in Bristol at 51.454, -2.588. Four kWp of crystalline silicon, 35° pitch, dead south, default 14% system loss, SARAH3 radiation database, free-standing mounting. That returns:

Yearly PV energy production:            3733 kWh
Yearly in-plane irradiation:            1158.6 kWh/m2
Year-to-year variability:               148.2 kWh

Angle of incidence loss:                -2.94 %
Spectral effects:                       +1.12 %
Temperature and low irradiance loss:    -4.58 %
Total loss (including system loss):     -19.45 %

And the monthly breakdown, which is the part worth screenshotting into your notes:

MonthkWhMonthkWh
Jan103Jul502
Feb172Aug448
Mar296Sep349
Apr433Oct221
May512Nov108
Jun512Dec77

December is 15% of June. Any model that assumes you’ll run the house off solar year-round dies right there on the table.

Inputs that genuinely change the answer

System loss. The 14% default is the single biggest lever after array size, and it’s doing something subtler than most people assume. PVGIS models angle-of-incidence, spectral and temperature effects separately, as you can see in that loss block. The 14% is what’s left: DC and AC cabling, inverter conversion, module mismatch, soiling, availability. A 2026 install with a 97.5%-efficient hybrid inverter, short DC runs and per-orientation MPPTs does not lose 14% to those. Ten or eleven percent is closer. Change it to 10 and the same roof returns 3,907 kWh, a 174 kWh swing on nothing but a judgement call. Decide what you believe and write the reasoning down, because this number will haunt your payback spreadsheet.

Radiation database. The dropdown offers PVGIS-SARAH3 (satellite-derived, roughly 5 km, 2005 onwards) and PVGIS-ERA5 (reanalysis, coarser at around 30 km). SARAH3 covers every part of the UK including Shetland, though the satellite view angle gets oblique above about 57°N and quality drifts. ERA5 often reads a little high over cloudy maritime climates. Run both. If they agree within 2%, you have a solid number. If they disagree by 6%, that gap is your uncertainty band, and you should carry it through rather than pretending precision you don’t have.

Mounting position. Free-standing assumes air circulating behind the modules; building-integrated assumes none, so the modules run hotter. Standard UK rail-and-hook mounting on tiles has a 50 mm to 100 mm air gap and behaves as free-standing. Only pick building-integrated for genuine in-roof systems (GSE trays, solar tiles). The difference is small in our cool climate, around 1% to 2%, but it’s free accuracy.

Horizon. Leave “calculated horizon” ticked; it models the Mendips, the ridge behind the village, the valley you’re sitting in. What it absolutely does not model is the neighbour’s Leyland cypress. This matters more than the percentage suggests. At 51.45°N, the sun at solar noon on 21 December reaches an altitude of about 15.1°. A tree due south with an apparent elevation of 18° removes December entirely while costing you perhaps 3% of June. The annual headline barely flinches. Your winter battery strategy is destroyed. Measure your obstructions with a clinometer app at eight compass points and feed them in via the custom horizon field (values in degrees, starting at north, going clockwise).

Inputs that barely matter

Tilt is remarkably forgiving. Between 25° and 45° on a south-facing UK roof you’re within about 3% of optimal, so don’t agonise over whether the pitch is 36° or 39°. Azimuth is similar: 30° off south costs roughly 2%. Full east-west is where it bites. Splitting that same 4 kWp into 2 kWp east and 2 kWp west gives about 1,512 kWh and 1,568 kWh, totalling 3,080 kWh, or 82% of the south-facing case. (West typically edges east in the UK, since mornings run cloudier.)

PV technology: unless you’re buying CdTe or CIS, leave it on crystalline silicon. The difference for c-Si versus “unknown” is under a percent.

One thing PVGIS ignores entirely: inverter clipping. It models a DC array with no AC ceiling. For a 4 kWp array that’s harmless. For 6.4 kWp behind a 3.68 kW inverter (the G98 single-phase limit), it isn’t. Only the hourly export lets you see that, which brings us to the actual point.

Getting the 8,760 out

Switch to the Hourly data tab. Re-enter the same slope, azimuth, kWp and loss, tick PV power, set the year range wide (SARAH3 runs 2005 to 2023), choose CSV, download.

The file looks like this:

Latitude (decimal degrees):	51.454
Longitude (decimal degrees):	-2.588
Elevation (m):	32
Radiation database:	PVGIS-SARAH3
Slope: 35 deg.
Azimuth: 0 deg.
Nominal power of the PV system (c-Si) (kWp):	4.0
System losses (%):	14.0

time,P,G(i),H_sun,T2m,WS10m,Int
20210621:0410,52.11,18.44,4.21,12.02,1.93,0.0
20210621:0510,441.67,151.88,12.64,12.44,2.07,0.0
20210621:1210,3187.40,912.55,59.83,21.31,3.42,0.0

Three gotchas, all of which will silently corrupt your model:

P is watts, not kilowatts. Sum the column across a year and divide by 1000.

The timestamps are UTC. Your smart meter data is in Europe/London, which means BST for seven months of the year. Join them raw and every summer generation peak lands an hour early, which is exactly the kind of error that makes a battery simulation look plausible and be wrong.

The minutes aren’t zero. You’ll see :0010 or :0011, because PVGIS stamps the centre of the satellite’s observation window rather than the top of the hour. Round to the hour before joining.

In pandas:

import pandas as pd

df = pd.read_csv("Timeseries_51.454_-2.588_SA3_4kWp_crystSi_14_35deg_0deg_2015_2023.csv",
                 skiprows=10, skipfooter=11, engine="python")
df["time"] = pd.to_datetime(df["time"], format="%Y%m%d:%H%M").dt.round("h")
df = df.set_index("time").tz_localize("UTC").tz_convert("Europe/London")
df["kwh"] = df["P"] / 1000
print(df["kwh"].resample("YE").sum().round(0))

Count the header and footer lines yourself; they shift between PVGIS versions and skiprows=10 is a guess that will bite you.

Now the clipping question. For a 6.4 kWp version of this roof behind a 3.68 kW inverter, df["P"].clip(upper=3680) removes about 95 kWh a year, roughly 1.6%, concentrated in maybe 300 hours between April and August. Worth knowing before you spend £900 on two extra panels.

You can skip the browser entirely once you know the parameters. The non-interactive endpoint takes the same arguments:

https://re.jrc.ec.europa.eu/api/v5_3/seriescalc?lat=51.454&lon=-2.588
&startyear=2015&endyear=2023&pvcalculation=1&peakpower=4&loss=14
&angle=35&aspect=0&mountingplace=free&outputformat=csv

Change lat/lon and you can sweep every roof on the street. If you’re already in Python, pvlib.iotools.get_pvgis_hourly() wraps this and hands back a dataframe directly, though check its azimuth convention against yours before trusting the output.

Two adjustments PVGIS won’t make for you

Multiple orientations need multiple runs. PVGIS models one plane at a time, so an east-west roof means two downloads added together. That’s accurate for a dual-MPPT inverter and optimistic for a single string spanning both faces.

Snow and soiling sit inside your 14%, unmeasured. UK snow losses are trivial in the south and non-trivial in the Pennines. Bird mess under a flight path is not trivial anywhere.

Then check it against something real

A PVGIS UK solar estimate is a physics model fed satellite radiation, not a measurement of your house. Find a system near you on PVOutput.org with a known kWp and orientation, normalise both to kWh/kWp, and compare. If a real array two miles away has been producing 880 kWh/kWp and PVGIS says 933, your 14% loss assumption is probably too generous and the gap is telling you something specific about local shading or module degradation. For the wider question of how to turn a baseline like this into a forecast you’d actually stake money on, the pillar on forecasting what your roof will actually generate covers the calibration side.

Run the same coordinates through both SARAH3 and ERA5 tonight, and see how far apart they land. That number is the honest error bar on everything else you’re about to build.