Skip to main content
FastF1’s plotting module provides tools for creating professional-looking F1 visualizations with official team colors, driver-specific styling, and matplotlib integration.

Setup Matplotlib

Before creating visualizations, configure matplotlib for optimal F1 data plotting:
import fastf1
from fastf1 import plotting
from matplotlib import pyplot as plt

# Enable FastF1's plotting features
plotting.setup_mpl(
    mpl_timedelta_support=True,  # Enable timedelta formatting
    color_scheme='fastf1'        # Use FastF1 dark color scheme
)

Setup Options

  • mpl_timedelta_support: Enables proper formatting of lap times and time deltas on plot axes. Essential for plotting LapTime, sector times, and other timedelta values.
  • color_scheme: Set to 'fastf1' for the signature dark theme with optimized colors, or None for default matplotlib styling.

Team Colors

FastF1 automatically provides official F1 team colors for any session:
import fastf1
from fastf1 import plotting

# Load a session
race = fastf1.get_session(2023, "Azerbaijan", 'R')
race.load()

# Get team color for a specific team
rbr_color = plotting.get_team_color('Red Bull Racing', session=race)
mer_color = plotting.get_team_color('Mercedes', session=race)

# List all teams in the session
teams = plotting.list_team_names(session=race)
print(teams)

Using Team Colors in Plots

import matplotlib.pyplot as plt
import seaborn as sns

# Create a team pace comparison with official colors
race = fastf1.get_session(2024, 1, 'R')
race.load()
laps = race.laps.pick_quicklaps()

# Convert lap times to seconds
transformed_laps = laps.copy()
transformed_laps.loc[:, "LapTime (s)"] = laps["LapTime"].dt.total_seconds()

# Order teams by median lap time
team_order = (
    transformed_laps[["Team", "LapTime (s)"]]
    .groupby("Team")
    .median()["LapTime (s)"]
    .sort_values()
    .index
)

# Create color palette with official team colors
team_palette = {
    team: plotting.get_team_color(team, session=race)
    for team in team_order
}

# Create box plot
fig, ax = plt.subplots(figsize=(15, 10))
sns.boxplot(
    data=transformed_laps,
    x="Team",
    y="LapTime (s)",
    hue="Team",
    order=team_order,
    palette=team_palette,
    whiskerprops=dict(color="white"),
    boxprops=dict(edgecolor="white"),
    medianprops=dict(color="grey"),
    capprops=dict(color="white"),
)

plt.title("Team Pace Comparison")
plt.grid(visible=False)
ax.set(xlabel=None)
plt.tight_layout()
plt.show()

Driver Styling

Apply consistent driver-specific colors and line styles to plots:
from matplotlib import pyplot as plt
from fastf1 import plotting

race = fastf1.get_session(2023, "Azerbaijan", 'R')
race.load()

# Basic driver styling
fig, ax = plt.subplots(figsize=(8, 5))

for driver in ('HAM', 'PER', 'VER', 'RUS'):
    laps = race.laps.pick_drivers(driver).pick_quicklaps().reset_index()
    
    # Get driver style (color and line style)
    style = plotting.get_driver_style(
        identifier=driver,
        style=['color', 'linestyle'],
        session=race
    )
    
    ax.plot(laps['LapNumber'], laps['LapTime'], **style, label=driver)

ax.set_xlabel("Lap Number")
ax.set_ylabel("Lap Time")
ax.legend()
plt.show()

Sorted Driver Legends

Automatically sort legend entries by team and driver order:
fig, ax = plt.subplots(figsize=(8, 5))

for driver in ('HAM', 'PER', 'VER', 'RUS'):
    laps = race.laps.pick_drivers(driver).pick_quicklaps().reset_index()
    style = plotting.get_driver_style(
        identifier=driver,
        style=['color', 'linestyle'],
        session=race
    )
    ax.plot(laps['LapNumber'], laps['LapTime'], **style, label=driver)

ax.set_xlabel("Lap Number")
ax.set_ylabel("Lap Time")

# Add sorted legend instead of regular legend
plotting.add_sorted_driver_legend(ax, race)

plt.show()

Custom Driver Styles

Define custom styling variants while keeping official team colors:
# Define custom styles for first and second drivers
my_styles = [
    # Style for each team's first driver
    {'color': 'auto', 'linestyle': 'solid', 'linewidth': 5, 'alpha': 0.3},
    # Style for each team's second driver
    {'color': 'auto', 'linestyle': 'solid', 'linewidth': 1, 'alpha': 0.7}
]

fig, ax = plt.subplots(figsize=(8, 5))

for driver in ('HAM', 'PER', 'VER', 'RUS'):
    laps = race.laps.pick_drivers(driver).pick_quicklaps().reset_index()
    
    # Use custom styles with 'auto' for team colors
    style = plotting.get_driver_style(
        identifier=driver,
        style=my_styles,
        session=race
    )
    
    ax.plot(laps['LapNumber'], laps['LapTime'], **style, label=driver)

ax.set_xlabel("Lap Number")
ax.set_ylabel("Lap Time")
plotting.add_sorted_driver_legend(ax, race)
plt.show()
The magic keyword 'auto' is replaced with the official team color automatically.

Tire Compound Colors

Visualize tire strategies with official compound colors:
import seaborn as sns
from matplotlib import pyplot as plt

race = fastf1.get_session(2023, "Azerbaijan", 'R')
race.load()

# Get laps for a driver
driver_laps = race.laps.pick_drivers("ALO").pick_quicklaps().reset_index()

# Create scatter plot with compound colors
fig, ax = plt.subplots(figsize=(8, 8))

sns.scatterplot(
    data=driver_laps,
    x="LapNumber",
    y="LapTime",
    ax=ax,
    hue="Compound",
    palette=plotting.get_compound_mapping(session=race),
    s=80,
    linewidth=0,
    legend='auto'
)

ax.set_xlabel("Lap Number")
ax.set_ylabel("Lap Time")
ax.invert_yaxis()  # Faster times at top

plt.suptitle("Alonso Lap Times - 2023 Azerbaijan GP")
plt.grid(color='w', which='major', axis='both')
sns.despine(left=True, bottom=True)
plt.tight_layout()
plt.show()

Tire Strategy Visualization

from matplotlib import pyplot as plt
import fastf1
from fastf1 import plotting

plotting.setup_mpl(color_scheme='fastf1')

session = fastf1.get_session(2022, "Hungary", 'R')
session.load()
laps = session.laps

# Get drivers and convert to abbreviations
drivers = [session.get_driver(d)["Abbreviation"] for d in session.drivers]

# Group laps by driver, stint, and compound
stints = laps[["Driver", "Stint", "Compound", "LapNumber"]]
stints = stints.groupby(["Driver", "Stint", "Compound"]).count().reset_index()
stints = stints.rename(columns={"LapNumber": "StintLength"})

# Plot strategies
fig, ax = plt.subplots(figsize=(5, 10))

for driver in drivers:
    driver_stints = stints.loc[stints["Driver"] == driver]
    
    previous_stint_end = 0
    for idx, row in driver_stints.iterrows():
        compound_color = plotting.get_compound_color(
            row["Compound"],
            session=session
        )
        plt.barh(
            y=driver,
            width=row["StintLength"],
            left=previous_stint_end,
            color=compound_color,
            edgecolor="black",
            fill=True
        )
        previous_stint_end += row["StintLength"]

plt.title("2022 Hungarian GP - Tire Strategies")
plt.xlabel("Lap Number")
plt.grid(False)
ax.invert_yaxis()
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_visible(False)
plt.tight_layout()
plt.show()

Telemetry Visualization

Speed Traces

import matplotlib.pyplot as plt
import fastf1
from fastf1 import plotting

plotting.setup_mpl(mpl_timedelta_support=True, color_scheme='fastf1')

session = fastf1.get_session(2021, 'Spanish Grand Prix', 'Q')
session.load()

# Get fastest laps for two drivers
ver_lap = session.laps.pick_drivers('VER').pick_fastest()
ham_lap = session.laps.pick_drivers('HAM').pick_fastest()

# Get telemetry with distance
ver_tel = ver_lap.get_car_data().add_distance()
ham_tel = ham_lap.get_car_data().add_distance()

# Get team colors
rbr_color = plotting.get_team_color(ver_lap['Team'], session=session)
mer_color = plotting.get_team_color(ham_lap['Team'], session=session)

# Plot speed comparison
fig, ax = plt.subplots()
ax.plot(ver_tel['Distance'], ver_tel['Speed'], color=rbr_color, label='VER')
ax.plot(ham_tel['Distance'], ham_tel['Speed'], color=mer_color, label='HAM')

ax.set_xlabel('Distance (m)')
ax.set_ylabel('Speed (km/h)')
ax.legend()
plt.suptitle(f"Fastest Lap Comparison\n{session.event['EventName']} {session.event.year} Qualifying")
plt.show()

Gear Visualization on Track Map

import matplotlib.pyplot as plt
import numpy as np
from matplotlib import colormaps
from matplotlib.collections import LineCollection
import fastf1

session = fastf1.get_session(2021, 'Austrian Grand Prix', 'Q')
session.load()

lap = session.laps.pick_fastest()
tel = lap.get_telemetry()

# Prepare track coordinates
x = np.array(tel['X'].values)
y = np.array(tel['Y'].values)
points = np.array([x, y]).T.reshape(-1, 1, 2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)
gear = tel['nGear'].to_numpy().astype(float)

# Create colored line segments
cmap = colormaps['Paired']
lc_comp = LineCollection(segments, norm=plt.Normalize(1, cmap.N+1), cmap=cmap)
lc_comp.set_array(gear)
lc_comp.set_linewidth(4)

# Plot
plt.gca().add_collection(lc_comp)
plt.axis('equal')
plt.tick_params(labelleft=False, left=False, labelbottom=False, bottom=False)

title = plt.suptitle(
    f"Gear Shift Visualization\n{lap['Driver']} - {session.event['EventName']} {session.event.year}"
)

# Add colorbar
cbar = plt.colorbar(mappable=lc_comp, label="Gear", boundaries=np.arange(1, 10))
cbar.set_ticks(np.arange(1.5, 9.5))
cbar.set_ticklabels(np.arange(1, 9))

plt.show()

Available Plotting Functions

FastF1’s plotting module provides these key functions:
FunctionDescription
setup_mpl()Configure matplotlib for FastF1
get_team_color()Get official team color
get_team_name()Get official team name
list_team_names()List all teams in session
get_driver_color()Get driver’s team color
get_driver_style()Get driver plot styling
get_driver_name()Get driver’s full name
get_driver_abbreviation()Get driver abbreviation
list_driver_names()List all drivers in session
add_sorted_driver_legend()Add sorted legend to plot
get_compound_color()Get tire compound color
get_compound_mapping()Get compound-to-color mapping
list_compounds()List available compounds

Best Practices

  1. Always call setup_mpl() before creating plots
  2. Enable timedelta support when plotting lap times: setup_mpl(mpl_timedelta_support=True)
  3. Pass the session object to color/style functions for accurate season data
  4. Use pick_quicklaps() to filter outlier lap times before visualization
  5. Invert Y-axis for time-based plots so faster times appear at the top
  6. Use official colors via get_team_color() and get_driver_style() for professional appearance

Next Steps

Build docs developers (and LLMs) love