The 2021 FIA Formula One World Championship was contested over twenty - two Grands Prix and held around the world. After a fierce battle for championship between Max Verstappen and Lewis Hamilton, Verstappen won his first World Championship. Hamilton, the defending champion, finished runner-up.
I implemented the visualization of the battle with the BarChartRace which has been often seen on SNS and other media these days.
Out[]=
Base URLs
Base URLs
In[]:=
baseURL="https://www.formula1.com/en/results.html/";driversURL[year_]:=URL[baseURL<>StringTemplate["``/drivers.html"][year]];
Final result
Final result
Show the final result in 2021 as follows.
In[]:=
year=2021;Grid[Join[{{"rank","driver","country","team","point"}},Import[driversURL[year],"Data"][[3,2]][[2]]],Background{None,{LightGray}},Alignment{{Right,Left,Center,Left,"."}}]
Out[]=
rank | driver | country | team | point |
1 | Max Verstappen VER | NED | Red Bull Racing Honda | 395.5 |
2 | Lewis Hamilton HAM | GBR | Mercedes | 387.5 |
3 | Valtteri Bottas BOT | FIN | Mercedes | 226 |
4 | Sergio Perez PER | MEX | Red Bull Racing Honda | 190 |
5 | Carlos Sainz SAI | ESP | Ferrari | 164.5 |
6 | Lando Norris NOR | GBR | McLaren Mercedes | 160 |
7 | Charles Leclerc LEC | MON | Ferrari | 159 |
8 | Daniel Ricciardo RIC | AUS | McLaren Mercedes | 115 |
9 | Pierre Gasly GAS | FRA | AlphaTauri Honda | 110 |
10 | Fernando Alonso ALO | ESP | Alpine Renault | 81 |
11 | Esteban Ocon OCO | FRA | Alpine Renault | 74 |
12 | Sebastian Vettel VET | GER | Aston Martin Mercedes | 43 |
13 | Lance Stroll STR | CAN | Aston Martin Mercedes | 34 |
14 | Yuki Tsunoda TSU | JPN | AlphaTauri Honda | 32 |
15 | George Russell RUS | GBR | Williams Mercedes | 16 |
16 | Kimi Räikkönen RAI | FIN | Alfa Romeo Racing Ferrari | 10 |
17 | Nicholas Latifi LAT | CAN | Williams Mercedes | 7 |
18 | Antonio Giovinazzi GIO | ITA | Alfa Romeo Racing Ferrari | 3 |
19 | Mick Schumacher MSC | GER | Haas Ferrari | 0 |
20 | Robert Kubica KUB | POL | Alfa Romeo Racing Ferrari | 0 |
21 | Nikita Mazepin MAZ | RAF | Haas Ferrari | 0 |
Table of accumulated drivers’ points
Table of accumulated drivers’ points
Create a table of accumulated points for each driver in twenty-two Grands Prix, which will be used as input for BarChartRace.
First, get URLs with detailed information of all drivers in a specified year.
In[]:=
getdriverURL[year_]:=Module[{resp,xml,pos},resp=URLRead[driversURL@year];xml=resp["Body"]//ImportString[#,"XMLObject"]&;pos=Position[xml,XMLElement["tbody",___]][[1]];Cases[Extract[xml,pos],XMLElement["a",{"shape""rect","class""dark bold ArchiveLink","href"x_,___},___]URL["https://www.formula1.com"<>x],∞]];driverURLs=getdriverURL[year];driverURLs[[1]]
Out[]=
URL
Get a driver name from the URL obtained above.
In[]:=
getdrivername[driverurl_URL]:=Module[{resp,xml},resp=URLRead[driverurl];xml=resp["Body"]//ImportString[#,"XMLObject"]&;Cases[xml[[2]],XMLElement["title",{},{x_}]StringSplit@x,∞][[1,-2;;]]];getdrivername[driverURLs[[1]]]
Out[]=
{Max,Verstappen}
The information in driverURLs is a list of points for the Grands Prix in which the driver participated. In other words, there is no points for the Grands Prix in which the driver did not participate. Taking this into account, create a table of accumulated points in all Grands Prix during the year.
In[]:=
getlocationandpoint[xml_]:={(*location*)Cases[xml,XMLElement["a",{"shape""rect","class""dark ArchiveLink",___},{x_}]x,∞][[1]],(*point*)Cases[xml,XMLElement["td",{"colspan""1","rowspan""1","class""dark bold"},{x_}]ToExpression@x,∞][[-1]]};getresult[driverurl_URL]:=Module[{resp,xml,p,list},resp=URLRead[driverurl];xml=resp["Body"]//ImportString[#,"XMLObject"]&;p=Position[xml,XMLElement["tr",{},___]];list=getlocationandpoint[Extract[xml,#]]&/@p[[2;;]];(*locationandpointfortheGrandsPrixinwhichthedriverparticipated*)Association@Thread[list[[All,1]]->list[[All,2]]]];getresult2[driverurl_URL,locations_List]:=Module[{as,v,list},as=getresult@driverurl;v=Lookup[as,#,0]&/@locations;(*driver,locationandpointforallGrandsPrix*)list=Association@Join[{"name"->(getdrivername@driverurl)[[2]]},Thread[locations->v]]];getaccumulate[year_]:=Module[{driverURLs,drivernames,result,result2,maxpos,locations,accumulate},(*dirversURL*)driverURLs=getdriverURL[year];(*driversname*)drivernames=getdrivername/@driverURLs;(*locationandpointfortheGrandsPrixinwhichthedriverparticipated*)result=getresult/@driverURLs;maxpos=Position[Length/@result,Max[Length/@result]][[1,1]];(*allGrandsPrix*)locations=Keys[result[[maxpos]]];(*pointsforallGrandsPrix*)result2=getresult2[#,locations]&/@driverURLs;(*joinallGrandsPrix*)result2=Join[{Join[{"driver"},locations]},Values@result2];(*accumulatepoints*)accumulate=Join[{result2[[1]]},Join[{#[[1]]},Accumulate[#[[2;;]]]]&/@result2[[2;;]]];accumulate];
In[]:=
accumulate=getaccumulate[year];
Show the table of accumulated drivers' points.
In[]:=
Grid[accumulate,Background{None,{LightGray}},Alignment{Join[{Left},Table[".",(Dimensions@accumulate)[[2]]-1]]},ItemSizeFull]
Out[]=
driver | Bahrain | Emilia Romagna | Portugal | Spain | Monaco | Azerbaijan | France | Styria | Austria | Great Britain | Hungary | Belgium | Netherlands | Italy | Russia | Turkey | United States | Mexico | Brazil | Qatar | Saudi Arabia | Abu Dhabi |
Verstappen | 18 | 43 | 61 | 80 | 105 | 105 | 131 | 156 | 182 | 185 | 187 | 199.5 | 224.5 | 226.5 | 244.5 | 262.5 | 287.5 | 312.5 | 332.5 | 351.5 | 369.5 | 395.5 |
Hamilton | 25 | 44 | 69 | 94 | 101 | 101 | 119 | 138 | 150 | 177 | 195 | 202.5 | 221.5 | 221.5 | 246.5 | 256.5 | 275.5 | 293.5 | 318.5 | 343.5 | 369.5 | 387.5 |
Bottas | 16 | 16 | 32 | 47 | 47 | 47 | 59 | 74 | 92 | 108 | 108 | 108 | 123 | 141 | 151 | 177 | 185 | 185 | 203 | 203 | 218 | 226 |
Perez | 10 | 10 | 22 | 32 | 44 | 69 | 84 | 96 | 104 | 104 | 104 | 104 | 108 | 118 | 120 | 135 | 150 | 165 | 178 | 190 | 190 | 190 |
Sainz | 4 | 14 | 14 | 20 | 38 | 42 | 42 | 50 | 60 | 68 | 83 | 83.5 | 89.5 | 97.5 | 112.5 | 116.5 | 122.5 | 130.5 | 139.5 | 145.5 | 149.5 | 164.5 |
Norris | 12 | 27 | 37 | 41 | 56 | 66 | 76 | 86 | 101 | 113 | 113 | 113 | 114 | 132 | 139 | 145 | 149 | 150 | 151 | 153 | 154 | 160 |
Leclerc | 8 | 20 | 28 | 40 | 40 | 52 | 52 | 58 | 62 | 80 | 80 | 82 | 92 | 104 | 104 | 116 | 128 | 138 | 148 | 152 | 158 | 159 |
Ricciardo | 6 | 14 | 16 | 24 | 24 | 26 | 34 | 34 | 40 | 50 | 50 | 56 | 56 | 83 | 95 | 95 | 105 | 105 | 105 | 105 | 115 | 115 |
Gasly | 0 | 6 | 7 | 8 | 16 | 31 | 37 | 37 | 39 | 39 | 50 | 54 | 66 | 66 | 66 | 74 | 74 | 86 | 92 | 92 | 100 | 110 |
Alonso | 0 | 1 | 5 | 5 | 5 | 13 | 17 | 19 | 20 | 26 | 38 | 38 | 46 | 50 | 58 | 58 | 58 | 60 | 62 | 77 | 77 | 81 |
Ocon | 0 | 2 | 8 | 10 | 12 | 12 | 12 | 12 | 12 | 14 | 39 | 42 | 44 | 45 | 45 | 46 | 46 | 46 | 50 | 60 | 72 | 74 |
Vettel | 0 | 0 | 0 | 0 | 10 | 28 | 30 | 30 | 30 | 30 | 30 | 35 | 35 | 35 | 35 | 35 | 36 | 42 | 42 | 43 | 43 | 43 |
Stroll | 1 | 5 | 5 | 5 | 9 | 9 | 10 | 14 | 14 | 18 | 18 | 18 | 18 | 24 | 24 | 26 | 26 | 26 | 26 | 34 | 34 | 34 |
Tsunoda | 2 | 2 | 2 | 2 | 2 | 8 | 8 | 9 | 9 | 10 | 18 | 18 | 18 | 18 | 18 | 18 | 20 | 20 | 20 | 20 | 20 | 32 |
Russell | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 4 | 13 | 13 | 15 | 16 | 16 | 16 | 16 | 16 | 16 | 16 | 16 |
Räikkönen | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 2 | 2 | 2 | 2 | 6 | 6 | 6 | 10 | 10 | 10 | 10 | 10 |
Latifi | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 6 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 |
Giovinazzi | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 3 | 3 |
Schumacher | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Kubica | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Mazepin | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
BarChartRace
BarChartRace
I have published a Wolfram Language version of BarChartRace, which you may have seen on social networking sites, to the WOLFRAM FUNCTION REPOSITORY.