About Points+
Methodology and calculation details
What is Points+?
Points+ is a context-adjusted scoring metric for NBA players, inspired by stats like OPS+ and wRC+ in baseball. It measures how a player's scoring output compares to the league average after accounting for the difficulty of their opponents.
A Points+ of 100 means a player scores exactly at the league average rate. A Points+ of 130 means a player scores 30% above average, while 80 means 20% below.
Why adjust raw scoring?
Raw points per game doesn't tell the whole story. A player who scores 28 PPG against elite defenses is arguably more impressive than one who scores 28 PPG against the league's weakest teams. Similarly, a player on a fast-paced team will have more possessions (and therefore more opportunities to score) than one on a slow-paced team.
Points+ adjusts for both of these factors to give a fairer comparison across all players.
The Formula
Points+ is calculated in three steps:
Step 1: Adjust each game
adjusted_pts = raw_pts × (league_avg_def_rating / opp_def_rating) × (league_avg_pace / opp_pace)- Opponent Defense: If the opponent has a lower (better) defensive rating than league average, the player's points are scaled up to credit them for scoring against a tough defense.
- Pace: If the opponent plays at a faster pace than average, points are scaled down since more possessions means more scoring opportunities.
Step 2: Compute adjusted PPG
adjusted_ppg = sum(adjusted_pts) / games_playedEach player's adjusted points are summed across all their games and divided by games played to get their adjusted points per game.
Step 3: Scale to league average = 100
Points+ = (player_adjusted_ppg / league_avg_adjusted_ppg) × 100The final Points+ value is the player's adjusted PPG divided by the league average adjusted PPG, scaled so that 100 represents the average qualifying player.
Key Inputs
| Input | Source | Description |
|---|---|---|
| DEF_RATING | Team Advanced Stats | Points allowed per 100 possessions. Lower = better defense. |
| PACE | Team Advanced Stats | Possessions per 48 minutes. Higher = faster game tempo. |
| PTS | Player Game Logs | Raw points scored in each individual game. |
| MATCHUP | Player Game Logs | Used to identify the opponent for each game. |
Qualifying Criteria
To appear on the leaderboard, a player must meet both of these thresholds:
- Minimum 20 games played — filters out players with small sample sizes
- Minimum 15 minutes per game — ensures players have meaningful playing time
This yields 315 qualifying players for the 2025-26 season.
Color Scale
Points+ values are color-coded for quick visual reference:
Limitations
- Opponent defensive rating and pace are season-level averages, not per-game values. A team's defense may vary game-to-game due to injuries, rest, or matchup strategy.
- The metric does not account for a player's own team context — a primary option on a bad team may have inflated volume compared to a secondary scorer on a great team.
- Points+ only measures scoring output. It does not capture playmaking, defense, rebounding, or other contributions.
Data Source
All data is sourced from the official NBA stats API via the nba_api Python package. The data pipeline fetches player game logs, team advanced statistics, and player biographical information for the 2025-26 regular season.
Data last updated: 2026-02-10