Skip to content

Commit

Permalink
Add example: results tracker (#351)
Browse files Browse the repository at this point in the history
* Add an example script to visualise driver standings and points (#325)

* Configure sphinx-gallery to support scraping plotly output including gallery thumbnail using kaleido
  • Loading branch information
harningle authored Apr 15, 2023
1 parent 518f739 commit 3f4f262
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ docs/examples_gallery/

# all variations of cache directories
*_cache/
.DS_Store

# other data directories
reference/
Expand Down
9 changes: 8 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
from datetime import datetime
import re

import plotly.io as pio
from plotly.io._sg_scraper import plotly_sg_scraper

# -- Project information -----------------------------------------------------

# load version number from file in sources dir without importing
Expand Down Expand Up @@ -79,8 +82,11 @@
html_css_files = [
'css/custom.css',
]

doc_cache = os.path.abspath('../doc_cache')

# Plotly configuration: use sphinx to render plotly
pio.renderers.default = 'sphinx_gallery_png'

# matplotlib plot directive options
plot_pre_code = f"import numpy as np;" \
f"from matplotlib import pyplot as plt;" \
Expand All @@ -106,6 +112,7 @@
'gallery_dirs': 'examples_gallery',
'download_all_examples': False,
'remove_config_comments': True,
'image_scrapers': ('matplotlib', plotly_sg_scraper) # For plotly thumbnail
}

# options for latexpdf build
Expand Down
89 changes: 89 additions & 0 deletions examples/plot_results_tracker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
"""Plot driver standings in a heatmap
======================================
Plot the points for each driven in each race of a given season in a heatmap, as
https://public.tableau.com/app/profile/mateusz.karmalski/viz/F1ResultsTracker2022
"""

import pandas as pd
import plotly.express as px
from plotly.io import show

from fastf1.ergast import Ergast


##############################################################################
# First, we load the results for season 2022.
ergast = Ergast()
races = ergast.get_race_schedule(2022) # Races in year 2022
results = []

# For each race in the season
for rnd, race in races['raceName'].items():

# Get results. Note that we use the round no. + 1, because the round no.
# starts from one (1) instead of zero (0)
temp = ergast.get_race_results(season=2022, round=rnd + 1)
temp = temp.content[0]

# If there is a sprint, get the results as well
sprint = ergast.get_sprint_results(season=2022, round=rnd + 1)
if sprint.content and sprint.description['round'][0] == rnd + 1:
temp = pd.merge(temp, sprint.content[0], on='driverCode', how='left')
# Add sprint points and race points to get the total
temp['points'] = temp['points_x'] + temp['points_y']
temp.drop(columns=['points_x', 'points_y'], inplace=True)

# Add round no. and grand prix name
temp['round'] = rnd + 1
temp['race'] = race.removesuffix(' Grand Prix')
temp = temp[['round', 'race', 'driverCode', 'points']] # Keep useful cols.
results.append(temp)

# Append all races into a single dataframe
results = pd.concat(results)
races = results['race'].drop_duplicates()

##############################################################################
# Then we “reshape” the results to a wide table, where each row represents a
# driver and each column refers to a race, and the cell value is the points.
results = results.pivot(index='driverCode', columns='round', values='points')
# Here we have a 22-by-22 matrix (22 races and 22 drivers, incl. DEV and HUL)

# Rank the drivers by their total points
results['total_points'] = results.sum(axis=1)
results = results.sort_values(by='total_points', ascending=False)
results.drop(columns='total_points', inplace=True)

# Use race name, instead of round no., as column names
results.columns = races


##############################################################################
# The final step is to plot a heatmap using plotly
fig = px.imshow(
results,
text_auto=True,
aspect='auto', # Automatically adjust the aspect ratio
color_continuous_scale=[[0, 'rgb(198, 219, 239)'], # Blue scale
[0.25, 'rgb(107, 174, 214)'],
[0.5, 'rgb(33, 113, 181)'],
[0.75, 'rgb(8, 81, 156)'],
[1, 'rgb(8, 48, 107)']],
labels={'x': 'Race',
'y': 'Driver',
'color': 'Points'} # Change hover texts
)
fig.update_xaxes(title_text='') # Remove axis titles
fig.update_yaxes(title_text='')
fig.update_yaxes(tickmode='linear') # Show all ticks, i.e. driver names
fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor='LightGrey',
showline=False,
tickson='boundaries') # Show horizontal grid only
fig.update_xaxes(showgrid=False, showline=False) # And remove vertical grid
fig.update_layout(plot_bgcolor='rgba(0,0,0,0)') # White background
fig.update_layout(coloraxis_showscale=False) # Remove legend
fig.update_layout(xaxis=dict(side='top')) # x-axis on top
fig.update_layout(margin=dict(l=0, r=0, b=0, t=0)) # Remove border margins
fig
show(fig)
4 changes: 3 additions & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ readme-renderer
xdoctest
pre-commit
requests>=2.28.1
websockets>=10.3
websockets>=10.3
plotly
kaleido

0 comments on commit 3f4f262

Please sign in to comment.