2019 F1 season: ALL THE LAPS!

If we could see all the laps done over the season, how would it look? Here, I attempt to answer that question, and hopefully, answer a few questions about the race pace of each team. Let’s take a look at the numbers.


There is absolutely no way of putting all the laps in a single plot without making the appropriate transformations. Laps from races like Spa take over 1 minute and 40 seconds, while laps done in Austria are just over a minute long. To be able to compare laps from different races, I did two different transformations. First, I transformed the data to a scale of 0 to 1, just to be able to visualize all the laps. Second, I filtered in ordered to remove outliers, and re-transformed the data to either (1) a percentile scale, or (2) a standardized scale. I will explain a bit more about those transformations in the analysis.

Regarding the outliers, I will first explain about what they are and why I decided to remove them. My idea was to show the laps that were representative of the pace of each team. Outliers are laps that are not representative, for example, the first lap of the race, or laps done when the safety car was out. The best way to remove them is by knowing exactly in which laps the safety car was out for example, and then filtering those out. Unfortunately I do not have that data for every single lap of the season. Maybe I should have it, but I don’t. So what’s the solution then? Well, I decided to use statistical methods to automatically detect those outliers that I was just talking about.

In the chart shown above, you’ll see that I used five different methods to detect these outliers. Outlier detection is not an exact science. Some methods are very aggressive, and may wrongly classify “normal” laps as outliers. Some are the other way around, a bit too soft, and may not remove some of those anomalies. The most important thing to know is that there’s no perfect choice about which method to use. I will explain a bit more about this process in the next section of the article.
Finally, I created a few plots that look quite similar, show the same data points, but present the information in different ways. I will explain their differences in that section of the article.

Detection and removal of outliers

You can slide between both of the images shown. The first one shows every single lap done throughout the season. The second one shows how the data looks after removing those pesky outliers.

In the first chart, we can see how the races have many of these outliers. Take the Brazilian GP as an example. There are many red-coloured laps at the bottom of the chart, representing laps done under racing conditions. But as we know, the Brazilian GP required the safety car to come out for quite a few laps. Those laps are detected as outliers by every single method that we used. That’s good!

The first method is a combination of the remaining four methods. What are the remaining four methods you may ask? Just different ways of detecting anomalies in the data. In this case, we are trying to detect laps that are considered “strangely” slow. So slow that they just can’t be part of normal racing. In our case, method three, four and five give us similar results. Method two is great for non-normal distributions but has a great disadvantage here. Since it’s so good at removing outliers from both sides of the distribution, it also considers many of the faster laps as outliers, which is something that we do not want.

The second chart shows our dataset after removing outliers. Now everything looks more uniform, leaving only representative laps. While the distribution is not entirely normal, meaning that it doesn’t form a perfect Gaussian bell, it’s still pretty good for our purposes.

Once again, we can see that the methods test detected different numbers of outliers. Method 1 is a combination of the remaining four, so it makes sense that it is the most conservative one. Method two would be great for other applications, but it’s too aggressive for what we wanted to do here.

I ended up choosing method 4, the second most aggressive from the ones that I tested. The idea behind this decision is pretty simple. The more conservative methods may leave some excessively slow laps on our dataset, penalizing teams like Williams and Haas a little bit too much for my taste. By using a more aggressive approach, I may have ended up removing some of their slowest laps, but it won’t affect their distribution that much. Think of it this way. I’d rather remove a 1 minute 55 seconds lap (which was a valid lap) than leave a 2 minutes and 10 seconds lap (an anomaly) on the dataset.

All laps by percentile

Believe it or not, this chart shows 20,477 laps. As stated in the methodology section, the lap times needed to be transformed to show them in a single chart. Here, they were transformed in a way that shows in which percentile that particular lap time belongs. For example, a lap in the 50th percentile shows that its time was faster than 50% of the laps during a race, but also slower than the other 50%. Mercedes, for example, has most of their laps below the 24th percentile (mean percentile). This means that on average, their laps were faster than 76% of the laps done in a race. Their median as a team was in the 19th percentile overall. This means that 50% of their laps were among the 19% fastest laps done throughout a race.

Williams was the worst in this category. Their mean percentile was the 79th percentile. On a race by race basis, on average, Williams’ laps were slower than 79% of all the laps done during a race. Their median was in the 86th percentile. Once again, this means that 50% of their laps were slower than 86% of all the laps done during a race.

What about the funky bar at the bottom of the chart? That is a stacked density plot. It shows the distribution of the laps over the x-axis (percentile). The next graph shows the same data in a slightly different way.

This is another way of taking a look at the same data. Transformed the same way, analyzed the same way. The main difference is that this type of plot allows us to take a better look at the distribution of lap times.

The most important result aspect of the plot is the shape of the “bell”. Teams that had most of the fastest laps done over the race have shown a right-skewed distribution. This refers to the way the shape of the bell looks. In the case of the top three teams, it’s right-skewed because you have a tall bell on the left side and a very long tail on the right side.

Midfield teams tend to have a more symmetrical distribution. Their laps were usually between the 25th and 75th percentile, with some being among the fastest and some among the slowest.

Slow teams show a left-skewed distribution. Teams like Alfa Romeo, Haas, and Williams, show this type of distribution. Many of their lap times were among the slowest half of the laps done during a race.

All laps by Z-score

The previous chart has a particular…disadvantage. The percentiles tell you the number of times X lap was faster or slower compared to the rest of the laps, but it doesn’t tell you how much faster or slower they were. To fix that, I decided to standardize the lap times.

Standardizing means subtracting the mean time of all the laps done over a race from every single lap done in that race. That number is then divided by the standard deviation of all the laps. What we end up with a scale called the Z-score. This scale allows us to see how far each lap time was from the average time of all the laps of the race.

Let me show you an example. In the chart above, the black line is positioned at number 0. This means that laps that are around this line were “average”. Laps between the -1 and 0 mark were slightly faster than average, while laps between the 0 and 1 mark were slightly slower than average. The farther the laps are from the mean line, the slower they were compared to the average time of a particular race.

The difference between teams is quite clear. The top teams were considerably faster than the midfield teams. In the midfield, McLaren has a small but distinct advantage over Renault. Toro Rosso and Racing Point were almost equal, while Alfa Romeo distinctively trailed behind them. Haas was the 9th fastest team, and Williams ranked as the worst team in this analysis.

The ridge plot shows how tight was the midfield battle. McLaren had a great season, and comfortably took the 4th position in the Constructor’s Championship. However, their race pace wasn’t necessarily particularly superior to the pace of teams like Renault, Toro Rosso, or even Racing Point.

Take a look at the 1st, 2nd (median) and third quartiles for each team. The difference between Mercedes, Ferrari, and Red Bull, is subtle, but clear. Mercedes was significatively, but not tremendously, faster than Ferrari. We see the same pattern between the Scuderia and Red Bull. Midfield teams, however, do not show this pattern. McLaren seems to be just ahead of Renault, but then the French team, Toro Rosso and Racing point are separated by practically nothing. You can see that Renault took 5th place because their 3rd quartile is slightly more to the left than Toro Rosso and Racing Point’s. In other words, their slower laps were a little bit faster compared to those two teams.

Final remarks

The first thing that came to my mind when taking a look at the charts was: “wow, the order of the teams is the same as the standings of the season”. This wasn’t ordered by me. I didn’t have any input on ordering teams. The rankings were created just based on the race pace of every team during the season.

The results prove to me that the teams deserved their finishing positions, which is great. They also tell me that this midfield battle was closer than I thought. I knew that the midfield teams were pretty even, but it’s still interesting to see how similar their performance was after thousands of laps.

It’s quite unfortunate that the laps cannot be compared with their original times, which are easier to interpret, but that is the nature of our dataset. At the end of the day, I think that is a good thing. Nobody wants to see a single race repeated 21 times. Everybody wants to see 21 different races, with unexpected results.

In any case, I hope that you have enjoyed this article. If you did, let me know. Perhaps I could do the same for each driver? Thank you for taking the time to read, and please, help me out by share my site with your friends and people who may enjoy this type of content.


  1. Marc Matthies

    This is a fun way of looking at the season 🙂

    If we can conclude that the team standings are correct, can we then also say something about individual drivers performance?

    For example

    -Alfa Romeo finished 8th, meaning the drivers “should” have finished 15 and 16th. Yet Kimi finished 12th and Giovinazzi 17th. Kimi performed better than his car was worth.

    – Renault finished 5th, meaning the drivers should have finished 9th and 10th. Ricciardo finished 9th, yet the Hulk only finished 14th. So Daniel “merely” reached his car’s potential while Nico underperformed.

    • admin

      Hello Marc

      You could do it, but then again, the standings are correct because the drivers performed the way they performed. It’s like circular logic. The only way you could definitively conclude that, would be if you knew that, Alfa Romeo for example, would finish in 8th place even before the season started. Then yes, you would expect both drivers to finish around that position, and if they did more, then they exceeded the potential, or if they did less, then they failed to live up to it.

      In real life, separating the driver’s performance from the car’s performance is not possible with frequentist statistics (the normal ones). This is because of the way the data is structured. This is because a from X team is tied to Y driver. Without Y driver getting to test another car, we cannot know how good he would be in that particular car. We cannot say how good Kubica would be in a Mercedes, because he has never driven a Mercedes’ car.

      What we can do, however, is to make some assumptions and compare the performance of each driver within teams. Why? Well, both drivers technically drive the same car, so you are basically saying that Kimi and Gio both had the same tools. If they did, then you can compare their performance (statistically). You could state confidently that Kimi was faster than Gio throughout the season, or if Gio was faster than Kimi, or if both of them were statistically the same. Yes, perhaps Kimi was slightly faster, or the other way around, but maybe the difference was so little that statistically they were both just as good. But saying that a driver matched the car’s potential is not really possible. In our dataset a car is just as good as the driver, and the driver is intrinsically related to the team. They are pretty much one entity, and even with fancy modelling analyses, they cannot be separated.

      I hope this makes a bit of sense.

  2. Marc Matthies

    That certainly makes sense.

    (I also get those circular logic errors in excel, and then im always dissapointed in myself 😉 )

    • admin

      Haha, it all sounds great when you think about it. Then you get to work and you’re like “what was I thinking?” … Don’t worry, it happens to most people … ALL THE TIME.


Submit a Comment

Your email address will not be published. Required fields are marked *