ATP Tennis Singles Matches

Source Notebook

Details about all ATP tennis singles matches from 1968 to 2024

Details

The Association of Tennis Professionals (ATP) is the governing body of the men's professional tennis circuit, responsible for organizing tournaments and ranking players.
This dataset covers the Open Era of tennis, which began in 1968 and allowed professional players to compete in Grand Slam tournaments.
The default content is a Tabular obejct containing the following proporties for each match:
"TournamentID"Unique tournament ID
"TournamentName"Tournament name
"Surface"Type of surface match is played on (i.e., grass, clay, hard or carpet)
"DrawSize"Number of players in tournament draw
"TournamentLevel"Tournament Level
"TournamentDate"Tournament Date
"MatchNumber"Unique identifier for match within tournament
"WinnerID"Unique identifier for player who won the match
"WinnerSeed"Seed number of match winner, if applicable
"WinnerName"Name of player who won match
"WinnerHand"Playing hand of winner (left or right)
"WinnerHeight"Height of winner in centimeters
"WinnerIOC"International Olympic Committee country code for winner
"WinnerAge"Age of winner at time of match.
"LoserID"Unique identifier for player who lost the match
"LoserSeed"Seed number of match loser, if applicable
"LoserName"Name of player who lost match
"LoserHand"Playing hand of loser (left or right)
"LoserHeight"Height of loser in centimeters
"LoserIOC"International Olympic Committee country code for loser
"LoserAge"Age of loser at time of match
"Score"Final score of match
"BestOf"Maximum number of sets to be played (i.e., best of 3 or 5)
"Round"Round of tournament in which match was played
"Minutes"Total duration of match in minutes
"WAces"Number of aces served by winner
"WDoubleFaults"Number of double faults made by winner
"WServePoints"Total number of serve points played by winner
"W1stServeIn"Number of first serves made by winner
"W1stServeWon"Number of points won on first serve by winner
"W2ndServeWon"Number of points won on second serve by winner
"WServeGames"Number of service games played by winner
"WBpSaved"Number of break points saved by winner
"WBpFaced"Number of break points faced by winner
"LAces"Number of aces served by loser
"LDoubleFaults"Number of double faults made by loser
"LServePoints"Total number of serve points played by loser
"L1stServeIn"Number of first serves made by loser
"L1stServeWon"Number of points won on first serve by loser
"L2ndServeWon"Number of points won on second serve by loser
"LServeGames"Number of service games played by loser
"LBpSaved"Number of break points saved by loser
"LBpFaced"Number of break points faced by loser
"WinnerRank"ATP ranking of winner at time of match
"WinnerRankPoints"ATP ranking points of winner at time of match
"LoserRank"ATP ranking of loser at time of match
"LoserRankPoints"ATP ranking points of loser at time of match
The "TournamentLevel" property can be one of the following:
G Grand Slams
MMasters 1000s
AOther tour-level events
CChallegers
SSatellites/ITFs
FTour finals and other season-ending events
DDavis Cup
Match statistics, such as aces and double faults, are included whenever available, generally covering the period from 1991 onward.
Additional content elements include:
"Players"Player-related information

Examples

Basic Examples (2) 

Retrieve the data as a Tabular object:

In[1]:=
ResourceData[\!\(\*
TagBox["\"\<ATP Tennis Singles Matches\>\"",
#& ,
BoxID -> "ResourceTag-ATP Tennis Singles Matches-Input",
AutoDelete->True]\)]
Out[1]=

Get structural information about the data using TabularStructure:

In[2]:=
TabularStructure[ResourceData[\!\(\*
TagBox["\"\<ATP Tennis Singles Matches\>\"",
#& ,
BoxID -> "ResourceTag-ATP Tennis Singles Matches-Input",
AutoDelete->True]\)], All, {"ColumnType", "NonMissingCount", "MissingCount", "CountDistinct"}]
Out[2]=

Scope & Additional Elements (1) 

Get information about players in the ATP Tour:

In[3]:=
ResourceData[\!\(\*
TagBox["\"\<ATP Tennis Singles Matches\>\"",
#& ,
BoxID -> "ResourceTag-ATP Tennis Singles Matches-Input",
AutoDelete->True]\), "Players"]
Out[3]=

Visualizations (2) 

Visualize the number of matches over the years. Notice the decrease around 2020 due to the Covid-19 pandemic:

In[4]:=
DateListPlot[GroupBy[ResourceData[\!\(\*
TagBox["\"\<ATP Tennis Singles Matches\>\"",
#& ,
BoxID -> "ResourceTag-ATP Tennis Singles Matches-Input",
AutoDelete->True]\)], DateObject[{#TournamentDate["Year"]}] &, Length]]
Out[4]=

Visualize players' birth years:

In[5]:=
DateHistogram[Normal[ResourceData[\!\(\*
TagBox["\"\<ATP Tennis Singles Matches\>\"",
#& ,
BoxID -> "ResourceTag-ATP Tennis Singles Matches-Input",
AutoDelete->True]\), "Players"][All, "DOB"]], "Year", "Count"]
Out[5]=

Analysis (5) 

Get the total number of matches recorded:

In[6]:=
Length[ResourceData[\!\(\*
TagBox["\"\<ATP Tennis Singles Matches\>\"",
#& ,
BoxID -> "ResourceTag-ATP Tennis Singles Matches-Input",
AutoDelete->True]\)]]
Out[6]=

As an unexpected result for many, take the top five players with the most wins:

In[7]:=
TakeLargest[Counts[ResourceData[\!\(\*
TagBox["\"\<ATP Tennis Singles Matches\>\"",
#& ,
BoxID -> "ResourceTag-ATP Tennis Singles Matches-Input",
AutoDelete->True]\)][All, "WinnerName"]], 5]
Out[7]=

Analyze the number of matches played on each surface over the years:

In[8]:=
Module[{surfaces, groupBySurface, surfaceData}, surfaces = {"Hard", "Clay", "Grass", "Carpet"};
 groupBySurface = Normal@GroupBy[ResourceData[\!\(\*
TagBox["\"\<ATP Tennis Singles Matches\>\"",
#& ,
BoxID -> "ResourceTag-ATP Tennis Singles Matches-Input",
AutoDelete->True]\)], {#Surface, DateObject[{#TournamentDate["Year"]}]} &, Length]; surfaceData = AssociationMap[surfaceName |->
    {#[[1, 2]], #[[2]]} & /@ Select[groupBySurface, #[[1, 1]] == surfaceName &],
   surfaces]; DateListPlot[Values[surfaceData], PlotLegends -> surfaces]
 ]
Out[8]=

Analyze the top five countries with the most wins over the years:

In[9]:=
Module[{groupByCoutry, coutryData, largestByWins}, groupByCoutry = Normal@GroupBy[ResourceData[\!\(\*
TagBox["\"\<ATP Tennis Singles Matches\>\"",
#& ,
BoxID -> "ResourceTag-ATP Tennis Singles Matches-Input",
AutoDelete->True]\)], {DateObject[{#TournamentDate[
         "Year"]}], #WinnerIOC} &, Length]; coutryData = AssociationMap[
     country |-> AssociationThread[#[[All, 1, 1]] -> Accumulate[Values[#]]] & /@ {Select[
       groupByCoutry, #[[1, 2]] == country &]},
     Union[ResourceData[\!\(\*
TagBox["\"\<ATP Tennis Singles Matches\>\"",
#& ,
BoxID -> "ResourceTag-ATP Tennis Singles Matches-Input",
AutoDelete->True]\)][All, "WinnerIOC"] // Normal]]; largestByWins = TakeLargestBy[coutryData, Last[Last[Values[#]]] &, 5]; DateListPlot[Values[largestByWins], PlotLegends -> Keys[largestByWins]]
 ]
Out[9]=

And compare it with each country's yearly win totals:

In[10]:=
Module[{groupByCoutryYearly, coutryDataYearly, largestByWinsYearly}, groupByCoutryYearly = Normal@GroupBy[ResourceData[\!\(\*
TagBox["\"\<ATP Tennis Singles Matches\>\"",
#& ,
BoxID -> "ResourceTag-ATP Tennis Singles Matches-Input",
AutoDelete->True]\)], {DateObject[{#TournamentDate[
         "Year"]}], #WinnerIOC} &, Length]; coutryDataYearly = AssociationMap[
     country |-> {#[[1, 1]], #[[2]]} & /@ Select[groupByCoutryYearly, #[[1, 2]] == country &],
     Union[ResourceData[\!\(\*
TagBox["\"\<ATP Tennis Singles Matches\>\"",
#& ,
BoxID -> "ResourceTag-ATP Tennis Singles Matches-Input",
AutoDelete->True]\)][All, "WinnerIOC"] // Normal]
   ];
 largestByWinsYearly = TakeLargestBy[coutryDataYearly, Total[#[[All, 2]]] &, 5]; DateListPlot[Values[largestByWinsYearly], PlotLegends -> Keys[largestByWinsYearly], PlotRange -> All]]
Out[10]=

Generate a Graph illustrating the connection between winners and losers:

In[11]:=
winnersAndLosers = ResourceData[\!\(\*
TagBox["\"\<ATP Tennis Singles Matches\>\"",
#& ,
BoxID -> "ResourceTag-ATP Tennis Singles Matches-Input",
AutoDelete->True]\)][All, {"WinnerName", "LoserName"}]; edges = DirectedEdge @@@ (Values /@ Normal[winnersAndLosers]);
graph = Graph[edges]
Out[12]=

Visualize it:

In[13]:=
GraphPlot@graph
Out[13]=

Find the shortest path between two players:

In[14]:=
path = FindShortestPath[graph, "Carlos Alcaraz", "Rod Laver"]
Out[14]=

Paths between players illustrate how wins have connected them over time:

In[15]:=
StringRiffle[path, ", who defeated "]
Out[15]=

Felipe Amorim, "ATP Tennis Singles Matches" from the Wolfram Data Repository (2025)  

Data Resource History

Source Metadata

Publisher Information