<jupyter_start><jupyter_text>Introduction + BackgroundThis is a notebook that generates a ridgeline plot of the laptimes for teams in the endurance race at Baja SAE Louisville 2021.Data is available from the Baja SAE results website. I used a Chrome extension to download all the data and put it in an excel sheet, which is attached in this repo. Code based on F1 lap analysis code from reddit user hvcno.<jupyter_code>import re
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt<jupyter_output>C:\Users\ksali\Anaconda3\lib\site-packages\statsmodels\tools\_testing.py:19: FutureWarning: pandas.util.testing is deprecated. Use the functions in the public API at pandas.testing instead.
  import pandas.util.testing as tm<jupyter_text>Helpers<jupyter_code># Some regex helpers
driver_name = re.compile('([a-zA-Z])+\w ([A-Z])\w+')
lap_time = re.compile('([0-9])+:([0-9])+.([0-9])+')
lap_count = re.compile('([0-9])+')
def convert_lap_time_to_seconds(x):
    tot_time = 3600*x.hour + 60*x.minute + x.second + 0.000001*x.microsecond
    #print(tot_time)
    return tot_time<jupyter_output><empty_output><jupyter_text>Execution<jupyter_code>excel_sheet1 = pd.read_excel('All Louisville Times Sheet.xlsx', "Virginia Tech")
excel_sheet2 = pd.read_excel('All Louisville Times Sheet.xlsx', 1)

teams = pd.ExcelFile('All Louisville Times Sheet.xlsx').sheet_names
# print(excel_file)
print(excel_sheet['Lap Time'])
print(teams)
all_times = pd.DataFrame(columns=['Team Name', 'Lap Time'])

for team in teams:
    excel_sheet = pd.read_excel('All Louisville Times Sheet.xlsx', team)
    times = excel_sheet['Lap Time']

    if len(times) > 40:
        names_list = [team] * len(times)

        temp_frame = pd.DataFrame()
        temp_frame['Team Name'] = pd.Series(names_list)
        temp_frame['Lap Time'] = times

        all_times = all_times.append(temp_frame, ignore_index=True)

all_times = all_times.dropna()
print(all_times)
all_times.head()
all_times.tail()
all_times['laptime_seconds'] = all_times['Lap Time'].apply(convert_lap_time_to_seconds)
all_times = all_times[all_times['laptime_seconds'] < 300]  # Eliminate really long laptimes
all_times.head()
# Hardcode finishing order to help seaborn arrange the plots correctly

raw_finishes = ['Iowa State Univ',
'Georgia Institute of Technology',
'Pennsylvania College of Technology',
'Univ of Michigan - Ann Arbor',
'Georgia Southern Univ',
'Northwestern Univ',
'Cleveland State Univ',
'Rochester Institute of Technology',
'Lehigh Univ',
'North Carolina State Univ - Raleigh',
'Tennessee Tech Univ',
'Clarkson University',
'Cornell Univ',
'Purdue Univ - W Lafayette',
'Michigan Tech Univ',
'South Dakota School of Mines & Tech',
'Rowan Univ',
'Youngstown State Univ',
'Univ of Rochester'
'Kansas State Univ'
'Oklahoma State Univ'
'Virginia Tech'
'Lawrence Technological Univ'
'Texas A&M Univ'
'Univ of Oklahoma'
'Univ of Illinois - Urbana Champaign'
'Univ of Missouri - Kansas City'
'Mississippi State Univ'
'Univ of Maryland - Baltimore County'
'Manhattan College'
'Auburn Univ'
'Penn State Univ - Altoona'
'Johns Hopkins Univ'
'Case Western Reserve Univ'
'Univ of Virginia'
'Western New England University'
'The Ohio State University'
'Missouri University of Science and Tech'
'Univ of Iowa'
'Citadel'
'Univ of Nevada - Las Vegas'
'Univ of Alabama - Tuscaloosa'
'Fairfield Univ'
'Virginia Military Inst'
'Olivet Nazarene Univ'
'West Virginia Univ'
'Univ of Puerto Rico-Mayaquez'
'Christian Brothers Univ'
'Purdue Univ - Northwest'
'Univ of Central Florida'
'Univ of Notre Dame'
'Univ of Evansville'
'South Dakota State Univ'
'Univ of Akron'
'Alfred Univ'
'Montana State Univ - Bozeman'
'Univ of Tennessee - Martin'
'Universidade de Santa Cruz do Sul'
'Univ Federal do Rio Grande do Norte'
'Centro Universitario Da FEI'
'Ohio Northern Univ'
'York College of Pennsylvania'
'Middle Tennessee State Univ'
'Univ of West Florida'
'Wright State Univ'
'Louisiana Tech Univ'
'Univ of Tennessee - Chattanooga'
'Syracuse Univ'
'Eastern Michigan Univ'
'Binghamton Univ'
'Southern Illinois Univ - Edwardville'
'Union College'
'Univ of Michigan - Flint'
'Embry-Riddle Aero Univ - Daytona Beach'
'Lamar Univ'
'Univ of Southern Indiana'
'Central Michigan Univ'
'Liberty Univ'
'Quinnipiac University'
'North Carolina A & T State Univ'
'Lipscomb Univ'
'Univ of Pittsburgh - Johnstown']

finishing_order = [x for x in raw_finishes if x in all_times['Team Name'].unique()
print(finishing_order)
# Encode team colours maybe ill get to this 
mercedes = '#01ffcd' #'#00d2be' # <-- official colours from the F1 website, but they look ugly in a plot
redbull = '#0000fe'#'#0600ef'
mclaren = '#ff6600'#'#ff8700'
ferrari = '#fe0000' #'#dc0000'
racing_point = '#ff99cb'#'#f596c8'
renault = '#ffc000' #'#fff500'
alpha_tauri = '#000000'
alfa_romeo = '#960000'
haas = '#787878'
williams = '#0082fa'

colors = [
    mercedes,
    redbull,
    mclaren,
    ferrari,
    racing_point,
    renault,
    alpha_tauri,
    alfa_romeo,
    haas,
    williams
]
# Test out our colormap
col = sns.color_palette([color_lookup[d] for d in finishing_order])
sns.palplot(col)<jupyter_output><empty_output><jupyter_text>PlotAdapted from an [official example](https://seaborn.pydata.org/examples/kde_ridgeplot.html)<jupyter_code>sns.set(style="white", rc={"axes.facecolor": (0, 0, 0, 0)})

g = sns.FacetGrid(all_times,
                  row='Team Name', # <-- "driver" column (was lazy and didn't rename)
                  hue='Team Name',
                  aspect=15,
                  height=1,
                  palette="viridis",
                  row_order=finishing_order,
                  hue_order=finishing_order)
# Map a KDE plot for each driver
g.map(sns.kdeplot, 'laptime_seconds', clip_on=False, shade=True, alpha=1, bw=0.5)
# Add a white outline
g.map(sns.kdeplot, 'laptime_seconds', clip_on=False, color='w', alpha=1, lw=3, bw=0.5)
# Add a solid horizontal line
g.map(plt.axhline, y=0, lw=2, clip_on=False)

# Define and use a simple function to label the plot in axes coordinates
def label(x, color, label):
    ax = plt.gca()
    ax.text(0, .1, label, fontweight="bold", color=color,
            ha="left", va="center", transform=ax.transAxes)


g.map(label, "Team Name")

# Set the subplots to overlap
g.fig.subplots_adjust(hspace=-0.5)

# Remove axes details that don't play well with overlap
g.set(yticks=[])
g.despine(bottom=True, left=True)

g.set_titles("")
g.set(xlim=(190,300))
g.set_axis_labels('Laptime (seconds)')
plt.suptitle('Laptime distributions for Baja SAE Louisville 2021', fontsize=20)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11905123916679337, 'fraction_numerical': 0.0202219857077695, 'mean_word_length': 4.755030621172353, 'pattern_counts': {'":': 1, '<': 19, '<?xml version=': 0, '>': 17, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '444005', 'license': 'MIT', 'n_tokens_mistral': 2476, 'n_tokens_neox': 2255, 'n_words': 679, 'path': 'Misc/.ipynb_checkpoints/f1-2020-hungarian-grand-prix-checkpoint.ipynb', 'repo_name': 'kevinSaladpants/baja-db', 'size': '6577'}