Post-Up Play Analysis
Post-Up Analytics: Low Post Scoring and Passing
Post-up play represents one of basketball's most fundamental offensive strategies, combining physical positioning, technical skill, and strategic decision-making. This analysis explores the analytical frameworks for evaluating post-up efficiency, the evolution of low post play in modern basketball, and the metrics that define elite post players.
Understanding Post-Up Plays
Definition and Mechanics
A post-up play occurs when an offensive player establishes position with their back to the basket, typically within 12 feet of the rim. The player receives the ball in this position and attempts to score through a variety of moves including:
- Drop steps: Pivoting toward the baseline for a power move
- Hook shots: One-handed sweeping shots over the defender
- Up-and-under moves: Pump fakes followed by baseline drives
- Face-up jumpers: Turning to face the basket for mid-range shots
- Post passes: Passing out to perimeter shooters when double-teamed
Strategic Context
Post-ups serve multiple offensive purposes:
- Exploiting size/strength mismatches
- Drawing double teams to create open perimeter shots
- Slowing game tempo and controlling possession
- Generating high-percentage shots near the rim
- Creating foul-drawing opportunities
Key Insight: While post-ups have declined from 20% of NBA possessions in 2004-05 to approximately 7% in recent seasons, they remain crucial for specific matchup exploitation and offensive diversity.
Post-Up Efficiency Metrics
Core Performance Indicators
1. Points Per Possession (PPP)
The primary efficiency metric for post-up plays:
PPP = Total Points Scored / Total Post-Up Possessions
Benchmarks:
- Elite: 1.00+ PPP (90th percentile)
- Above Average: 0.90-0.99 PPP
- Average: 0.85-0.89 PPP
- Below Average: <0.85 PPP
2. Post-Up Frequency and Volume
Post-Up Frequency = Post-Up Possessions / Total Offensive Possessions
High-volume post players (5+ post-ups per game) face adjusted defensive schemes, making efficiency maintenance more challenging.
3. Shooting Efficiency Breakdown
- Field Goal Percentage: Shot quality from post position
- Free Throw Rate: (FTA / FGA) - Drawing fouls indicator
- Turnover Rate: Lost possessions per 100 post-up attempts
- Assist Rate: Percentage of post-ups resulting in assists (playmaking ability)
4. Shot Quality Metrics
- At-Rim Conversion: FG% on shots within 3 feet
- Contact Frequency: Rate of defensive contact/fouls drawn
- Second Chance Rate: Offensive rebounds on missed post attempts
Advanced Analytics
Synergy Sports Play Type Data
Synergy Sports Technology tracks post-up possessions with detailed classifications:
- Shot type (hook, jump shot, layup, dunk)
- Pass outcome (assist, hockey assist, turnover)
- Defensive pressure (single coverage, double team, front)
- Result efficiency (points per possession by scenario)
Expected Points Added (EPA)
EPA = Actual Points - Expected Points (based on league average for possession type)
Measures how much value a player adds above replacement-level post-up efficiency.
Context Matters: Elite post players average 0.92-1.05 PPP, compared to 1.10+ PPP for transition opportunities and 1.15+ PPP for spot-up three-pointers, highlighting why post-ups have declined strategically.
Python Analysis with NBA API
Using the nba_api library to extract and analyze post-up data:
Installation and Setup
pip install nba_api pandas numpy matplotlib seaborn
Post-Up Data Extraction
from nba_api.stats.endpoints import playerdashptpass, playerdashptshotdefend, leaguedashptstats
from nba_api.stats.static import players, teams
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# Get player post-up statistics
def get_post_up_stats(season='2023-24'):
"""
Extract post-up play type statistics
"""
# Using LeagueDashPtStats for post-up tracking data
post_stats = leaguedashptstats.LeagueDashPtStats(
season=season,
per_mode_simple='PerGame',
player_or_team='Player',
pt_measure_type='PostTouch' # Post touches tracking
)
df = post_stats.get_data_frames()[0]
# Calculate efficiency metrics
df['PPP'] = df['PTS'] / df['POST_TOUCHES']
df['PASS_RATE'] = df['PASSES_MADE'] / df['POST_TOUCHES']
df['SCORE_RATE'] = df['FGA'] / df['POST_TOUCHES']
return df
# Analyze post-up efficiency by player
def analyze_post_efficiency(df, min_touches=3.0):
"""
Filter and rank players by post-up efficiency
"""
# Filter for significant volume
qualified = df[df['POST_TOUCHES'] >= min_touches].copy()
# Sort by points per possession
qualified = qualified.sort_values('PPP', ascending=False)
print("Top 15 Post-Up Scorers by Efficiency (PPP):")
print(qualified[['PLAYER_NAME', 'POST_TOUCHES', 'PTS', 'FGA',
'PASSES_MADE', 'PPP', 'PASS_RATE']].head(15))
return qualified
# Get shooting data from post-ups
def get_post_shooting_data(player_id, season='2023-24'):
"""
Detailed shot chart data for post-up attempts
"""
from nba_api.stats.endpoints import shotchartdetail
shot_data = shotchartdetail.ShotChartDetail(
team_id=0,
player_id=player_id,
season_nullable=season,
season_type_all_star='Regular Season',
context_measure_simple='FGA'
)
shots_df = shot_data.get_data_frames()[0]
# Filter for post-up area shots (paint, within 10 feet)
post_shots = shots_df[
(shots_df['SHOT_DISTANCE'] <= 10) &
(shots_df['SHOT_ZONE_BASIC'].isin(['In The Paint (Non-RA)', 'Restricted Area']))
]
return post_shots
# Visualize post-up efficiency distribution
def plot_post_efficiency(df):
"""
Create visualization of post-up efficiency metrics
"""
fig, axes = plt.subplots(2, 2, figsize=(15, 12))
# 1. PPP Distribution
axes[0, 0].hist(df['PPP'], bins=30, edgecolor='black', alpha=0.7)
axes[0, 0].axvline(df['PPP'].median(), color='red', linestyle='--',
label=f'Median: {df["PPP"].median():.3f}')
axes[0, 0].set_xlabel('Points Per Possession')
axes[0, 0].set_ylabel('Frequency')
axes[0, 0].set_title('Post-Up Efficiency Distribution')
axes[0, 0].legend()
# 2. Post Touches vs PPP
axes[0, 1].scatter(df['POST_TOUCHES'], df['PPP'], alpha=0.6)
axes[0, 1].set_xlabel('Post Touches Per Game')
axes[0, 1].set_ylabel('Points Per Possession')
axes[0, 1].set_title('Volume vs Efficiency')
# Add trend line
z = np.polyfit(df['POST_TOUCHES'], df['PPP'], 1)
p = np.poly1d(z)
axes[0, 1].plot(df['POST_TOUCHES'], p(df['POST_TOUCHES']),
"r--", alpha=0.8, label='Trend')
axes[0, 1].legend()
# 3. Pass Rate vs Score Rate
axes[1, 0].scatter(df['SCORE_RATE'], df['PASS_RATE'], alpha=0.6)
axes[1, 0].set_xlabel('Scoring Rate (FGA/Touch)')
axes[1, 0].set_ylabel('Passing Rate (Passes/Touch)')
axes[1, 0].set_title('Scoring vs Playmaking Tendency')
# 4. Efficiency by Position
if 'PLAYER_POSITION' in df.columns:
position_eff = df.groupby('PLAYER_POSITION')['PPP'].mean().sort_values()
axes[1, 1].barh(position_eff.index, position_eff.values)
axes[1, 1].set_xlabel('Average PPP')
axes[1, 1].set_title('Post-Up Efficiency by Position')
plt.tight_layout()
plt.savefig('post_up_analysis.png', dpi=300, bbox_inches='tight')
plt.show()
# Calculate advanced post-up metrics
def calculate_advanced_metrics(df):
"""
Compute advanced efficiency and impact metrics
"""
# League average PPP for comparison
league_avg_ppp = df['PPP'].mean()
df['PPP_ABOVE_AVG'] = df['PPP'] - league_avg_ppp
df['TOTAL_IMPACT'] = df['POST_TOUCHES'] * df['PPP_ABOVE_AVG']
# Efficiency percentile
df['PPP_PERCENTILE'] = df['PPP'].rank(pct=True) * 100
# Classify player types
def classify_post_player(row):
if row['SCORE_RATE'] > 0.5:
return 'Scorer'
elif row['PASS_RATE'] > 0.4:
return 'Facilitator'
else:
return 'Balanced'
df['PLAYER_TYPE'] = df.apply(classify_post_player, axis=1)
return df
# Main execution
if __name__ == '__main__':
# Extract data
print("Fetching post-up statistics...")
post_df = get_post_up_stats(season='2023-24')
# Analyze efficiency
qualified_players = analyze_post_efficiency(post_df, min_touches=3.0)
# Calculate advanced metrics
advanced_df = calculate_advanced_metrics(qualified_players)
# Display top performers
print("\nTop 10 Post Players by Total Impact:")
print(advanced_df[['PLAYER_NAME', 'POST_TOUCHES', 'PPP',
'TOTAL_IMPACT', 'PLAYER_TYPE']].head(10))
# Create visualizations
plot_post_efficiency(qualified_players)
# Export results
advanced_df.to_csv('post_up_analysis_2023-24.csv', index=False)
print("\nAnalysis complete. Results saved to post_up_analysis_2023-24.csv")
Historical Trend Analysis
import pandas as pd
import matplotlib.pyplot as plt
def analyze_post_up_trends(start_season='2013-14', end_season='2023-24'):
"""
Track the evolution of post-up play across multiple seasons
"""
seasons = []
avg_post_touches = []
avg_ppp = []
total_possessions = []
# Generate season strings
start_year = int(start_season.split('-')[0])
end_year = int(end_season.split('-')[0])
for year in range(start_year, end_year + 1):
season = f"{year}-{str(year+1)[2:]}"
try:
df = get_post_up_stats(season=season)
seasons.append(season)
avg_post_touches.append(df['POST_TOUCHES'].mean())
avg_ppp.append(df['PPP'].mean())
total_possessions.append(df['POST_TOUCHES'].sum())
print(f"Processed {season}")
except Exception as e:
print(f"Error processing {season}: {e}")
continue
# Create trend dataframe
trends_df = pd.DataFrame({
'Season': seasons,
'Avg_Post_Touches': avg_post_touches,
'Avg_PPP': avg_ppp,
'Total_Post_Possessions': total_possessions
})
# Calculate year-over-year changes
trends_df['Post_Touch_Change'] = trends_df['Avg_Post_Touches'].pct_change() * 100
# Visualization
fig, axes = plt.subplots(1, 2, figsize=(16, 6))
# Post-up frequency decline
axes[0].plot(trends_df['Season'], trends_df['Avg_Post_Touches'],
marker='o', linewidth=2, markersize=8)
axes[0].set_xlabel('Season', fontsize=12)
axes[0].set_ylabel('Average Post Touches Per Game', fontsize=12)
axes[0].set_title('Decline of Post-Up Play (2013-2024)', fontsize=14, fontweight='bold')
axes[0].tick_params(axis='x', rotation=45)
axes[0].grid(True, alpha=0.3)
# Efficiency trends
axes[1].plot(trends_df['Season'], trends_df['Avg_PPP'],
marker='s', linewidth=2, markersize=8, color='green')
axes[1].set_xlabel('Season', fontsize=12)
axes[1].set_ylabel('Average Points Per Possession', fontsize=12)
axes[1].set_title('Post-Up Efficiency Over Time', fontsize=14, fontweight='bold')
axes[1].tick_params(axis='x', rotation=45)
axes[1].grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('post_up_trends.png', dpi=300, bbox_inches='tight')
plt.show()
return trends_df
# Execute trend analysis
trends = analyze_post_up_trends()
print("\nPost-Up Trends Summary:")
print(trends)
Statistical Modeling with R (hoopR)
Using R and the hoopR package for advanced statistical analysis of post-up efficiency:
Setup and Data Loading
# Install required packages
install.packages(c("hoopR", "tidyverse", "lme4", "broom", "ggplot2", "corrplot"))
library(hoopR)
library(tidyverse)
library(lme4)
library(broom)
library(ggplot2)
library(corrplot)
# Load NBA play-by-play data
load_nba_data <- function(seasons = 2024) {
# Get play-by-play data
pbp_data <- load_nba_pbp(seasons = seasons)
# Filter for post-up plays (using shot location and play description)
post_plays <- pbp_data %>%
filter(
shooting_play == TRUE,
shot_distance <= 10,
str_detect(type_text, "(?i)(post|hook|layup|dunk)"),
coordinate_x != "NA"
) %>%
mutate(
post_shot = case_when(
shot_distance <= 3 ~ "At Rim",
shot_distance <= 10 ~ "Paint",
TRUE ~ "Other"
),
shot_made = scoring_play == TRUE
)
return(post_plays)
}
# Load player tracking data
get_player_stats <- function(season = 2024) {
# Get player box scores
player_stats <- nba_leaguedashplayerstats(
season = paste0(season-1, "-", substr(season, 3, 4))
)
return(player_stats)
}
# Execute data loading
post_data <- load_nba_data(seasons = 2024)
player_stats <- get_player_stats(season = 2024)
Regression Analysis: Post-Up Efficiency Predictors
# Prepare data for regression modeling
prepare_regression_data <- function(post_plays, player_stats) {
# Aggregate post-up statistics by player
player_post_stats <- post_plays %>%
group_by(athlete_id_1, athlete_id_1_name) %>%
summarize(
post_attempts = n(),
post_makes = sum(shot_made),
fg_pct = mean(shot_made),
avg_shot_distance = mean(shot_distance, na.rm = TRUE),
at_rim_pct = sum(post_shot == "At Rim") / n(),
.groups = 'drop'
) %>%
filter(post_attempts >= 50) %>% # Minimum volume threshold
rename(player_id = athlete_id_1, player_name = athlete_id_1_name)
# Merge with player physical/performance data
merged_data <- player_post_stats %>%
left_join(
player_stats %>% select(player_id, height, weight, position,
usage_rate, assist_rate, turnover_rate),
by = "player_id"
) %>%
na.omit()
# Convert height to inches
merged_data <- merged_data %>%
mutate(
height_inches = as.numeric(str_extract(height, "\\d+")) * 12 +
as.numeric(str_extract(height, "-(\\d+)"))
)
return(merged_data)
}
# Build regression model
model_data <- prepare_regression_data(post_data, player_stats)
# Multiple linear regression: Predicting post-up FG%
post_efficiency_model <- lm(
fg_pct ~ height_inches + weight + at_rim_pct + avg_shot_distance +
usage_rate + assist_rate + position,
data = model_data
)
# Model summary
summary(post_efficiency_model)
# Extract coefficients
model_coefs <- tidy(post_efficiency_model, conf.int = TRUE)
print(model_coefs)
# Visualize coefficients
ggplot(model_coefs %>% filter(term != "(Intercept)"),
aes(x = reorder(term, estimate), y = estimate)) +
geom_point(size = 4, color = "steelblue") +
geom_errorbar(aes(ymin = conf.low, ymax = conf.high),
width = 0.2, linewidth = 1) +
geom_hline(yintercept = 0, linetype = "dashed", color = "red") +
coord_flip() +
labs(
title = "Post-Up Efficiency Predictors",
subtitle = "Regression Coefficients with 95% Confidence Intervals",
x = "Predictor Variables",
y = "Coefficient Estimate (Effect on FG%)"
) +
theme_minimal(base_size = 14)
ggsave("post_efficiency_predictors.png", width = 10, height = 8, dpi = 300)
Mixed Effects Model: Player and Team Effects
# Multi-level model accounting for player and team variation
library(lme4)
# Prepare hierarchical data
hierarchical_data <- post_plays %>%
mutate(
shot_value = case_when(
score_value == 3 ~ 3,
score_value == 2 ~ 2,
TRUE ~ 0
),
defender_distance = case_when(
qtr <= 2 ~ "First Half",
TRUE ~ "Second Half"
)
) %>%
filter(!is.na(athlete_id_1), !is.na(team_id))
# Mixed effects logistic regression
mixed_model <- glmer(
shot_made ~ shot_distance + at_rim_pct + (1 | athlete_id_1) + (1 | team_id),
data = hierarchical_data %>%
filter(post_shot %in% c("At Rim", "Paint")),
family = binomial(link = "logit"),
control = glmerControl(optimizer = "bobyqa")
)
# Model summary
summary(mixed_model)
# Extract random effects (player-specific deviations)
player_effects <- ranef(mixed_model)$athlete_id_1 %>%
rownames_to_column("player_id") %>%
rename(player_effect = `(Intercept)`) %>%
arrange(desc(player_effect))
print("Top 15 Players by Random Effect (Post-Up Skill Above Average):")
print(head(player_effects, 15))
# Visualize random effects distribution
ggplot(player_effects, aes(x = player_effect)) +
geom_histogram(bins = 30, fill = "darkgreen", alpha = 0.7, color = "black") +
geom_vline(xintercept = 0, linetype = "dashed", color = "red", linewidth = 1) +
labs(
title = "Distribution of Player-Specific Post-Up Skill",
subtitle = "Random Effects from Mixed Model",
x = "Player Effect (Log-Odds Scale)",
y = "Frequency"
) +
theme_minimal(base_size = 14)
ggsave("player_effects_distribution.png", width = 10, height = 6, dpi = 300)
Shot Location Heatmap Analysis
# Create shot location heatmap for post-up attempts
library(ggplot2)
library(hexbin)
# Filter for post area shots
post_shots_spatial <- post_plays %>%
filter(
!is.na(coordinate_x),
!is.na(coordinate_y),
shot_distance <= 12
) %>%
mutate(
shot_outcome = ifelse(shot_made, "Made", "Missed")
)
# Create heatmap
ggplot(post_shots_spatial, aes(x = coordinate_x, y = coordinate_y)) +
stat_density_2d(aes(fill = ..level..), geom = "polygon", alpha = 0.6) +
scale_fill_gradient(low = "yellow", high = "red", name = "Shot Density") +
facet_wrap(~shot_outcome) +
labs(
title = "Post-Up Shot Location Heatmap",
subtitle = "Spatial Distribution of Made vs Missed Shots",
x = "Court X Coordinate",
y = "Court Y Coordinate"
) +
theme_minimal(base_size = 14) +
theme(legend.position = "bottom")
ggsave("post_shot_heatmap.png", width = 12, height = 6, dpi = 300)
# Calculate efficiency by court zone
zone_efficiency <- post_shots_spatial %>%
mutate(
zone = case_when(
abs(coordinate_x) < 4 & coordinate_y < 5 ~ "Restricted Area",
abs(coordinate_x) < 8 & coordinate_y < 10 ~ "Low Post",
coordinate_y < 10 ~ "Mid Post",
TRUE ~ "High Post"
)
) %>%
group_by(zone) %>%
summarize(
attempts = n(),
fg_pct = mean(shot_made),
avg_distance = mean(shot_distance),
.groups = 'drop'
) %>%
arrange(desc(fg_pct))
print("Post-Up Efficiency by Court Zone:")
print(zone_efficiency)
# Visualize zone efficiency
ggplot(zone_efficiency, aes(x = reorder(zone, fg_pct), y = fg_pct, fill = zone)) +
geom_col(color = "black", linewidth = 0.5) +
geom_text(aes(label = sprintf("%.1f%%", fg_pct * 100)),
vjust = -0.5, size = 5, fontface = "bold") +
scale_y_continuous(labels = scales::percent, limits = c(0, 0.7)) +
labs(
title = "Post-Up Shooting Efficiency by Court Zone",
x = "Court Zone",
y = "Field Goal Percentage"
) +
theme_minimal(base_size = 14) +
theme(legend.position = "none")
ggsave("zone_efficiency.png", width = 10, height = 6, dpi = 300)
Time Series Analysis: Within-Game Trends
# Analyze post-up efficiency across game situations
game_situation_analysis <- post_plays %>%
mutate(
quarter = qtr,
time_remaining = period_seconds_remaining,
score_margin = score_value - lag(score_value, default = 0)
) %>%
group_by(quarter) %>%
summarize(
attempts = n(),
fg_pct = mean(shot_made),
avg_shot_distance = mean(shot_distance, na.rm = TRUE),
.groups = 'drop'
)
print("Post-Up Efficiency by Quarter:")
print(game_situation_analysis)
# Visualize quarter-by-quarter trends
ggplot(game_situation_analysis, aes(x = factor(quarter), y = fg_pct, group = 1)) +
geom_line(linewidth = 1.5, color = "darkblue") +
geom_point(size = 4, color = "darkred") +
geom_text(aes(label = sprintf("%.1f%%", fg_pct * 100)),
vjust = -1, size = 4, fontface = "bold") +
scale_y_continuous(labels = scales::percent, limits = c(0.3, 0.6)) +
labs(
title = "Post-Up Efficiency Across Game Quarters",
subtitle = "How does post-up effectiveness change throughout the game?",
x = "Quarter",
y = "Field Goal Percentage"
) +
theme_minimal(base_size = 14)
ggsave("quarter_efficiency.png", width = 10, height = 6, dpi = 300)
Correlation Analysis
# Examine correlations between post-up metrics and team success
library(corrplot)
# Aggregate team-level post statistics
team_post_stats <- post_plays %>%
group_by(team_id) %>%
summarize(
post_freq = n(),
post_fg_pct = mean(shot_made),
at_rim_rate = sum(post_shot == "At Rim") / n(),
avg_shot_distance = mean(shot_distance, na.rm = TRUE),
.groups = 'drop'
)
# Merge with team performance metrics
team_performance <- player_stats %>%
group_by(team_id) %>%
summarize(
team_off_rating = mean(off_rating, na.rm = TRUE),
team_def_rating = mean(def_rating, na.rm = TRUE),
team_net_rating = team_off_rating - team_def_rating,
.groups = 'drop'
)
team_analysis <- team_post_stats %>%
left_join(team_performance, by = "team_id") %>%
na.omit()
# Correlation matrix
cor_matrix <- cor(team_analysis %>% select(-team_id))
# Visualize correlations
corrplot(cor_matrix, method = "color", type = "upper",
addCoef.col = "black", number.cex = 0.8,
tl.col = "black", tl.srt = 45,
title = "Correlation: Post-Up Metrics vs Team Performance",
mar = c(0, 0, 2, 0))
The Decline and Evolution of Post Play
Historical Context
Post-up play dominated NBA offense from the 1980s through the mid-2000s, with elite big men serving as offensive centerpieces:
Era Breakdown:
- 1980s-1990s (Peak Era): 25-30% of possessions featured post-ups
- 2000-2010 (Traditional Era): 18-22% post-up frequency
- 2010-2015 (Transition): 12-16% as pace-and-space emerged
- 2015-Present (Modern Era): 6-8% with emphasis on three-point shooting
Statistical Drivers of Decline
1. Efficiency Comparison
| Play Type | Points Per Possession | Relative Efficiency |
|---|---|---|
| Spot-Up Three-Pointer | 1.15 | +23% vs Post-Up |
| Transition | 1.18 | +26% vs Post-Up |
| Pick-and-Roll | 0.98 | +5% vs Post-Up |
| Post-Up | 0.93 | Baseline |
| Isolation | 0.89 | -4% vs Post-Up |
2. Pace and Spacing Revolution
Mathematical advantage of three-point shooting:
Expected Value = FG% × Points Per Shot
Post-Up (2pt): 0.46 × 2 = 0.92 points
Corner Three: 0.38 × 3 = 1.14 points (+24% advantage)
3. Defensive Adaptation
Modern defenses have evolved to neutralize post-ups:
- Fronting: Denying entry passes to prevent post touches
- Quick doubles: Immediate help defense from weak-side corners
- Zone principles: Packing the paint with multiple defenders
- Switching: Versatile defenders who can match up with various sizes
Tactical Evolution
From Primary Option to Complementary Weapon
Post-ups have transitioned from offensive foundations to situational tactics:
Traditional Role (Pre-2010)
- Primary offensive action
- Isolation-based possessions
- Clock management tool
- 15-20 seconds per possession
Modern Application (2015-Present)
- Mismatch exploitation
- Integrated within motion offenses
- Quick decision-making emphasis
- 8-12 seconds per possession
Hybrid Big Men
The modern game rewards versatile big men who combine post skills with perimeter abilities:
- Stretch Bigs: Post threats who space to the three-point line (e.g., Brook Lopez, Karl-Anthony Towns)
- Playmaking Bigs: Post passers who initiate offense from the elbow (e.g., Nikola Jokic, Domantas Sabonis)
- Face-Up Bigs: Players who attack from the perimeter after post-ups (e.g., Anthony Davis, Giannis Antetokounmpo)
Key Transformation: The average NBA center's three-point attempt rate increased from 3% (2010) to 23% (2024), reflecting the tactical shift from traditional post play to perimeter-oriented offense.
Elite Post Players Analysis
Historical Legends
Dominant Post Scorers (1990-2010)
| Player | Era | Post-Up PPG | FG% in Post | Signature Moves |
|---|---|---|---|---|
| Shaquille O'Neal | 1992-2011 | 18-22 | 58% | Drop step, power dunks, seal positioning |
| Tim Duncan | 1997-2016 | 12-16 | 52% | Bank shot, drop step, up-and-under |
| Hakeem Olajuwon | 1984-2002 | 15-20 | 51% | Dream Shake, pivot moves, fadeaways |
| Kevin Garnett | 1995-2016 | 10-14 | 49% | Turnaround jumper, face-up drives |
| Pau Gasol | 2001-2019 | 10-13 | 53% | High post passing, hook shots |
Modern Post Excellence (2020-2024)
Joel Embiid: Dominant Two-Way Center
Post-Up Statistics (2023-24):
- 5.2 post-up possessions per game (League leader)
- 1.08 PPP (Elite efficiency - 88th percentile)
- 54% FG on post-up shots
- Free throw rate: 0.62 (exceptional foul-drawing)
Analytical Strengths:
- Size advantage: 7'0", 280 lbs dominates physically
- Versatile moves: Hook shots, fadeaways, power finishes
- Drawing gravity: 42% of post-ups result in double teams
- Passing reads: 1.2 assists per post-up touch (strong playmaking)
Impact: Embiid's post-up threat forces defensive adjustments that create three-point opportunities for teammates, generating an additional 0.18 PPP value through kick-out passes.
Nikola Jokic: Playmaking Revolutionary
Post-Up Statistics (2023-24):
- 4.8 post-up possessions per game
- 1.15 PPP (Elite scoring + passing efficiency)
- 58% FG on post-up shots
- 2.3 assists per game from post position
Analytical Strengths:
- Elite passing vision: Leads all centers in assist rate from post
- Soft touch: Hook shots and floaters at 62% efficiency
- Decision-making: Turnover rate of just 9% on post touches
- Versatility: Can face up, shoot from elbow, or drive baseline
Impact: Jokic's post-up possessions generate 1.32 expected points when accounting for both direct scoring and assist value—the highest in the NBA.
Anthony Davis: Mobile Post Scorer
Post-Up Statistics (2023-24):
- 3.6 post-up possessions per game
- 0.98 PPP
- 50% FG on post-up shots
- Quick decisions: Averages 3.2 seconds per touch
Analytical Strengths:
- Mobility: Transitions quickly from post to perimeter
- Face-up threat: 35% of post touches end in face-up jumpers
- Rim-running: Combines post seals with pick-and-roll actions
- Defensive versatility: Can switch onto guards after post actions
Comparative Analysis: Elite vs Average
| Metric | Elite Post Players | Average Post Players | Difference |
|---|---|---|---|
| PPP | 1.05 | 0.87 | +0.18 (21%) |
| FG% | 54% | 44% | +10% |
| Turnover Rate | 11% | 18% | -7% |
| Free Throw Rate | 0.48 | 0.32 | +0.16 |
| Assist Rate | 18% | 9% | +9% |
| Double Team Rate | 38% | 15% | +23% |
Skill Components of Elite Post Play
1. Footwork and Positioning
- Sealing: Using body leverage to establish deep position
- Pivot efficiency: Creating shooting angles through precise footwork
- Balance: Maintaining control through contact
2. Touch and Finishing
- Soft hands: Converting difficult angles into scores
- Arc control: High-arcing shots over length
- Body control: Finishing through fouls
3. Decision-Making
- Read speed: Recognizing double teams within 1-2 seconds
- Passing lanes: Finding open shooters from difficult angles
- Shot selection: Taking high-quality attempts
4. Physical Tools
- Strength: Moving defenders for position
- Length: Shooting over contests
- Conditioning: Sustaining post play throughout games
Modern Strategic Applications
When Post-Ups Are Most Effective
1. Mismatch Exploitation
Scenario: Smaller defender switches onto a post player
Expected Value: 1.15-1.25 PPP (40-50% efficiency increase)
Key Factors:
- Height differential of 4+ inches
- Strength advantage allowing deep position
- Quick recognition and entry pass timing
Example: Joel Embiid vs a 6'3" guard generates 1.24 PPP vs 1.05 PPP against typical center matchups.
2. Late-Clock Situations
Scenario: Shot clock under 7 seconds, need a quality shot
Expected Value: 0.92 PPP vs 0.78 PPP for late-clock isolation
Advantages:
- Proximity to basket increases success probability
- Foul-drawing opportunity in critical moments
- Less defensive preparation time
3. Tempo Control
Scenario: Leading late, need to drain clock
Strategic Value: Uses 14-18 seconds per possession vs 11-13 for perimeter actions
Implementation:
- Enter post at 12-14 seconds on shot clock
- Work for high-percentage shot or foul
- Minimize opponent's remaining possession time
4. Playoff Pressure Situations
Context: Playoff defenses are more physical and prepared
Post-Up Advantage:
- Higher foul rate in physical playoff games (+12% vs regular season)
- Less dependent on perimeter shooting variance
- Creates second-chance opportunities (offensive rebounding)
Data: Elite post players increase PPP by 0.08 in playoffs vs regular season, while three-point shooters decrease by 0.06 PPP.
Integration with Modern Offense
Post-Up as Secondary Action
Motion Offense Integration:
- Initial Action: Pick-and-roll or dribble handoff creates defensive rotation
- Post Seal: Big man seals mismatched defender during rotation
- Quick Entry: Pass delivered within 2 seconds to prevent help defense
- Decision: Score, kick out to open shooter, or reset
Efficiency Gain: Post-ups off motion actions generate 1.04 PPP vs 0.91 PPP for static post-ups.
High-Low Actions
Structure: One big at high post (elbow), one at low post (block)
Advantages:
- Passing angles: High post can hit low post over defense
- Decision-making: High post reads defense and delivers or shoots
- Spacing: Creates driving lanes for guards
Modern Implementation: High post often at three-point line (stretch big) creating vertical spacing while maintaining passing options.
Post Splits and Cuts
Action: Perimeter players cut off post player as screener
Options:
- Post passes to cutter for layup (35% of actions)
- Defense helps, post player scores (28%)
- Perimeter shooter gets open look (37%)
Expected Value: 1.12 PPP for post-split actions (combining all outcomes).
Analytics-Driven Post-Up Strategy
Shot Selection Optimization
| Post-Up Shot Type | Frequency | FG% | PPP | Recommendation |
|---|---|---|---|---|
| Hook shot (3-6 ft) | 28% | 52% | 1.04 | Emphasize |
| Drop step layup (<3 ft) | 22% | 61% | 1.22 | Maximize |
| Turnaround jumper (8-12 ft) | 31% | 41% | 0.82 | Minimize |
| Up-and-under (3-5 ft) | 12% | 58% | 1.16 | Situational |
| Pass out to shooter | 7% | - | 1.18 | Increase |
Defensive Adjustment Response
If Defense Fronts:
- Lob passes over top (requires touch passer)
- Post player flashes to high post
- Relocate to weak-side block
- Expected PPP: 1.08 (easier shots when entry connects)
If Defense Doubles:
- Quick kick-out to corner three-point shooter
- High-low pass to open big man
- Skip pass to weak-side wing
- Expected PPP: 1.15 (open three-point attempts)
If Defense Plays Behind:
- Establish deep position for high-percentage shot
- Power move to rim
- Draw foul on physical finish
- Expected PPP: 1.10 (quality looks + free throws)
Player Development Applications
Modern Big Man Skill Stack
Priority 1: Finishing and Footwork
- Drop steps, hook shots, and power moves
- Training focus: 40% of individual workout time
- ROI: +0.15 PPP per season of development
Priority 2: Passing and Decision-Making
- Reading double teams and finding open shooters
- Training focus: 25% of workout time
- ROI: +0.22 PPP when accounting for assisted threes
Priority 3: Face-Up Game
- Mid-range shooting and perimeter drives
- Training focus: 20% of workout time
- ROI: +0.18 PPP through increased versatility
Priority 4: Three-Point Shooting
- Spacing the floor from perimeter
- Training focus: 15% of workout time
- ROI: +0.12 PPP through gravity effect on team offense
Key Takeaway: While post-up frequency has declined 63% since 2004, the strategic value of elite post play remains high in specific contexts. Modern teams that can selectively deploy post-ups (5-8% of possessions) while maintaining pace-and-space principles achieve 3-4% higher offensive efficiency than teams at either extreme.
Conclusion: The Future of Post Play
Post-up analytics reveals a nuanced story of evolution rather than obsolescence. While raw volume has declined dramatically, the strategic value of post play persists in three critical domains:
1. Matchup Optimization
Teams that can recognize and exploit switching defensive schemes through post mismatches generate significant efficiency advantages (1.15+ PPP vs 0.93 baseline).
2. Offensive Diversity
Playoff success correlates with offensive versatility. Teams with elite post options force defensive adjustments that create three-point opportunities, generating compound efficiency gains.
3. Player Development
Modern big men who combine post skills with perimeter abilities (shooting, passing, mobility) command premium value. The "unicorn" archetype exemplified by Jokic, Embiid, and Davis represents the evolution of traditional post play into hybrid offensive systems.
The analytical framework for evaluating post-ups must account for both direct efficiency (PPP) and indirect value (gravity, assists, foul-drawing). Organizations that successfully integrate selective post-up actions within modern pace-and-space systems maximize offensive potential while maintaining the flexibility to adapt to defensive schemes.
As defensive strategies continue evolving and three-point shooting variance influences playoff outcomes, the ability to generate high-percentage looks through post play in critical moments remains a competitive advantage. The future of post-up analytics lies not in restoring historical volume, but in optimizing strategic deployment through sophisticated matchup analysis and contextual decision-making.