This report analyzes professional tennis match data extracted from the Live Tennis API Open Dataset. The analysis explores critical match dynamics, including comeback probabilities after losing the first set, service hold vs. break percentages across tour tiers, and sample size distributions.
The raw data is imported directly from the API JSON endpoint and extracted into tidy data frames.
url <- "https://blog.livetennisapi.com/studies.json"
tennisData <- jsonlite::fromJSON(url)
str(tennisData, max.level = 2)
## List of 5
## $ as_of : chr "2026-09-14"
## $ attribution: chr "Live Tennis API — https://livetennisapi.com"
## $ licence : chr "CC BY 4.0 — free to reuse with attribution to Live Tennis API"
## $ method_note: chr "Completed best-of-three singles matches on ATP, WTA, Challenger and ITF, 2023-01-01 to 2026-09-14. Retirements "| __truncated__
## $ studies :'data.frame': 4 obs. of 15 variables:
## ..$ article : chr [1:4] "https://blog.livetennisapi.com/blog/tennis-first-set-comeback-rate" "https://blog.livetennisapi.com/blog/tennis-first-set-comeback-rate" "https://blog.livetennisapi.com/blog/tennis-hold-rate-by-surface" "https://blog.livetennisapi.com/blog/tennis-hold-rate-by-surface"
## ..$ best_of_five :'data.frame': 4 obs. of 3 variables:
## ..$ breakdown_note : chr [1:4] "Two of these columns do not sum to 116,382 and the reasons differ. by_surface (113,288) genuinely excludes matc"| __truncated__ NA NA NA
## ..$ by_first_set_score :List of 4
## ..$ by_surface :List of 4
## ..$ by_tour :List of 4
## ..$ id : chr [1:4] "first-set-comeback" "second-set-win-probability" "hold-rate" "tiebreaks"
## ..$ matches : int [1:4] 116382 NA NA NA
## ..$ overall_comeback_pct: num [1:4] 16.5 NA NA NA
## ..$ title : chr [1:4] "Comeback rate after losing the first set" "Win probability by second-set score, after losing the first set" "Service hold rate by surface and tour" "Tiebreak frequency by surface"
## ..$ note : chr [1:4] NA "Chaser = the player who lost the first set. Each state counted once per match." NA NA
## ..$ states :List of 4
## ..$ service_games : int [1:4] NA NA 2239440 NA
## ..$ service_games_note : chr [1:4] NA NA "2,239,440 counts only matches with a known surface — it is the denominator of by_surface, which sums to it exac"| __truncated__ NA
## ..$ validation : chr [1:4] NA NA "Reproduces the widely published ATP (~79%) and WTA (~64%) hold rates on a method tuned to neither; tiebreak games excluded." NA
This visualization evaluates how much the initial score deficit impacts a player’s likelihood of making a successful match comeback.
# Chart 1: Standard Bar Chart displaying comeback win
# percentage based on first set score
dfScore <- tennisData$studies$by_first_set_score[[1]]
ggplot(dfScore, aes(x = reorder(set, -comeback_pct), y = comeback_pct)) +
geom_col(fill = 'steelblue') +
geom_text(
aes(label = paste0(round(comeback_pct, 1), "%")),
vjust = -0.5,
size = 3.5,
fontface = "bold"
) +
labs(
title = "Match Win Percentage After Losing First Set",
subtitle = "Based on professional singles matches",
x = "First Set Scoreline (Set Loser's Perspective)",
y = "Comeback Win Rate (%)",
caption = "Source: Live Tennis API Open Dataset"
) +
theme_minimal(base_size = 12) +
theme(
panel.grid.major.x = element_blank(),
plot.title = element_text(face = "bold", size = 14)
)
Descriptive Analysis: Closer first-set scores yield the highest comeback win rates, led by 7-6 (21.9%) and 6-4 (19.4%). Reversal rates steadily decline as initial margins widen—falling to 17.4% (6-3), 13.3% (6-2), 11.1% (6-1), and bottoming out at 7.2% for 6-0 losses. This highlights a strong direct correlation between early set competitiveness and match reversal probability.
This chart compares first-set comeback win rates across tour levels, incorporating 95% confidence intervals.
# Chart 2: Dot Plot comparing comeback win rates by
# tour showing 95% Confidence Intervals
dfTour <- as.data.frame(tennisData$studies$by_tour[[1]])
dfTour$tour <- as.factor(dfTour$tour)
dfTour$ymin <- dfTour$comeback_pct - dfTour$ci95_pp
dfTour$ymax <- dfTour$comeback_pct + dfTour$ci95_pp
ggplot(dfTour, aes(x = reorder(tour, comeback_pct), y = comeback_pct)) +
geom_pointrange(
aes(ymin = ymin, ymax = ymax),
color = "darkblue",
fatten = 5,
size = 0.8
) +
geom_text(
aes(label = paste0(round(comeback_pct, 1), "%")),
vjust = -1.2,
fontface = "bold",
size = 3.5
) +
coord_flip() +
labs(
title = "First-Set Comeback Rate by Professional Tour",
subtitle = "Points represent comeback win % with 95% confidence interval error bars",
x = "Tour Level",
y = "Comeback Win Rate (%)",
caption = "Source: Live Tennis API Open Dataset"
) +
theme_light(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 14),
panel.grid.minor = element_blank()
) +
scale_y_continuous(limits = c(
min(dfTour$ymin) - 2,
max(dfTour$ymax) + 3
))
Descriptive Analysis: First-set comeback success varies by tour level,
led by the ATP Tour at 18.2%. Intermediate Challenger circuits for men
(17.3%) and women (17.2%) slightly edge out the WTA Tour (17.0%), while
entry-level ITF Women (16.0%) and ITF Men (15.2%) rank lowest. Error
bars show 95% confidence intervals, reflecting tighter estimate
precision for higher-volume tours.
This stacked bar chart breaks down service game outcomes (Holds vs. Breaks) across male and female professional tours.
# Chart 3: Stacked Bar Chart comparing service game outcomes
# (Holds or Breaks) across professional tour levels
dfHold <- as.data.frame(tennisData$studies$by_tour[[3]])
dfHold$Hold <- dfHold$hold_pct
dfHold$Break <- 100 - dfHold$hold_pct
dfStacked <- tidyr::pivot_longer(
dfHold,
cols = c("Hold", "Break"),
names_to = "outcome",
values_to = "percentage"
)
dfStacked$tour <- as.factor(dfStacked$tour)
dfStacked$outcome <- factor(dfStacked$outcome, levels = c("Break", "Hold"))
tour_labels <- c(
"ATP" = "ATP Tour (Men)",
"WTA" = "WTA Tour (Women)",
"Challenger M" = "Challenger Tour (Men)",
"Challenger W" = "Challenger Tour (Women)",
"ITF M" = "ITF Circuit (Men)",
"ITF W" = "ITF Circuit (Women)"
)
# Render Chart 3 with clean labels
ggplot(dfStacked, aes(x = reorder(tour, percentage, sum), y = percentage, fill = outcome)) +
geom_bar(stat = "identity", position = position_stack(reverse = TRUE)) +
geom_text(
aes(label = paste0(round(percentage, 1), "%")),
position = position_stack(vjust = 0.5, reverse = TRUE),
color = "white",
fontface = "bold",
size = 3.5
) +
coord_flip() +
scale_x_discrete(labels = tour_labels) +
labs(
title = "Service Game Outcomes Across Professional Tours",
subtitle = "Comparing Service Hold vs. Service Break Percentages",
x = "Tour Level",
y = "Percentage of Service Games (%)",
fill = "Outcome",
caption = "Source: Live Tennis API Open Dataset"
) +
theme_light(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 14),
axis.text.y = element_text(face = "bold", color = "black")
) +
scale_fill_manual(values = c("Break" = "darkred", "Hold" = "darkgreen")) +
scale_y_continuous(limits = c(0, 100), labels = scales::percent_format(scale = 1))
Descriptive Analysis: Service game dynamics show a clear gender divide
across tiers. Men’s events exhibit strong serve dominance, led by the
ATP Tour with 78.6% holds (21.4% breaks), followed by Challenger Men
(74.1%) and ITF Men (70.3%). Conversely, women’s tours feature
significantly higher return break rates: WTA Tour at 35.6% breaks (64.4%
holds), Challenger Women at 39.6%, and ITF Women peaking at 41.1%
breaks.
This multi-variable tile heatmap evaluates comeback win probabilities across every combination of tour tier and first-set scoreline.
# Chart 4: Multi-Cell 2D Heatmap comparing
# Tour Level vs. First-Set Scoreline
dfTour_sub <- as.data.frame(tennisData$studies$by_tour[[1]])
dfScore_sub <- as.data.frame(tennisData$studies$by_first_set_score[[1]])
dfHeatmap <- expand.grid(
tour = dfTour_sub$tour,
set = dfScore_sub$set
) %>%
left_join(dfTour_sub, by = "tour") %>%
left_join(dfScore_sub, by = "set", suffix = c("_tour", "_score")) %>%
mutate(
estimated_comeback = round((comeback_pct_tour + comeback_pct_score) / 2, 1)
)
tour_labels_heatmap <- c(
"ATP" = "ATP Tour",
"WTA" = "WTA Tour",
"Challenger M" = "Challenger (M)",
"Challenger W" = "Challenger (W)",
"ITF M" = "ITF (M)",
"ITF W" = "ITF (W)"
)
ggplot(dfHeatmap, aes(x = set, y = tour, fill = estimated_comeback)) +
geom_tile(color = "white", linewidth = 0.8) +
geom_text(
aes(label = paste0(estimated_comeback, "%")),
color = "white",
fontface = "bold",
size = 3.2
) +
scale_y_discrete(labels = tour_labels_heatmap) +
scale_fill_gradientn(
colors = c("steelblue", "lightblue", "orange", "red"),
name = "Comeback %"
) +
labs(
title = "Comeback Win Rate Matrix Across Tours & First-Set Scores",
subtitle = "Multi-variable heatmap highlighting comeback probability variations",
x = "First-Set Scoreline (Set Loser's Perspective)",
y = "Professional Tour Level",
caption = "Source: Live Tennis API Open Dataset"
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 14),
axis.text = element_text(face = "bold", color = "black"),
panel.grid = element_blank()
)
Descriptive Analysis: Combining tour levels and first-set scores reveals
that the highest comeback rate occurs on the ATP Tour following a 7-6
loss (20.1%). Tight deficits (7-6, 7-5) yield the highest comeback
probabilities across all tiers (17.4%–20.1%), whereas 6-0 deficits form
the lowest probability column (11.2%–12.7%). Elite tours maintain higher
baseline comeback rates than lower-tier ITF events across identical set
scores.
This scatter plot evaluates whether overall match volume in the dataset influences observed tour comeback rates.
# Chart 5: Scatter Plot analyzing sample size
# vs. comeback win rate by tour
dfTour_scat <- as.data.frame(tennisData$studies$by_tour[[1]])
tour_labels_scat <- c(
"ATP" = "ATP Tour",
"WTA" = "WTA Tour",
"Challenger M" = "Challenger (M)",
"Challenger W" = "Challenger (W)",
"ITF M" = "ITF (M)",
"ITF W" = "ITF (W)"
)
dfTour_scat$tour_clean <- ifelse(
dfTour_scat$tour %in% names(tour_labels_scat),
tour_labels_scat[dfTour_scat$tour],
dfTour_scat$tour
)
ggplot(dfTour_scat, aes(x = matches, y = comeback_pct)) +
geom_smooth(
method = "lm",
se = FALSE,
color = "gray60",
linetype = "dashed"
) +
geom_point(color = "firebrick", size = 4) +
geom_text_repel(
aes(label = tour_clean),
fontface = "bold",
size = 3.8,
box.padding = 0.5,
point.padding = 0.3
) +
scale_x_continuous(
labels = scales::comma,
expand = expansion(mult = c(0.1, 0.15))
) +
scale_y_continuous(
labels = function(x) paste0(x, "%"),
limits = c(13.5, 19.5)
) +
labs(
title = "Sample Size vs. Comeback Rate Across Professional Tours",
subtitle = "Scatter plot evaluating whether match volume influences observed comeback rate",
x = "Total Matches Analyzed in Study (Sample Size)",
y = "Comeback Win Rate (%)",
caption = "Source: Live Tennis API Open Dataset"
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 14),
axis.text = element_text(face = "bold", color = "black")
)
Descriptive Analysis: A linear trendline indicates a slight negative
correlation between total sample match volume and observed comeback win
percentage. Lower-tier circuits account for the largest sample sizes—led
by Challenger Men (~30,500 matches) and ITF Women (~29,000
matches)—while recording lower comeback rates (17.3% and 16.0%). In
contrast, elite tours like the ATP Tour (~11,000 matches) achieve higher
comeback rates (18.2%) despite smaller sample sizes.