-
-
Notifications
You must be signed in to change notification settings - Fork 271
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* 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
Showing
4 changed files
with
101 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,4 +12,6 @@ readme-renderer | |
xdoctest | ||
pre-commit | ||
requests>=2.28.1 | ||
websockets>=10.3 | ||
websockets>=10.3 | ||
plotly | ||
kaleido |