Over the last couple of races, I’ve started trying to review a variety of battlemaps for various drivers in each race. Prompted by an email request for more info around the battlemaps, I generated a new sketch charting the on track gaps between each driver and the lap leader for each lap of the race (How the F1 Canadian Grand Prix Race Evolved on Track).

Colour is used to identify cars on lead lap compared to lapped drivers. For lapped drivers, a count of how many laps they are behind the leader is displayed. I additionally overplot with a highlight for specified driver, as well as adding in a mark that shows the on track position of the leader of the next lap, along with their driver code.

Battles can be identified through the close proximity of two or more drivers within a lap, across several laps. The ‘next-lap-leader’ time at the far right shows how close the leader on the next lead lap is to the backmarker (on track) on the current lead lap.

By highlighting two particular drivers, we could compare how their races evolved, perhaps highlighting different strategies used within a race that eventually bring the drivers into a close competitive battle in the last few laps of a race.

The unchanging leader-on-track-delta-of-0 line is perhaps missing an informational opportunity? For example, should we set the leader’s time to be the delta compared to the lap time for the leader laps from the previous lead lap? Or a delta compared to the fastest laptime on the previous lead lap? And if we do start messing about with an offset to the leader’s lap time, we presumably need to apply the same offset to the laptime of everyone else on the lap so we can still see the comparative on-track gaps to leader?

On the to-do list are various strategies for automatically identifying potential battles based on a variety of in-lap and across-lap heuristics.

Here’s the code:

#Grab some data lapTimes =lapsData.df(2015,7) #Process the laptimes lapTimes=battlemap_encoder(laptimes) #Find the accumulated race time at the start of each leader's lap lapTimes=ddply(lapTimes,.(leadlap),transform,lstart=min(acctime)) #Find the on-track gap to leader lapTimes['trackdiff']=lapTimes['acctime']-lapTimes['lstart'] #Construct a dataframe that contains the difference between the #leader accumulated laptime on current lap and next lap #i.e. how far behind current lap leader is next-lap leader? ll=data.frame(t=diff(lapTimes[lapTimes['position']==1,'acctime'])) #Generate a de facto lap count ll['n']=1:nrow(ll) #Grab the code of the lap leader on the next lap ll['c']=lapTimes[lapTimes['position']==1 & lapTimes['lap']>1,'code'] #Plot the on-track gap to leader versus leader lap g = ggplot(lapTimes) g = g + geom_point(aes(x=trackdiff,y=leadlap,col=(lap==leadlap)), pch=1) g= g + geom_point(data=lapTimes[lapTimes['driverId']=='vettel',], aes(x=trackdiff,y=leadlap), pch='+') g=g + geom_text(data=lapTimes[lapTimes['lapsbehind']>0,], aes(x=trackdiff,y=leadlap, label=lapsbehind),size=3) g = g + geom_point(data=ll,aes(x=t, y=n), pch='x') g = g + geom_text(data=ll,aes(x=t+3, y=n,label=c), size=2) g = g + geom_vline(aes(xintercept=17), linetype=3) g

This chart will be included in a future update to the Wrangling F1 Data With R book. I hope to do a sprint on that book to tidy it up and get it into a reasonably edited state in the next few weeks. At that point, the text will probably be frozen, a print-on-demand version generated, and if it ends up on Amazon, the minimum price being hiked considerably.