> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/theOehrly/Fast-F1/llms.txt
> Use this file to discover all available pages before exploring further.

# Race Strategy Examples

> Analyze race strategies including tire choices, pit stops, and position changes

These examples demonstrate how to analyze race strategies, tire compounds, position changes, and team performance.

## Tire Strategy

Visualize all drivers' tire strategies throughout a race.

```python theme={null}
from matplotlib import pyplot as plt
import fastf1
import fastf1.plotting

# Load the race session
session = fastf1.get_session(2022, "Hungary", 'R')
session.load()
laps = session.laps

# Get the list of drivers and convert to abbreviations
drivers = session.drivers
drivers = [session.get_driver(driver)["Abbreviation"] for driver in drivers]
print(drivers)

# Find the stint length and compound used for every stint by every driver
# Group by driver, stint number, and compound, then count laps
stints = laps[["Driver", "Stint", "Compound", "LapNumber"]]
stints = stints.groupby(["Driver", "Stint", "Compound"])
stints = stints.count().reset_index()

# Rename LapNumber column to StintLength
stints = stints.rename(columns={"LapNumber": "StintLength"})
print(stints)

# Plot the strategies for each driver
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():
        # Each row contains the compound name and stint length
        # Use these to draw horizontal bars
        compound_color = fastf1.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"]

# Make the plot more readable
plt.title("2022 Hungarian Grand Prix Strategies")
plt.xlabel("Lap Number")
plt.grid(False)
# Invert y-axis so drivers that finish higher are closer to the top
ax.invert_yaxis()

# Plot aesthetics
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_visible(False)

plt.tight_layout()
plt.show()
```

### What This Example Shows

* Grouping laps by driver and stint
* Calculating stint lengths
* Using horizontal bars to visualize strategies
* Color coding by tire compound
* Ordering drivers by finishing position

### Expected Output

A horizontal bar chart showing each driver's race with colored segments representing different tire compound stints. You can see:

* How many stops each driver made
* Which compounds they used and when
* Stint lengths for each driver
* Strategic differences between teams

### Understanding Stints

A **stint** is a period of running on the same set of tires. FastF1 automatically numbers stints:

* Stint 1: Start to first pit stop
* Stint 2: First pit stop to second pit stop
* And so on...

## Position Changes

Track how driver positions change throughout a race.

```python theme={null}
import matplotlib.pyplot as plt
import fastf1.plotting

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

# Load the session
session = fastf1.get_session(2023, 1, 'R')
session.load(telemetry=False, weather=False)

fig, ax = plt.subplots(figsize=(8.0, 4.9))

# For each driver, plot their position over the laps
for drv in session.drivers:
    drv_laps = session.laps.pick_drivers(drv)
    
    abb = drv_laps['Driver'].iloc[0]
    style = fastf1.plotting.get_driver_style(identifier=abb,
                                             style=['color', 'linestyle'],
                                             session=session)
    
    ax.plot(drv_laps['LapNumber'], drv_laps['Position'],
            label=abb, **style)

# Finalize the plot
ax.set_ylim([20.5, 0.5])
ax.set_yticks([1, 5, 10, 15, 20])
ax.set_xlabel('Lap')
ax.set_ylabel('Position')

# Add legend outside the plot area
ax.legend(bbox_to_anchor=(1.0, 1.02))
plt.tight_layout()

plt.show()
```

### What This Example Shows

* Tracking position changes lap by lap
* Using driver-specific styling (colors and line styles)
* Creating an inverted y-axis (position 1 at top)
* Handling crowded plots with external legends

### Expected Output

A line plot showing all drivers' positions throughout the race. You can observe:

* Starting grid positions
* Overtakes and position swaps
* Pit stop drops
* Safety car bunching
* Final finishing order

### Performance Optimization

```python theme={null}
# For position analysis, skip telemetry and weather data
session.load(telemetry=False, weather=False)
```

This significantly speeds up loading when you only need lap-by-lap data.

## Qualifying Results

Visualize qualifying results with time gaps to pole position.

```python theme={null}
import matplotlib.pyplot as plt
import pandas as pd
from timple.timedelta import strftimedelta
import fastf1
import fastf1.plotting
from fastf1.core import Laps

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

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

# Get an array of all drivers
drivers = pd.unique(session.laps['Driver'])
print(drivers)

# Get each driver's fastest lap and create a sorted list
list_fastest_laps = list()
for drv in drivers:
    drvs_fastest_lap = session.laps.pick_drivers(drv).pick_fastest()
    list_fastest_laps.append(drvs_fastest_lap)

fastest_laps = Laps(list_fastest_laps) \
    .sort_values(by='LapTime') \
    .reset_index(drop=True)

# Calculate time delta from pole position
pole_lap = fastest_laps.pick_fastest()
fastest_laps['LapTimeDelta'] = fastest_laps['LapTime'] - pole_lap['LapTime']

print(fastest_laps[['Driver', 'LapTime', 'LapTimeDelta']])

# Create a list of team colors per lap
team_colors = list()
for index, lap in fastest_laps.iterlaps():
    color = fastf1.plotting.get_team_color(lap['Team'], session=session)
    team_colors.append(color)

# Plot the data
fig, ax = plt.subplots()
ax.barh(fastest_laps.index, fastest_laps['LapTimeDelta'],
        color=team_colors, edgecolor='grey')
ax.set_yticks(fastest_laps.index)
ax.set_yticklabels(fastest_laps['Driver'])

# Show fastest at the top
ax.invert_yaxis()

# Draw vertical lines behind the bars
ax.set_axisbelow(True)
ax.xaxis.grid(True, which='major', linestyle='--', color='black', zorder=-1000)

# Add title with pole lap time
lap_time_string = strftimedelta(pole_lap['LapTime'], '%m:%s.%ms')
plt.suptitle(f"{session.event['EventName']} {session.event.year} Qualifying\n"
             f"Fastest Lap: {lap_time_string} ({pole_lap['Driver']})")

plt.show()
```

### What This Example Shows

* Collecting fastest laps for all drivers
* Calculating time gaps from pole position
* Creating horizontal bar charts
* Using team colors for bars
* Formatting timedelta for display

### Expected Output

A horizontal bar chart showing the qualifying results, with bars representing the time gap to pole position. Team colors make it easy to compare teammates.

## Team Pace Ranking

Rank teams by race pace using box plots.

```python theme={null}
import seaborn as sns
from matplotlib import pyplot as plt
import fastf1
import fastf1.plotting

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

# Load the race session and pick quick laps
race = fastf1.get_session(2024, 1, 'R')
race.load()
laps = race.laps.pick_quicklaps()

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

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

# Create color palette for teams
team_palette = {team: fastf1.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("2024 Bahrain Grand Prix - Team Pace Comparison")
plt.grid(visible=False)
ax.set(xlabel=None)
plt.tight_layout()
plt.show()
```

### What This Example Shows

* Aggregating laps by team
* Using box plots to show pace distribution
* Ordering teams by median pace
* Customizing box plot styling

### Expected Output

A box plot showing each team's lap time distribution:

* **Box**: 25th to 75th percentile (middle 50% of laps)
* **Line in box**: Median lap time
* **Whiskers**: Extend to show range (excluding outliers)
* **Teams ordered**: Fastest (left) to slowest (right)

### Understanding Box Plots

* **Narrow box**: Consistent pace
* **Wide box**: Variable pace (tire deg, traffic, etc.)
* **Lower position**: Faster overall pace
* **Outliers**: Shown as individual points beyond whiskers

## Strategy Analysis Tips

### Identifying Strategic Trends

```python theme={null}
# Count pit stops per driver
pit_stops = stints.groupby('Driver').size() - 1  # Subtract 1 (initial stint)

# Most common strategy
common_strategy = stints.groupby(['Stint', 'Compound']).size()

# Average stint length by compound
avg_stint_length = stints.groupby('Compound')['StintLength'].mean()
```

### Comparing Strategies

```python theme={null}
# Compare two drivers' strategies
driver1_stints = stints[stints['Driver'] == 'VER']
driver2_stints = stints[stints['Driver'] == 'HAM']

print("VER stints:", driver1_stints[['Stint', 'Compound', 'StintLength']])
print("HAM stints:", driver2_stints[['Stint', 'Compound', 'StintLength']])
```

<Note>
  Strategy analysis is most interesting for dry races. Mixed conditions races may show unusual patterns due to weather-driven pit stops.
</Note>
