import tif1
from tif1.plotting import plot_speed_comparison
session = tif1.get_session(2025, "Monaco Grand Prix", "Qualifying")
# Get fastest laps for two drivers
ver_fastest = session.get_driver("VER").get_fastest_lap()
lec_fastest = session.get_driver("LEC").get_fastest_lap()
# Plot speed comparison
plot_speed_comparison(
[ver_fastest, lec_fastest],
labels=["VER", "LEC"],
title="Monaco Q3 Speed Comparison"
)
```python
### Lap Time Evolution
Track how lap times evolve throughout a stint.
```python
from tif1.plotting import plot_lap_times
session = tif1.get_session(2025, "Bahrain Grand Prix", "Race")
laps = session.laps
# Filter to specific drivers
drivers = ["VER", "HAM", "LEC"]
filtered = laps[laps["Driver"].isin(drivers)]
plot_lap_times(
filtered,
by_driver=True,
highlight_compounds=True
)
```python
## Matplotlib Integration
For custom visualizations, use matplotlib directly.
### Telemetry Overlay
```python
import matplotlib.pyplot as plt
import tif1
session = tif1.get_session(2025, "Silverstone", "Race")
ver = session.get_driver("VER")
lap = ver.get_lap(15)
tel = lap.telemetry
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(12, 8), sharex=True)
# Speed
ax1.plot(tel["Distance"], tel["Speed"], color="#E10600", linewidth=2)
ax1.set_ylabel("Speed (km/h)")
ax1.grid(True, alpha=0.3)
# Throttle
ax2.plot(tel["Distance"], tel["Throttle"], color="#00D2BE", linewidth=2)
ax2.set_ylabel("Throttle (%)")
ax2.grid(True, alpha=0.3)
# Brake
ax3.plot(tel["Distance"], tel["Brake"].astype(int), color="#FF1E00", linewidth=2)
ax3.set_ylabel("Brake")
ax3.set_xlabel("Distance (m)")
ax3.grid(True, alpha=0.3)
plt.suptitle(f"VER Lap {lap['LapNumber']} Telemetry", fontsize=14, fontweight="bold")
plt.tight_layout()
plt.show()
```python
### Tire strategy visualization
```python
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
session = tif1.get_session(2025, "Monza", "Race")
laps = session.laps
# Compound colors
compound_colors = {
"SOFT": "#FF0000",
"MEDIUM": "#FFF200",
"HARD": "#FFFFFF",
"INTERMEDIATE": "#00FF00",
"WET": "#0000FF"
}
fig, ax = plt.subplots(figsize=(14, 8))
drivers = laps["Driver"].unique()
for i, driver in enumerate(drivers):
driver_laps = laps[laps["Driver"] == driver].sort_values("LapNumber")
for _, lap in driver_laps.iterrows():
color = compound_colors.get(lap["Compound"], "#CCCCCC")
ax.barh(i, 1, left=lap["LapNumber"], color=color, edgecolor="black", linewidth=0.5)
ax.set_yticks(range(len(drivers)))
ax.set_yticklabels(drivers)
ax.set_xlabel("Lap Number")
ax.set_title("Tire Strategy - 2025 Monza GP")
# Legend
patches = [mpatches.Patch(color=color, label=compound)
for compound, color in compound_colors.items()]
ax.legend(handles=patches, loc="upper right")
plt.tight_layout()
plt.show()
```python
## Plotly for interactive plots
Plotly enables interactive visualizations perfect for Jupyter notebooks.
### Interactive speed trace
```python
import plotly.graph_objects as go
import tif1
session = tif1.get_session(2025, "Spa", "Qualifying")
ver = session.get_driver("VER")
fastest = ver.get_fastest_lap()
tel = fastest.telemetry
fig = go.Figure()
fig.add_trace(go.Scatter(
x=tel["Distance"],
y=tel["Speed"],
mode="lines",
name="Speed",
line=dict(color="#E10600", width=2),
hovertemplate="Distance: %{x:.0f}m<br>Speed: %{y:.0f} km/h<extra></extra>"
))
fig.update_layout(
title="VER Fastest Lap - Speed Trace",
xaxis_title="Distance (m)",
yaxis_title="Speed (km/h)",
hovermode="x unified",
template="plotly_dark"
)
fig.show()
```python
### 3D Track Map
```python
import plotly.graph_objects as go
session = tif1.get_session(2025, "Suzuka", "Race")
ver = session.get_driver("VER")
lap = ver.get_lap(1)
tel = lap.telemetry
fig = go.Figure(data=[go.Scatter3d(
x=tel["X"],
y=tel["Y"],
z=tel["Z"],
mode="lines",
line=dict(
color=tel["Speed"],
colorscale="Viridis",
width=4,
colorbar=dict(title="Speed (km/h)")
),
hovertemplate="X: %{x:.0f}<br>Y: %{y:.0f}<br>Z: %{z:.0f}<br>Speed: %{marker.color:.0f} km/h<extra></extra>"
)])
fig.update_layout(
title="3D Track Map - Suzuka",
scene=dict(
xaxis_title="X (m)",
yaxis_title="Y (m)",
zaxis_title="Z (m)",
aspectmode="data"
),
template="plotly_dark"
)
fig.show()
```python
## Seaborn for statistical plots
Seaborn excels at statistical visualizations.
### Lap Time Distribution
```python
import seaborn as sns
import matplotlib.pyplot as plt
session = tif1.get_session(2025, "Barcelona", "Race")
laps = session.laps
# Clean data
clean = laps[~laps["Deleted"] & (laps["LapNumber"] > 1)]
plt.figure(figsize=(12, 6))
sns.violinplot(data=clean, x="Driver", y="LapTime", hue="Compound", split=False)
plt.xticks(rotation=45)
plt.title("Lap Time Distribution by Driver and Compound")
plt.ylabel("Lap Time (s)")
plt.tight_layout()
plt.show()
```python
### Correlation Heatmap
```python
import seaborn as sns
import matplotlib.pyplot as plt
session = tif1.get_session(2025, "Singapore", "Race")
laps = session.laps
# Select numeric columns
numeric_cols = ["LapTime", "Sector1Time", "Sector2Time", "Sector3Time",
"SpeedI1", "SpeedI2", "SpeedFL", "SpeedST",
"AirTemp", "TrackTemp", "TyreLife"]
correlation = laps[numeric_cols].corr()
plt.figure(figsize=(10, 8))
sns.heatmap(correlation, annot=True, fmt=".2f", cmap="coolwarm", center=0)
plt.title("Lap Data Correlation Matrix")
plt.tight_layout()
plt.show()
```python ## Best Practices
### Use Team Colors
Make plots more recognizable by using official team colors.
```python
session = tif1.get_session(2025, "Monaco", "Race")
drivers_df = session.drivers_df
# Create color map
color_map = dict(zip(drivers_df["Driver"], drivers_df["TeamColor"]))
# Use in plots
for driver in ["VER", "HAM", "LEC"]:
driver_laps = laps[laps["Driver"] == driver]
plt.plot(driver_laps["LapNumber"], driver_laps["LapTime"],
color=f"#{color_map[driver]}", label=driver)
```python
### Handle missing data
Always filter out invalid laps before plotting.
```python
def clean_for_plotting(laps):
"""Prepare laps for visualization."""
clean = laps.copy()
# Remove deleted laps
clean = clean[~clean["Deleted"]]
# Remove pit laps
clean = clean[clean["PitInTime"].isna()]
# Remove outliers
fastest = clean["LapTime"].min()
clean = clean[clean["LapTime"] < fastest * 1.10]
return clean
laps = session.laps
plot_data = clean_for_plotting(laps)
```bash
### Optimize for Performance
For large datasets, downsample telemetry before plotting.
```python
# Downsample telemetry to every 10th point
tel_downsampled = tel[::10]
plt.plot(tel_downsampled["Distance"], tel_downsampled["Speed"])
```bash
## Export for external tools
Save data for use in other visualization tools.
```python
# Export to CSV
laps.to_csv("race_laps.csv", index=False)
# Export to Parquet (smaller, faster)
laps.to_parquet("race_laps.parquet")
# Export to Excel
with pd.ExcelWriter("race_analysis.xlsx") as writer:
laps.to_excel(writer, sheet_name="Laps", index=False)
session.weather.to_excel(writer, sheet_name="Weather", index=False)
```python
---
## Related Pages
<CardGroup cols={2}>
<Card title="Plotting API" href="/api-reference/plotting">
Plotting reference
</Card>
<Card title="Examples" href="/examples">
Visualization examples
</Card>
<Card title="Telemetry Tutorial" href="/tutorials/advanced-telemetry">
Telemetry viz
</Card>
</CardGroup>