Defensive Rebounding Rate

Beginner 10 min read 0 views Nov 27, 2025

Defensive Rebounding: The Complete Guide

Defensive rebounding is one of basketball's most critical yet underappreciated skills. While offensive rebounds generate additional scoring opportunities, defensive rebounds end opponent possessions and create transition opportunities. A missed defensive rebound gives opponents second-chance points—statistically the most efficient scoring opportunities in basketball. Understanding defensive rebounding through advanced metrics reveals which players and teams truly control the glass and prevent extended possessions.

What is Defensive Rebounding?

A defensive rebound (DRB) occurs when a player retrieves a missed field goal attempt or free throw by the opposing team. Defensive rebounds represent approximately 70-75% of all rebounds in NBA games because defenses have significant positional advantages: defenders are typically closer to the basket, face the rim, and have established position before the shot goes up.

Why Defensive Rebounding Matters

Defensive rebounding serves multiple strategic purposes:

  • Possession Control: Ends opponent offensive possessions, preventing second-chance opportunities
  • Transition Opportunities: Creates fast break chances with defenders already positioned near the basket
  • Defensive Efficiency: Limits opponent effective field goal percentage by denying offensive rebounds
  • Momentum Shifts: Defensive rebounds after opponent misses can deflate offensive intensity
  • Foul Management: Secures possessions without fouling, especially late in close games

Key Insight: Teams that dominate defensive rebounding typically allow fewer points per possession because they limit opponent offensive rebounding (second-chance opportunities). The correlation between defensive rebounding rate and defensive efficiency is one of basketball's strongest statistical relationships.

Defensive Rebounding Percentage (DRB%)

Defensive Rebounding Percentage (DRB%) measures the percentage of available defensive rebounds a player or team secures while on the court. It's the gold standard metric for evaluating defensive rebounding effectiveness because it accounts for opportunity and playing time.

Formula

DRB% = (Defensive Rebounds / (Defensive Rebounds + Opponent Offensive Rebounds)) × 100

This formula calculates what percentage of all available defensive rebounds (total misses by opponents) were secured by the player or team.

Calculation Example

Team Scenario:

  • Team defensive rebounds: 38
  • Opponent offensive rebounds: 12
  • Total available defensive rebounds: 38 + 12 = 50
Team DRB% = (38 / 50) × 100 = 76.0%

This team secured 76% of available defensive rebounds, allowing opponents only 24% offensive rebounding rate.

Individual Player Scenario:

  • Player defensive rebounds: 8
  • Team defensive rebounds while player on court: 32
  • Opponent offensive rebounds while player on court: 8
  • Total available: 32 + 8 = 40
Individual DRB% = (8 / 40) × 100 = 20.0%

This player secured 20% of all available defensive rebounds while on the court, indicating strong rebounding contribution for a single player.

Interpreting DRB%

Team Defensive Rebounding % Benchmarks

Team DRB% Range Quality Description
78% and above Elite Top 3-5 teams league-wide, championship-caliber rebounding
76-78% Very Good Top 10 teams, playoff-level defensive rebounding
74-76% Above Average Solid defensive rebounding, limits second chances
72-74% Average League average range, neutral rebounding impact
70-72% Below Average Struggles to secure defensive boards consistently
Below 70% Poor Bottom 5 teams, significant defensive rebounding weakness

Individual Defensive Rebounding % Benchmarks (by Position)

Position Elite Good Average Below Average
Centers 30%+ 25-30% 20-25% Below 20%
Power Forwards 25%+ 20-25% 15-20% Below 15%
Small Forwards 20%+ 15-20% 12-15% Below 12%
Guards (SG/PG) 15%+ 12-15% 8-12% Below 8%

Context Note: Position classifications vary widely in modern basketball. Versatile forwards and "big guards" blur traditional positional lines, so evaluate DRB% relative to playing role and minutes distribution.

Modern Era Team DRB% Leaders (2023-24 Season)

  1. Minnesota Timberwolves: 77.8% DRB% - Elite rim protection with Rudy Gobert
  2. Cleveland Cavaliers: 77.2% DRB% - Strong frontcourt with Evan Mobley and Jarrett Allen
  3. Denver Nuggets: 76.9% DRB% - Nikola Jokic elite positioning and boxing out
  4. Miami Heat: 76.5% DRB% - Team commitment to defensive rebounding
  5. Oklahoma City Thunder: 76.2% DRB% - Young, athletic frontcourt

Individual vs Team Defensive Rebounding

Defensive rebounding is inherently a team activity that requires coordination, but individual contributions vary significantly based on position, role, and rebounding ability.

Team Defensive Rebounding

Characteristics:

  • Collective Responsibility: All five defenders must box out and pursue rebounds
  • Scheme-Dependent: Defensive systems emphasizing switching or aggressive traps may sacrifice rebounding position
  • Positional Advantage: Defenders naturally positioned closer to basket
  • Box-Out Discipline: Effective boxing out prevents offensive rebounds even without securing the rebound

Key Factors Affecting Team DRB%:

  • Defensive scheme (drop coverage vs. switching)
  • Opponent offensive rebounding ability
  • Pace of play (faster pace = fewer rebounding opportunities)
  • Three-point attempt rate (long rebounds more unpredictable)
  • Team size and length

Individual Defensive Rebounding

Characteristics:

  • Position-Dependent: Centers and power forwards expected to secure 20-30% DRB% while guards average 8-15%
  • Opportunity-Based: Players near the basket have more rebounding chances
  • Skill + Effort: Combination of positioning, timing, strength, and motor
  • Context-Heavy: Playing alongside strong rebounders reduces individual DRB% opportunities

Elite Individual Defensive Rebounders (2023-24 Season):

  1. Rudy Gobert (Timberwolves): 30.7% DRB% - Dominant rim protector and defensive rebounder
  2. Domantas Sabonis (Kings): 29.8% DRB% - Elite positioning and box-out technique
  3. Anthony Davis (Lakers): 27.4% DRB% - Length and athleticism near rim
  4. Nikola Jokic (Nuggets): 26.9% DRB% - Elite positioning IQ and anticipation
  5. Jarrett Allen (Cavaliers): 26.5% DRB% - Traditional rim-running center

The Interaction: Individual + Team

Individual and team defensive rebounding are interconnected. A single elite rebounder can dramatically improve team DRB%, but team schemes and effort determine whether that advantage is maximized or minimized.

Example: Rudy Gobert's presence increases Minnesota's team DRB% not just through his own rebounds (30.7% individual) but by:

  • Boxing out multiple opponents, freeing teammates for rebounds
  • Deterring opponent offensive rebounding attempts near the rim
  • Positioning teammates for optimal rebounding lanes
  • Setting the standard for rebounding effort and intensity

Contested vs Uncontested Defensive Rebounds

NBA player tracking data distinguishes between contested (opponent within 3.5 feet) and uncontested defensive rebounds, revealing different rebounding skills and contexts.

Contested Defensive Rebounds

Definition: Defensive rebounds secured with at least one opponent within 3.5 feet at time of rebound.

Characteristics:

  • Higher Difficulty: Requires strength, timing, positioning, and physicality
  • More Valuable: Prevents opponent second-chance opportunities in traffic
  • Box-Out Required: Almost always follows effective box-out technique
  • Size Advantage: Taller, stronger players have significant advantage

Leaders in Contested DRB (2023-24):

  1. Rudy Gobert: 6.8 contested DRB per game - Dominates contested situations
  2. Domantas Sabonis: 6.3 contested DRB per game - Physical low-post rebounding
  3. Anthony Davis: 5.9 contested DRB per game - Elite length and timing
  4. Nikola Jokic: 5.7 contested DRB per game - Positioning and strength
  5. Jarrett Allen: 5.5 contested DRB per game - Traditional center rebounding

Uncontested Defensive Rebounds

Definition: Defensive rebounds with no opponent within 3.5 feet at time of rebound.

Characteristics:

  • Lower Difficulty: Positional awareness and hustle primary requirements
  • Common for Guards: Perimeter players often secure long rebounds after three-point misses
  • Transition Value: Uncontested rebounds often lead to fast breaks
  • Effort Indicator: High uncontested rebound rate shows motor and positioning

Why Uncontested Rebounds Matter: While less physically demanding, uncontested rebounds are crucial for:

  • Starting fast breaks quickly (guard rebounds especially valuable)
  • Preventing opponent from crashing for long rebounds
  • Maintaining defensive rebounding percentage
  • Demonstrating court awareness and effort

Leaders in Uncontested DRB (2023-24):

  1. Nikola Jokic: 7.2 uncontested DRB per game - Elite positioning IQ
  2. Domantas Sabonis: 6.8 uncontested DRB per game - Hustle and motor
  3. Rudy Gobert: 6.5 uncontested DRB per game - Consistent positioning
  4. Anthony Davis: 6.2 uncontested DRB per game - Length and range
  5. Giannis Antetokounmpo: 5.9 uncontested DRB per game - Elite athleticism

Contested vs Uncontested: Analytical Perspective

Aspect Contested Rebounds Uncontested Rebounds
Difficulty High - requires physicality Lower - requires positioning
Value Prevents second chances Enables fast breaks
Primary Skill Strength, timing, box-out Hustle, awareness, anticipation
Position Advantage Centers, power forwards All positions (especially guards for long rebounds)
Team Impact Directly reduces opponent ORB% Increases transition efficiency

Analytical Insight: Elite defensive rebounders excel in both categories. Players with high contested rebound rates demonstrate true rebounding ability, while high uncontested rates show positioning IQ and effort. The ideal defensive rebounder maximizes both.

Shot Distance and Rebound Contest Rates

Shot distance significantly impacts whether defensive rebounds are contested:

  • Rim/Paint Shots (0-10 feet): 70-80% of defensive rebounds are contested (high traffic area)
  • Mid-Range (10-24 feet): 50-60% contested (moderate traffic)
  • Three-Point (24+ feet): 30-40% contested (long rebounds, more unpredictable)

Strategic Implication: As three-point attempt rates increase league-wide, uncontested defensive rebound rates also increase because long rebounds are harder to predict and contest.

Historical Defensive Rebounding Leaders

All-Time Career Defensive Rebounding Leaders

  1. Kevin Garnett: 15,279 defensive rebounds - Consistent excellence over 21 seasons
  2. Tim Duncan: 13,321 defensive rebounds - Fundamental positioning and technique
  3. Dwight Howard: 12,632 defensive rebounds - Athletic dominance in prime
  4. Karl Malone: 12,357 defensive rebounds - Power forward rebounding excellence
  5. Dirk Nowitzki: 10,744 defensive rebounds - Consistent over 21 seasons

Note: Defensive rebounds were officially tracked starting in 1973-74 season, so earlier legends like Wilt Chamberlain and Bill Russell don't appear on this list despite dominant rebounding careers.

All-Time Career Defensive Rebounding % Leaders (Min 10,000 minutes)

  1. DeAndre Jordan: 30.2% DRB% - Elite rim-runner and lob threat
  2. Dwight Howard: 29.8% DRB% - Peak athletic center dominance
  3. Andre Drummond: 29.5% DRB% - Traditional rebounding center
  4. Rudy Gobert: 29.1% DRB% - Modern defensive anchor
  5. Hassan Whiteside: 28.7% DRB% - Rebounding specialist

Pattern: Traditional, rim-protecting centers dominate career DRB% leaderboards, highlighting position's natural rebounding advantages.

Single-Season DRB% Records (Min 2000 minutes)

  1. Wilt Chamberlain (1970-71): 35.9% DRB% - Estimated from total rebound data
  2. Dennis Rodman (1991-92): 34.7% DRB% - Peak rebounding specialist season
  3. Dennis Rodman (1992-93): 34.3% DRB% - Consecutive elite rebounding
  4. Dennis Rodman (1993-94): 33.8% DRB% - Third consecutive season above 33%
  5. Dwight Howard (2009-10): 33.6% DRB% - Modern era record

Dennis Rodman's Dominance: Rodman's three consecutive seasons above 34% DRB% represent unmatched sustained defensive rebounding excellence. Despite playing at 6'7" (short for a power forward), Rodman's positioning, timing, and relentless effort made him basketball's greatest defensive rebounder.

Recent Season DRB% Leaders (2023-24, Min 1500 minutes)

  1. Rudy Gobert (Timberwolves): 30.7% DRB%
  2. Domantas Sabonis (Kings): 29.8% DRB%
  3. Jonas Valanciunas (Pelicans): 28.9% DRB%
  4. Andre Drummond (Bulls): 28.6% DRB%
  5. Anthony Davis (Lakers): 27.4% DRB%

Modern Era Team DRB% Leaders (2015-Present)

  1. 2015-16 Detroit Pistons: 79.2% DRB% - Andre Drummond peak season
  2. 2018-19 Golden State Warriors: 78.9% DRB% - Team rebounding commitment
  3. 2022-23 Cleveland Cavaliers: 78.5% DRB% - Twin towers (Mobley + Allen)
  4. 2023-24 Minnesota Timberwolves: 77.8% DRB% - Rudy Gobert anchoring
  5. 2016-17 Toronto Raptors: 77.6% DRB% - Jonas Valanciunas era

Team Rebounding Trends: Elite defensive rebounding teams typically feature at least one elite individual rebounder (center or power forward) combined with team-wide commitment to boxing out and pursuing rebounds.

Limitations and Context

1. Opportunity Bias

Problem: Defensive rebounding opportunities vary widely based on opponent shot quality, teammate rebounding, and defensive scheme.

Example: A center on a team that forces many opponent turnovers will have fewer rebounding opportunities than a center on a team that allows many shots.

Solution: Compare DRB% (percentage-based) rather than raw defensive rebound totals.

2. Position and Role Dependency

Problem: Centers naturally secure more defensive rebounds due to positioning near basket. Comparing guard DRB% to center DRB% isn't meaningful.

Example: A guard with 12% DRB% might be an elite rebounder for their position, while a center with 20% DRB% would be below average.

Solution: Use positional benchmarks when evaluating individual players.

3. Team Scheme Effects

Problem: Defensive schemes prioritizing switching, trapping, or aggressive perimeter defense may sacrifice rebounding position.

Example: Small-ball lineups with five switchable defenders might have lower team DRB% but better overall defense due to versatility.

Context: Evaluate defensive rebounding within the broader defensive strategy context.

4. Box-Out vs Rebound Credit

Problem: Effective box-outs that free teammates for rebounds don't appear in statistics, despite being crucial to defensive rebounding success.

Example: A center who consistently boxes out opponents but allows teammates to secure rebounds will have lower individual DRB% despite strong rebounding contribution.

Limitation: Traditional stats don't capture box-out effectiveness, though some advanced tracking systems now measure this.

5. Pace and Three-Point Era Effects

Problem: Modern basketball's high three-point attempt rate creates more long rebounds, which are less predictable and harder to contest.

Trend: League-wide DRB% has slightly decreased as three-point attempts increased, not because players are worse rebounders but because long rebounds are inherently more variable.

6. Teammate Rebounding Interaction

Problem: Playing alongside elite rebounders naturally decreases individual DRB% opportunities.

Example: A power forward playing with an elite rebounding center will have fewer rebounding opportunities than if paired with a non-rebounding center.

Solution: Evaluate lineup-adjusted rebounding metrics that account for teammate rebounding ability.

Code Examples: Defensive Rebounding Analysis

Python: Calculating Defensive Rebounding Metrics

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

def calculate_drb_percentage(def_rebounds, opp_off_rebounds):
    """
    Calculate defensive rebounding percentage.

    Parameters:
    -----------
    def_rebounds : int or float
        Defensive rebounds secured
    opp_off_rebounds : int or float
        Opponent offensive rebounds

    Returns:
    --------
    float
        Defensive rebounding percentage
    """
    total_available = def_rebounds + opp_off_rebounds

    if total_available == 0:
        return 0.0

    drb_pct = (def_rebounds / total_available) * 100
    return drb_pct

def calculate_team_drb_rate(df):
    """
    Calculate team defensive rebounding rate and related metrics.

    Parameters:
    -----------
    df : pandas.DataFrame
        Team statistics with rebounding data

    Returns:
    --------
    pandas.DataFrame
        Enhanced dataframe with rebounding metrics
    """
    # Calculate DRB%
    df['DRB%'] = df.apply(
        lambda row: calculate_drb_percentage(row['DRB'], row['Opp_ORB']),
        axis=1
    )

    # Calculate opponent ORB% (inverse of DRB%)
    df['Opp_ORB%'] = 100 - df['DRB%']

    # Calculate per-game averages
    df['DRB_per_game'] = df['DRB'] / df['Games']
    df['Opp_ORB_per_game'] = df['Opp_ORB'] / df['Games']

    # Calculate total rebounding opportunities
    df['Total_DRB_Opportunities'] = df['DRB'] + df['Opp_ORB']

    return df

def categorize_drb_quality(drb_pct):
    """
    Categorize defensive rebounding quality based on DRB%.

    Parameters:
    -----------
    drb_pct : float
        Defensive rebounding percentage

    Returns:
    --------
    str
        Quality category
    """
    if drb_pct >= 78:
        return 'Elite'
    elif drb_pct >= 76:
        return 'Very Good'
    elif drb_pct >= 74:
        return 'Above Average'
    elif drb_pct >= 72:
        return 'Average'
    elif drb_pct >= 70:
        return 'Below Average'
    else:
        return 'Poor'

# Sample team defensive rebounding data (2023-24 Season)
team_data = {
    'Team': ['Timberwolves', 'Cavaliers', 'Nuggets', 'Heat', 'Thunder',
             'Celtics', 'Lakers', 'Warriors', 'Kings', 'Knicks',
             'Rockets', 'Wizards', 'Pistons'],
    'Games': [82] * 13,
    'DRB': [3589, 3567, 3534, 3512, 3489, 3467, 3445, 3423, 3401, 3378,
            3289, 3234, 3178],
    'Opp_ORB': [1023, 1056, 1089, 1112, 1145, 1178, 1212, 1245, 1278, 1312,
                1389, 1423, 1456],
    'Opp_FGA': [7123, 7234, 7189, 7298, 7345, 7267, 7423, 7389, 7456, 7512,
                7634, 7723, 7801]
}

df = pd.DataFrame(team_data)

# Calculate defensive rebounding metrics
df = calculate_team_drb_rate(df)

# Add quality categorization
df['DRB_Quality'] = df['DRB%'].apply(categorize_drb_quality)

# Calculate rank
df['DRB_Rank'] = df['DRB%'].rank(ascending=False, method='min')

# Sort by DRB%
df_sorted = df.sort_values('DRB%', ascending=False)

# Display results
print("=== Team Defensive Rebounding Analysis (2023-24 Season) ===\n")
print("Top Defensive Rebounding Teams:")
print(df_sorted[['DRB_Rank', 'Team', 'DRB%', 'Opp_ORB%', 'DRB_Quality']].head(10).to_string(index=False))

print(f"\nLeague Average DRB%: {df['DRB%'].mean():.1f}%")
print(f"Best DRB%: {df['Team'].iloc[df['DRB%'].idxmax()]} ({df['DRB%'].max():.1f}%)")
print(f"Worst DRB%: {df['Team'].iloc[df['DRB%'].idxmin()]} ({df['DRB%'].min():.1f}%)")

# Statistical summary
print("\n=== Defensive Rebounding Statistics ===")
print(f"Standard Deviation: {df['DRB%'].std():.2f}%")
print(f"Range: {df['DRB%'].max() - df['DRB%'].min():.1f}%")

Python: Individual Defensive Rebounding Analysis

import pandas as pd
import numpy as np

def calculate_individual_drb_pct(player_drb, team_drb_with_player, opp_orb_with_player):
    """
    Calculate individual defensive rebounding percentage.

    Parameters:
    -----------
    player_drb : int
        Player's defensive rebounds
    team_drb_with_player : int
        Team defensive rebounds while player on court
    opp_orb_with_player : int
        Opponent offensive rebounds while player on court

    Returns:
    --------
    float
        Individual DRB%
    """
    total_available = team_drb_with_player + opp_orb_with_player

    if total_available == 0:
        return 0.0

    return (player_drb / total_available) * 100

def categorize_individual_drb(drb_pct, position):
    """
    Categorize individual DRB% based on position.

    Parameters:
    -----------
    drb_pct : float
        Defensive rebounding percentage
    position : str
        Player position (C, PF, SF, SG, PG)

    Returns:
    --------
    str
        Quality rating
    """
    benchmarks = {
        'C': {'elite': 30, 'good': 25, 'average': 20},
        'PF': {'elite': 25, 'good': 20, 'average': 15},
        'SF': {'elite': 20, 'good': 15, 'average': 12},
        'SG': {'elite': 15, 'good': 12, 'average': 8},
        'PG': {'elite': 15, 'good': 12, 'average': 8}
    }

    if position not in benchmarks:
        position = 'SF'  # Default to SF if position unknown

    if drb_pct >= benchmarks[position]['elite']:
        return 'Elite'
    elif drb_pct >= benchmarks[position]['good']:
        return 'Good'
    elif drb_pct >= benchmarks[position]['average']:
        return 'Average'
    else:
        return 'Below Average'

# Sample individual player data (2023-24 Season)
player_data = {
    'Player': ['Rudy Gobert', 'Domantas Sabonis', 'Anthony Davis', 'Nikola Jokic',
               'Jarrett Allen', 'Giannis Antetokounmpo', 'Joel Embiid', 'Kevin Durant',
               'LeBron James', 'Stephen Curry'],
    'Position': ['C', 'PF', 'C', 'C', 'C', 'PF', 'C', 'SF', 'SF', 'PG'],
    'Games': [76, 82, 76, 79, 77, 73, 66, 75, 71, 74],
    'Minutes': [2789, 2934, 2678, 2812, 2534, 2612, 2389, 2745, 2534, 2467],
    'DRB': [778, 912, 723, 756, 645, 689, 612, 534, 489, 312],
    'Contested_DRB': [518, 516, 449, 450, 425, 423, 398, 267, 234, 89],
    'Uncontested_DRB': [260, 396, 274, 306, 220, 266, 214, 267, 255, 223],
    'Team_DRB_With_Player': [2534, 3056, 2645, 2812, 2389, 2534, 2278, 2645, 2389, 2456],
    'Opp_ORB_With_Player': [989, 1123, 1045, 1089, 978, 1034, 967, 1067, 1012, 1045]
}

df_players = pd.DataFrame(player_data)

# Calculate DRB metrics
df_players['DRB%'] = df_players.apply(
    lambda row: calculate_individual_drb_pct(
        row['DRB'], row['Team_DRB_With_Player'], row['Opp_ORB_With_Player']
    ),
    axis=1
)

df_players['DRB_per_game'] = df_players['DRB'] / df_players['Games']
df_players['Contested_per_game'] = df_players['Contested_DRB'] / df_players['Games']
df_players['Uncontested_per_game'] = df_players['Uncontested_DRB'] / df_players['Games']
df_players['Contested_pct'] = (df_players['Contested_DRB'] / df_players['DRB']) * 100

# Categorize by position
df_players['DRB_Quality'] = df_players.apply(
    lambda row: categorize_individual_drb(row['DRB%'], row['Position']),
    axis=1
)

# Sort by DRB%
df_players_sorted = df_players.sort_values('DRB%', ascending=False)

# Display results
print("\n=== Individual Defensive Rebounding Leaders ===\n")
print(df_players_sorted[[
    'Player', 'Position', 'DRB%', 'DRB_per_game',
    'Contested_per_game', 'Uncontested_per_game', 'DRB_Quality'
]].to_string(index=False))

# Position-based analysis
print("\n=== Defensive Rebounding by Position ===")
position_summary = df_players.groupby('Position').agg({
    'DRB%': 'mean',
    'DRB_per_game': 'mean',
    'Contested_per_game': 'mean',
    'Uncontested_per_game': 'mean'
}).round(1)

print(position_summary)

Python: Contested vs Uncontested Rebounding Analysis

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

def analyze_rebound_types(df):
    """
    Analyze contested vs uncontested rebounding patterns.

    Parameters:
    -----------
    df : pandas.DataFrame
        Player rebounding data with contested/uncontested splits

    Returns:
    --------
    dict
        Analysis results
    """
    # Calculate percentages
    df['Contested_Pct'] = (df['Contested_DRB'] / df['DRB']) * 100
    df['Uncontested_Pct'] = (df['Uncontested_DRB'] / df['DRB']) * 100

    # Identify rebounding style
    def classify_rebounding_style(contested_pct):
        if contested_pct >= 70:
            return 'Physical Rebounder'
        elif contested_pct >= 60:
            return 'Balanced'
        else:
            return 'Positioning Rebounder'

    df['Rebounding_Style'] = df['Contested_Pct'].apply(classify_rebounding_style)

    analysis = {
        'avg_contested_pct': df['Contested_Pct'].mean(),
        'avg_uncontested_pct': df['Uncontested_Pct'].mean(),
        'most_contested': df.loc[df['Contested_Pct'].idxmax(), 'Player'],
        'most_uncontested': df.loc[df['Uncontested_Pct'].idxmax(), 'Player']
    }

    return df, analysis

# Using previous player data
df_analyzed, rebound_analysis = analyze_rebound_types(df_players)

print("\n=== Contested vs Uncontested Rebounding Analysis ===\n")
print(f"League Average Contested %: {rebound_analysis['avg_contested_pct']:.1f}%")
print(f"League Average Uncontested %: {rebound_analysis['avg_uncontested_pct']:.1f}%")
print(f"Most Physical Rebounder: {rebound_analysis['most_contested']}")
print(f"Best Positioning Rebounder: {rebound_analysis['most_uncontested']}")

print("\nPlayer Rebounding Styles:")
print(df_analyzed[[
    'Player', 'Position', 'Contested_per_game', 'Uncontested_per_game',
    'Contested_Pct', 'Rebounding_Style'
]].to_string(index=False))

# Visualization: Contested vs Uncontested
plt.figure(figsize=(12, 7))

colors = {'C': '#e74c3c', 'PF': '#3498db', 'SF': '#2ecc71', 'SG': '#f39c12', 'PG': '#9b59b6'}
df_analyzed['Color'] = df_analyzed['Position'].map(colors)

plt.scatter(df_analyzed['Contested_per_game'], df_analyzed['Uncontested_per_game'],
           c=df_analyzed['Color'], s=200, alpha=0.7, edgecolors='black')

for idx, row in df_analyzed.iterrows():
    plt.annotate(row['Player'].split()[-1],  # Last name only
                (row['Contested_per_game'], row['Uncontested_per_game']),
                xytext=(5, 5), textcoords='offset points', fontsize=9)

plt.xlabel('Contested Defensive Rebounds per Game', fontsize=12)
plt.ylabel('Uncontested Defensive Rebounds per Game', fontsize=12)
plt.title('Contested vs Uncontested Defensive Rebounding\n2023-24 NBA Season',
         fontsize=14, fontweight='bold')

# Add legend for positions
from matplotlib.patches import Patch
legend_elements = [Patch(facecolor=colors[pos], label=pos) for pos in colors.keys()]
plt.legend(handles=legend_elements, title='Position', loc='upper right')

plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('contested_vs_uncontested_rebounding.png', dpi=300, bbox_inches='tight')
plt.show()

Python: Defensive Rebounding Visualization

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np

def create_drb_dashboard(team_df, player_df):
    """
    Create comprehensive defensive rebounding visualization dashboard.

    Parameters:
    -----------
    team_df : pandas.DataFrame
        Team defensive rebounding data
    player_df : pandas.DataFrame
        Individual player rebounding data
    """
    fig, axes = plt.subplots(2, 2, figsize=(16, 12))
    sns.set_style("whitegrid")

    # 1. Team DRB% Rankings
    team_sorted = team_df.sort_values('DRB%', ascending=True)
    colors_team = ['#2ecc71' if x >= 78 else '#3498db' if x >= 76 else '#f39c12' if x >= 74 else '#e74c3c'
                   for x in team_sorted['DRB%']]

    axes[0, 0].barh(team_sorted['Team'], team_sorted['DRB%'], color=colors_team, alpha=0.8)
    axes[0, 0].axvline(x=team_df['DRB%'].mean(), color='red', linestyle='--',
                       linewidth=2, label=f"League Avg: {team_df['DRB%'].mean():.1f}%")
    axes[0, 0].set_xlabel('Defensive Rebounding % (DRB%)', fontsize=11)
    axes[0, 0].set_ylabel('Team', fontsize=11)
    axes[0, 0].set_title('Team Defensive Rebounding % Rankings',
                         fontsize=13, fontweight='bold')
    axes[0, 0].legend()

    # 2. Individual DRB% by Position
    player_sorted = player_df.sort_values('DRB%', ascending=False)
    position_colors = {'C': '#e74c3c', 'PF': '#3498db', 'SF': '#2ecc71',
                      'SG': '#f39c12', 'PG': '#9b59b6'}
    colors_player = [position_colors[pos] for pos in player_sorted['Position']]

    axes[0, 1].bar(range(len(player_sorted)), player_sorted['DRB%'],
                   color=colors_player, alpha=0.8)
    axes[0, 1].set_xticks(range(len(player_sorted)))
    axes[0, 1].set_xticklabels(player_sorted['Player'].str.split().str[-1],
                               rotation=45, ha='right')
    axes[0, 1].set_ylabel('Defensive Rebounding % (DRB%)', fontsize=11)
    axes[0, 1].set_title('Individual Defensive Rebounding Leaders',
                         fontsize=13, fontweight='bold')

    # Add legend
    from matplotlib.patches import Patch
    legend_elements = [Patch(facecolor=position_colors[pos], label=pos)
                      for pos in position_colors.keys()]
    axes[0, 1].legend(handles=legend_elements, title='Position', loc='upper right')

    # 3. DRB% Distribution
    axes[1, 0].hist(team_df['DRB%'], bins=12, edgecolor='black',
                    alpha=0.7, color='#3498db')
    axes[1, 0].axvline(team_df['DRB%'].mean(), color='red', linestyle='--',
                       linewidth=2, label=f"Mean: {team_df['DRB%'].mean():.1f}%")
    axes[1, 0].axvline(team_df['DRB%'].median(), color='green', linestyle='--',
                       linewidth=2, label=f"Median: {team_df['DRB%'].median():.1f}%")
    axes[1, 0].set_xlabel('Defensive Rebounding %', fontsize=11)
    axes[1, 0].set_ylabel('Number of Teams', fontsize=11)
    axes[1, 0].set_title('Distribution of Team DRB%',
                         fontsize=13, fontweight='bold')
    axes[1, 0].legend()

    # 4. Contested vs Uncontested Breakdown
    player_df_sorted = player_df.sort_values('DRB_per_game', ascending=True)

    axes[1, 1].barh(player_df_sorted['Player'].str.split().str[-1],
                    player_df_sorted['Contested_per_game'],
                    label='Contested', color='#e74c3c', alpha=0.8)
    axes[1, 1].barh(player_df_sorted['Player'].str.split().str[-1],
                    player_df_sorted['Uncontested_per_game'],
                    left=player_df_sorted['Contested_per_game'],
                    label='Uncontested', color='#3498db', alpha=0.8)
    axes[1, 1].set_xlabel('Defensive Rebounds per Game', fontsize=11)
    axes[1, 1].set_title('Contested vs Uncontested Defensive Rebounds',
                         fontsize=13, fontweight='bold')
    axes[1, 1].legend()

    plt.tight_layout()
    plt.savefig('defensive_rebounding_dashboard.png', dpi=300, bbox_inches='tight')
    plt.show()

# Create dashboard using our data
create_drb_dashboard(df, df_players)

R: Defensive Rebounding Analysis

# Load required libraries
library(tidyverse)
library(ggplot2)
library(scales)

# Function to calculate DRB%
calculate_drb_pct <- function(def_rebounds, opp_off_rebounds) {
  total_available <- def_rebounds + opp_off_rebounds
  if (total_available == 0) return(0)
  return((def_rebounds / total_available) * 100)
}

# Sample team defensive rebounding data
team_rebounding <- tibble(
  team = c("Timberwolves", "Cavaliers", "Nuggets", "Heat", "Thunder",
           "Celtics", "Lakers", "Warriors", "Kings", "Knicks",
           "Rockets", "Wizards", "Pistons"),
  games = 82,
  drb = c(3589, 3567, 3534, 3512, 3489, 3467, 3445, 3423, 3401, 3378,
          3289, 3234, 3178),
  opp_orb = c(1023, 1056, 1089, 1112, 1145, 1178, 1212, 1245, 1278, 1312,
              1389, 1423, 1456)
)

# Calculate DRB%
team_rebounding <- team_rebounding %>%
  mutate(
    drb_pct = calculate_drb_pct(drb, opp_orb),
    opp_orb_pct = 100 - drb_pct,
    drb_per_game = drb / games,
    opp_orb_per_game = opp_orb / games,
    total_opportunities = drb + opp_orb,
    drb_quality = case_when(
      drb_pct >= 78 ~ "Elite",
      drb_pct >= 76 ~ "Very Good",
      drb_pct >= 74 ~ "Above Average",
      drb_pct >= 72 ~ "Average",
      drb_pct >= 70 ~ "Below Average",
      TRUE ~ "Poor"
    ),
    drb_rank = row_number(desc(drb_pct))
  ) %>%
  arrange(desc(drb_pct))

# Display results
cat("=== Team Defensive Rebounding Analysis ===\n\n")
cat(sprintf("League Average DRB%%: %.1f%%\n", mean(team_rebounding$drb_pct)))
cat(sprintf("Best: %s (%.1f%%)\n", team_rebounding$team[1], team_rebounding$drb_pct[1]))
cat(sprintf("Worst: %s (%.1f%%)\n\n",
            team_rebounding$team[nrow(team_rebounding)],
            team_rebounding$drb_pct[nrow(team_rebounding)]))

print("Team Defensive Rebounding Rankings:")
team_rebounding %>%
  select(drb_rank, team, drb_pct, opp_orb_pct, drb_quality) %>%
  mutate(drb_pct = round(drb_pct, 1),
         opp_orb_pct = round(opp_orb_pct, 1)) %>%
  print(n = Inf)

# Visualization 1: Team DRB% Bar Chart
p1 <- ggplot(team_rebounding, aes(x = reorder(team, drb_pct), y = drb_pct, fill = drb_quality)) +
  geom_bar(stat = "identity", alpha = 0.8) +
  geom_hline(yintercept = mean(team_rebounding$drb_pct),
             linetype = "dashed", color = "red", size = 1) +
  scale_fill_manual(values = c("Elite" = "#2ecc71", "Very Good" = "#3498db",
                               "Above Average" = "#95a5a6", "Average" = "#f39c12",
                               "Below Average" = "#e67e22", "Poor" = "#e74c3c")) +
  coord_flip() +
  labs(
    title = "Team Defensive Rebounding Percentage (2023-24)",
    subtitle = sprintf("League Average: %.1f%% (dashed line)",
                      mean(team_rebounding$drb_pct)),
    x = "Team",
    y = "Defensive Rebounding %",
    fill = "Quality"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 12),
    axis.title = element_text(size = 12),
    legend.position = "bottom"
  )

print(p1)
ggsave("team_drb_pct.png", p1, width = 12, height = 8, dpi = 300)

# Individual player data
player_rebounding <- tibble(
  player = c("Rudy Gobert", "Domantas Sabonis", "Anthony Davis", "Nikola Jokic",
             "Jarrett Allen", "Giannis Antetokounmpo", "Joel Embiid", "Kevin Durant",
             "LeBron James", "Stephen Curry"),
  position = c("C", "PF", "C", "C", "C", "PF", "C", "SF", "SF", "PG"),
  games = c(76, 82, 76, 79, 77, 73, 66, 75, 71, 74),
  drb = c(778, 912, 723, 756, 645, 689, 612, 534, 489, 312),
  contested_drb = c(518, 516, 449, 450, 425, 423, 398, 267, 234, 89),
  uncontested_drb = c(260, 396, 274, 306, 220, 266, 214, 267, 255, 223),
  team_drb_with = c(2534, 3056, 2645, 2812, 2389, 2534, 2278, 2645, 2389, 2456),
  opp_orb_with = c(989, 1123, 1045, 1089, 978, 1034, 967, 1067, 1012, 1045)
)

# Calculate individual metrics
player_rebounding <- player_rebounding %>%
  mutate(
    drb_pct = calculate_drb_pct(drb, (team_drb_with - drb + opp_orb_with)),
    drb_per_game = drb / games,
    contested_per_game = contested_drb / games,
    uncontested_per_game = uncontested_drb / games,
    contested_pct = (contested_drb / drb) * 100,
    rebounding_style = case_when(
      contested_pct >= 70 ~ "Physical",
      contested_pct >= 60 ~ "Balanced",
      TRUE ~ "Positioning"
    )
  ) %>%
  arrange(desc(drb_pct))

# Display individual results
cat("\n=== Individual Defensive Rebounding Leaders ===\n")
player_rebounding %>%
  select(player, position, drb_pct, drb_per_game, contested_per_game, rebounding_style) %>%
  mutate(drb_pct = round(drb_pct, 1),
         drb_per_game = round(drb_per_game, 1),
         contested_per_game = round(contested_per_game, 1)) %>%
  print(n = Inf)

# Visualization 2: Contested vs Uncontested
p2 <- ggplot(player_rebounding, aes(x = contested_per_game, y = uncontested_per_game)) +
  geom_point(aes(color = position, size = drb_per_game), alpha = 0.7) +
  geom_text(aes(label = str_extract(player, "\\w+$")),
           hjust = -0.2, vjust = 0.5, size = 3.5) +
  scale_color_manual(values = c("C" = "#e74c3c", "PF" = "#3498db",
                                "SF" = "#2ecc71", "PG" = "#9b59b6")) +
  scale_size_continuous(range = c(5, 15)) +
  labs(
    title = "Contested vs Uncontested Defensive Rebounds",
    subtitle = "2023-24 NBA Season",
    x = "Contested Defensive Rebounds per Game",
    y = "Uncontested Defensive Rebounds per Game",
    color = "Position",
    size = "Total DRB/G"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 12),
    axis.title = element_text(size = 12),
    legend.position = "right"
  )

print(p2)
ggsave("contested_uncontested_drb.png", p2, width = 12, height = 8, dpi = 300)

# Statistical summary
cat("\n=== Statistical Summary ===\n")
cat(sprintf("Average contested %%: %.1f%%\n", mean(player_rebounding$contested_pct)))
cat(sprintf("Average uncontested %%: %.1f%%\n", 100 - mean(player_rebounding$contested_pct)))

R: Historical DRB% Trends

library(tidyverse)
library(ggplot2)

# Historical league average DRB%
historical_drb <- tibble(
  season = c("2010-11", "2011-12", "2012-13", "2013-14", "2014-15",
             "2015-16", "2016-17", "2017-18", "2018-19", "2019-20",
             "2020-21", "2021-22", "2022-23", "2023-24"),
  league_avg_drb_pct = c(75.8, 75.6, 75.4, 75.2, 74.9,
                        74.7, 74.3, 74.0, 73.8, 73.5,
                        73.2, 73.0, 72.8, 72.6),
  three_pt_rate = c(22.2, 22.5, 24.1, 25.9, 27.0,
                   29.3, 31.6, 33.2, 35.3, 37.5,
                   39.2, 39.8, 40.4, 41.1)
)

# Add era classification
historical_drb <- historical_drb %>%
  mutate(
    era = case_when(
      season <= "2014-15" ~ "Traditional",
      season <= "2019-20" ~ "Modern",
      TRUE ~ "Current"
    ),
    year = as.numeric(substr(season, 1, 4))
  )

# Visualization: Historical trends
p_trend <- ggplot(historical_drb, aes(x = season, y = league_avg_drb_pct, group = 1)) +
  geom_line(size = 1.5, color = "#e74c3c") +
  geom_point(aes(color = era), size = 4) +
  scale_color_manual(values = c("Traditional" = "#2ecc71",
                                "Modern" = "#3498db",
                                "Current" = "#f39c12")) +
  labs(
    title = "NBA League Average Defensive Rebounding % (2010-2024)",
    subtitle = "Declining DRB% correlates with rising three-point attempt rates",
    x = "Season",
    y = "League Average Defensive Rebounding %",
    color = "Era"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 12),
    axis.title = element_text(size = 12),
    axis.text.x = element_text(angle = 45, hjust = 1),
    legend.position = "bottom"
  )

print(p_trend)
ggsave("historical_drb_trends.png", p_trend, width = 14, height = 7, dpi = 300)

# Correlation analysis
cat("\n=== Correlation Analysis ===\n")
correlation <- cor(historical_drb$league_avg_drb_pct, historical_drb$three_pt_rate)
cat(sprintf("Correlation between DRB%% and 3PT Rate: %.3f\n", correlation))
cat("Interpretation: Strong negative correlation indicates as three-point\n")
cat("attempts increase, defensive rebounding % decreases (longer rebounds)\n")

Practical Applications

For Team Executives

  • Roster Construction: Prioritize at least one elite defensive rebounder (28%+ DRB%) to anchor rebounding
  • Free Agency Targeting: Identify undervalued defensive rebounding specialists to improve team DRB%
  • Trade Evaluation: Assess how player additions/subtractions affect team defensive rebounding rate
  • Draft Strategy: Value defensive rebounding ability in big men prospects (strong correlation with NBA success)

For Coaches

  • Lineup Optimization: Balance defensive schemes with rebounding capability (switching may sacrifice rebounding position)
  • Box-Out Emphasis: Track defensive rebounding rate as key performance indicator for effort and discipline
  • Opponent Scouting: Target opponent weaknesses in offensive rebounding (low ORB% teams less dangerous)
  • Player Development: Emphasize defensive rebounding fundamentals (positioning, timing, effort)

For Analysts

  • Defensive Evaluation: Use DRB% as component of comprehensive defensive analysis
  • Lineup Analysis: Track DRB% by lineup to identify optimal rebounding combinations
  • Opponent Adjustment: Control for opponent offensive rebounding ability when evaluating team DRB%
  • Historical Comparison: Adjust for era when comparing defensive rebounding across different seasons

Conclusion

Defensive rebounding remains one of basketball's most important team skills. While less glamorous than offensive rebounding or scoring, securing defensive boards ends opponent possessions, prevents second-chance opportunities, and creates transition advantages. Defensive Rebounding Percentage (DRB%) provides the most accurate measure of defensive rebounding effectiveness by accounting for opportunities and playing time.

Elite defensive rebounding requires both individual skill (positioning, timing, strength, effort) and team commitment (boxing out, scheme design, collective responsibility). The best defensive rebounding teams feature at least one elite individual rebounder combined with team-wide emphasis on box-outs and pursuit.

Understanding contested vs uncontested defensive rebounds reveals different rebounding skills—physical rebounders excel in traffic while positioning rebounders maximize uncontested opportunities. Both contribute to team success, and the best rebounders excel in both categories.

As basketball evolves toward increased three-point shooting, defensive rebounding becomes more challenging due to longer, less predictable rebounds. Teams that maintain elite defensive rebounding rates despite modern offensive trends gain significant competitive advantages through possession control and defensive efficiency.

Discussion

Have questions or feedback? Join our community discussion on Discord or GitHub Discussions.