These examples demonstrate how to analyze and visualize lap time data to compare driver and team performance.
Driver Lap Times
Plot a driver’s lap times throughout a race with color coding for tire compounds.
import seaborn as sns
from matplotlib import pyplot as plt
import fastf1
import fastf1.plotting
# Enable Matplotlib patches for plotting timedelta values and load
# FastF1's dark color scheme
fastf1.plotting.setup_mpl(mpl_timedelta_support=True, color_scheme='fastf1')
# Load the race session
race = fastf1.get_session(2023, "Azerbaijan", 'R')
race.load()
# Get all the laps for a single driver
# Filter out slow laps as they distort the graph axis
driver_laps = race.laps.pick_drivers("ALO").pick_quicklaps().reset_index()
# Make the scatterplot using lap number as x-axis and lap time as y-axis
# Marker colors correspond to the compounds used
fig, ax = plt.subplots(figsize=(8, 8))
sns.scatterplot(data=driver_laps,
x="LapNumber",
y="LapTime",
ax=ax,
hue="Compound",
palette=fastf1.plotting.get_compound_mapping(session=race),
s=80,
linewidth=0,
legend='auto')
# Make the plot more aesthetic
ax.set_xlabel("Lap Number")
ax.set_ylabel("Lap Time")
# The y-axis increases from bottom to top by default
# Since we are plotting time, it makes sense to invert the axis
ax.invert_yaxis()
plt.suptitle("Alonso Laptimes in the 2023 Azerbaijan Grand Prix")
# Turn on major grid lines
plt.grid(color='w', which='major', axis='both')
sns.despine(left=True, bottom=True)
plt.tight_layout()
plt.show()
What This Example Shows
- Filtering laps for a specific driver
- Using
pick_quicklaps() to remove outliers
- Plotting lap times as a scatter plot
- Color coding by tire compound
- Using seaborn for enhanced visualizations
Expected Output
A scatter plot showing lap times progressing through the race, with different colors for SOFT, MEDIUM, and HARD tire compounds. You can see tire degradation as lap times increase within each stint.
Key Functions
pick_drivers(): Select laps for specific driver(s)
pick_quicklaps(): Filter out slow laps (outliers, yellow flags, pit stops)
get_compound_mapping(): Get official tire compound colors
Lap Time Distributions
Visualize lap time distributions for multiple drivers using violin plots.
import seaborn as sns
from matplotlib import pyplot as plt
import fastf1
import fastf1.plotting
fastf1.plotting.setup_mpl(mpl_timedelta_support=True, color_scheme='fastf1')
# Load the race session
race = fastf1.get_session(2023, "Azerbaijan", 'R')
race.load()
# Get all the laps for the point finishers only
# Filter out slow laps (yellow flag, VSC, pitstops etc.)
point_finishers = race.drivers[:10]
print(point_finishers)
driver_laps = race.laps.pick_drivers(point_finishers).pick_quicklaps()
driver_laps = driver_laps.reset_index()
# To plot the drivers by finishing order,
# we need to get their three-letter abbreviations in the finishing order
finishing_order = [race.get_driver(i)["Abbreviation"] for i in point_finishers]
print(finishing_order)
# Create the figure
fig, ax = plt.subplots(figsize=(10, 5))
# Seaborn doesn't have proper timedelta support,
# so we have to convert timedelta to float (in seconds)
driver_laps["LapTime(s)"] = driver_laps["LapTime"].dt.total_seconds()
# First create the violin plots to show the distributions
sns.violinplot(data=driver_laps,
x="Driver",
y="LapTime(s)",
hue="Driver",
inner=None,
density_norm="area",
order=finishing_order,
palette=fastf1.plotting.get_driver_color_mapping(session=race)
)
# Then use the swarm plot to show the actual laptimes
sns.swarmplot(data=driver_laps,
x="Driver",
y="LapTime(s)",
order=finishing_order,
hue="Compound",
palette=fastf1.plotting.get_compound_mapping(session=race),
hue_order=["SOFT", "MEDIUM", "HARD"],
linewidth=0,
size=4,
)
# Make the plot more aesthetic
ax.set_xlabel("Driver")
ax.set_ylabel("Lap Time (s)")
plt.suptitle("2023 Azerbaijan Grand Prix Lap Time Distributions")
sns.despine(left=True, bottom=True)
plt.tight_layout()
plt.show()
What This Example Shows
- Comparing multiple drivers simultaneously
- Using violin plots to show lap time distributions
- Overlaying swarm plots to show individual laps
- Ordering drivers by finishing position
- Combining driver colors and compound colors
Expected Output
A visualization showing:
- Violin plots (colored by driver) showing the distribution shape
- Individual lap points (colored by tire compound) showing actual data
- Drivers ordered by finishing position (winner on left)
- Clear comparison of consistency and pace
Understanding the Visualization
Violin Plot Width: Shows the density of lap times at each speed. Wider = more laps at that pace.
Swarm Plot Points: Each point is an individual lap, colored by tire compound used.
Interpretation:
- Narrow distributions = consistent driver
- Lower position = faster pace
- Point patterns show tire strategy (clusters of colors)
Converting Time Data
When working with libraries that don’t support timedelta objects:
# Convert timedelta to seconds (float)
driver_laps["LapTime(s)"] = driver_laps["LapTime"].dt.total_seconds()
# Or format as string for display
from timple.timedelta import strftimedelta
lap_time_string = strftimedelta(lap_time, '%m:%s.%ms')
Filtering Laps
FastF1 provides several methods to filter lap data:
Quick Laps Only
# Remove laps outside 107% of fastest lap
quick_laps = laps.pick_quicklaps()
# Custom threshold (e.g., 105%)
quick_laps = laps.pick_quicklaps(threshold=1.05)
By Accuracy
# Only laps with accurate timing data
accurate_laps = laps.pick_accurate()
By Track Status
# Only laps under green flag conditions
green_flag_laps = laps.pick_track_status('1') # '1' = clear track
Multiple Filters
# Combine multiple filters
filtered_laps = (race.laps
.pick_drivers(['VER', 'HAM', 'LEC'])
.pick_quicklaps()
.pick_accurate())
Compound Colors
FastF1 automatically maps tire compounds to their official colors:
# Get compound color mapping for a session
compound_colors = fastf1.plotting.get_compound_mapping(session=race)
# Returns dict like:
# {'SOFT': '#FF0000', 'MEDIUM': '#FFFF00', 'HARD': '#FFFFFF'}
# Get specific compound color
soft_color = fastf1.plotting.get_compound_color('SOFT', session=race)
Compound colors vary by event. The same compound might be labeled as C1, C2, etc., and the colors (SOFT/MEDIUM/HARD) are assigned based on the selected compounds for that race weekend.
Loading Data Efficiently
# Only load what you need
session.load(telemetry=False, weather=False) # Faster for lap time analysis
# Full load for telemetry analysis
session.load() # Loads everything
Working with Large Datasets
# Filter early to reduce memory usage
driver_laps = race.laps.pick_drivers('VER').pick_quicklaps()
# Rather than:
all_laps = race.laps # Loads all laps
driver_laps = all_laps[all_laps['Driver'] == 'VER'] # Then filters