xJawn NHL expected goals

← League

Vancouver Canucks

Pacific · 25-49-8, 58 pts

82 GP · 8th Pacific
2025-26 · regular season
Adjusts with rink filters
shots for◀ 5v5 offense
shots against5v5 defense ▶
How to read this map

One rink, both ends: what VAN generates on the left, what it concedes on the right. Every attempt is a Gaussian bump of height = its model xG, summed per game. The controls switch the surface (xG heatmapvs league, the league baseline at the same strength) and the markers: × goal · on net · missed · small blocked.

The page opens at 5v5; empty-net attempts are excluded throughout, and the strength buckets segregate them anyway — which is why the empty-net control greys out unless the view can actually contain one. Everything inside the outlined box moves with the filters; everything below it does not.

Observed production

5v5 · regular season
for against
axis spans ±31% of league average · centre = average · right = more
Goalsteam
131 3rd pctl210 100th pctl
Shotsteam
1,601 13th pctl1,945 94th pctl
Attemptsteam
3,504 22nd pctl4,038 91st pctl
xGteam
146.5 6th pctl200.7 100th pctl
xGF%share of team xG
42.2%3rd pctl
0% 50% = even split · gray = league middle 50% / 90% 100%

Percentiles and the gray spread rank against all 32 teams recomputed under the current filter — every bar and band here moves together, so a slice never ranks against a different slice's league.

Rolling xGF%

5v5 · regular season
Per-game chance share, smoothed. drag the slider to set the window

Model estimates

🔒 full season · 5v5
Season-long ratings — the filters above don't apply here. goals vs league average · bar grows from average
Shootingour skaters · on our shots
+4.625th pctl
3,504 attempts · 100% by rated shooters
Savingour goalies · on shots faced
Thatcher Demko +3.52 G · 863 shotsKevin Lankinen -1.14 G · 2,139 shotsNikita Tolopilo -0.31 G · 984 shotsJiri Patera -0.04 G · 52 shots
+2.019th pctl
Kevin Lankinen 2,139 · Nikita Tolopilo 984 · Thatcher Demko 863 · Jiri Patera 52 shots faced
Shooting againsttheir skaters · on shots faced
-11.53rd pctl
sign-flipped — positive means they shot worse than average
Saving againsttheir goalies · on our shots
-6.294th pctl
negative means their goalies stopped more than average
−23league average+23

These four are not centred at zero: the league average of each sits well away from it, and the two against columns barely vary between teams, since every team faces roughly average opposition. So the level of a bar is not the signal — its rank is. They are shown because they genuinely move adjusted xGF% below, and folding them into the two own-team rows would have hidden half of that.

Adjusted xGF%skill-weighted chance share
shooting +0.76 ppsaving against -1.02 ppshooting against -1.35 ppsaving +0.23 pp
40.8%3rd pctl · -1.37 pp
0% 50% = even split · gray = league middle 50% / 90% 100%
How it's built, and what it isn't
unadjusted 42.2% +shooting +0.76+saving against -1.02+shooting against -1.35+saving +0.23 = adjusted 40.8%

How it's builtEvery 5v5 shot is re-scored with σ(logit(xG) + shooter − goalie) and both ends re-summed. Both skill terms land on every shot — one team's for side, the other's against side — so the league share still averages 50%. The two moves are taken in that order and sum exactly to the total; shares don't decompose additively, so a side-by-side split would not close.

What it isn'tA descriptive re-score of shots already taken, not a forecast. Against future goal share the combined adjustment is indistinguishable from plain xGF% (+0.019 r, p = 0.192); only the shooting half shows a small honest lift (+0.026, p = 0.020), and the saving half contributes nothing forward-looking. The premise underneath is itself unestablished — xGF% over GF% is +0.040, p = 0.246. Read it as what this roster's skill was worth on these shots — nothing more.

The four segments are the four rows above, in order. They are four and not two because η puts both rating terms on every shot: the shots we took carry our shooters and the opposing goalie, and the shots we faced carry their shooters and ours. Over a full season the two “against” terms would sit near league average and contribute nothing — but the ratings are not centred at zero this season, so they do move the number, and hiding them inside a single “shots faced” figure would have left half the adjustment unexplained.

Season context

descriptive · not modeled
How the season was played, not how well. Not a modeled component: each is its own metric (a rate, a TOI share, or opponents' net xG-RAPM), shown with a league percentile only where one exists, never added together. Not a grade.
Ice timeshare by strength
5v5 80%PPPK
+0.7PP − PK min/60
Score stateTOI by game state
trail 44%tied 35%lead 21%
trails a lot
Goalie workloadstarter's share of shots
53%of 5v5 shots against
Schedule strengthopponents' net xG-RAPM
not available in the pipeline
0league average100 pctl
Full table · all numbers
FamilyStatValue (current slice)
Observed ◆ filtered Goals for / against 131 / 210
Observed ◆ filtered xG for / against 146.5 / 200.7
Observed ◆ filtered Shots for / against 1,601 / 1,945
Observed ◆ filtered Attempts for / against 3,504 / 4,038
Modeled 🔒 5v5 Shooting — our skaters · on our shots +4.6 G 25th pctl
Modeled 🔒 5v5 Saving — our goalies · on shots faced +2.0 G 19th pctl
Modeled 🔒 5v5 Shooting against — their skaters · on shots faced -11.5 G 3rd pctl
Modeled 🔒 5v5 Saving against — their goalies · on our shots -6.2 G 94th pctl
Modeled 🔒 5v5Unadjusted xGF%42.2%
Modeled 🔒 5v5↳ shooting shift+0.76 pp
Modeled 🔒 5v5↳ saving against shift-1.02 pp
Modeled 🔒 5v5↳ shooting against shift-1.35 pp
Modeled 🔒 5v5↳ saving shift+0.23 pp
Modeled 🔒 5v5Adjusted xGF% 40.8% 3rd pctl
ContextIce time — share by strength+0.7
ContextScore state — TOI by game statetrails a lot
ContextGoalie workload — starter's share of shots53%
ContextSchedule strength — opponents' net xG-RAPM

Observed values reflect the active rink filters; modeled values are fixed at their full-season 5v5 fit.

Modeled ratings come from joint__baseline_xg__42ccb89b (as of 2026-06-14) — a separate surface from the box-score xG model badged in the footer.