From d74335cb8ef2014cd18bce873f2fe54f01f03044 Mon Sep 17 00:00:00 2001 From: Lennard Geese <lennard.geese@sva.de> Date: Wed, 9 Apr 2025 17:27:08 +0200 Subject: [PATCH] Implement painting graph background for weather change window --- DataPlotter.py | 75 +++++++++++++++++++++++++++++++++++++++++--------- Todos.md | 2 +- main.py | 18 ++++++++---- 3 files changed, 75 insertions(+), 20 deletions(-) diff --git a/DataPlotter.py b/DataPlotter.py index 9b95e74..d0bbb6d 100644 --- a/DataPlotter.py +++ b/DataPlotter.py @@ -1,41 +1,90 @@ +import random + import matplotlib.pyplot as plt +import pandas as pd +from matplotlib import cm +import matplotlib as mpl import numpy as np -from DataHandler import DataHandler +from matplotlib.colors import ListedColormap +from DataHandler import DataHandler +# TODO: Adjust input parameters for multiple weather change windows class DataPlotter(DataHandler): - def plotOvertakesWithTireChangeWindow(self, overtakesPerLap: list[int], earliestTireChange: int, latestTireChange: int, raceName: str): + def plotOvertakesWithTireChangeWindow(self, overtakesPerLap: list[int], firstTireChange: int, lastTireChange: int, raceName: str): + + # TODO: Account for cases where no tire changes (meaning values of 0 or -1) + # TODO: Let visualization start at 0, but graph at 1 + # Adjust values + #overtakesPerLap.insert(0, 0) # Insert 0th lap, which cannot have overtakes + firstTireChange -= 1 + lastTireChange += 1 + - overtakesPerLap.insert(0, 0) # Insert 0th lap, which cannot have overtakes laps: int = len(overtakesPerLap) + plt.xlim(0, laps + 1) # set x-range of plot + - figure, axis = plt.subplots(figsize=(8.0, 4.9)) + # Define data range + x_values = np.arange(1, laps + 1) + plt.plot(x_values, overtakesPerLap) - axis.plot(overtakesPerLap) + axis = plt.gca() + + # Label stuff axis.set_xlabel('Lap') axis.set_ylabel('Position changes in lap') axis.set_title(raceName) - major_ticks_laps = np.arange(0, laps, 5) + # Set ticks on axis + major_ticks_laps = np.arange(0, laps + 1, 5) major_ticks_overtakes = np.arange(0, max(overtakesPerLap) + 1, 5) - minor_ticks_laps = np.arange(0, laps, 1) + minor_ticks_laps = np.arange(0, laps + 1, 1) minor_ticks_overtakes = np.arange(0, max(overtakesPerLap) + 1, 1) - axis.set_xticks(major_ticks_laps) axis.set_xticks(minor_ticks_laps, minor=True) axis.set_yticks(major_ticks_overtakes) axis.set_yticks(minor_ticks_overtakes, minor=True) - # And a corresponding grid + # Add grid axis.grid(which='both') - - # Or if you want different settings for the grids: axis.grid(which='minor', alpha=0.2) axis.grid(which='major', alpha=0.5) - + # Add legend axis.legend(bbox_to_anchor=(1.0, 1.02)) + + # Paint background between the first and last tire change + axis.axvspan(firstTireChange, lastTireChange, color='blue', alpha=0.3) + + + plt.tight_layout() - plt.show() \ No newline at end of file + plt.show() + + + def plotBackgroundPaintTest(self): + + laps: int = 50 + overtakesPerLap: list[int] = [random.randint(0,10) for _ in range(laps)] + firstTireChange: int = random.randint(10, 20) + lastTireChange: int = random.randint(30, 40) + + isWeatherChanging: list[bool] = [False] * laps + for lap in range(laps): + if firstTireChange <= lap <= lastTireChange: + isWeatherChanging[lap] = True + + colormap = mpl.colors.ListedColormap(['white', 'blue']) + dataFrame = pd.DataFrame(overtakesPerLap) + dataFrame[1] = isWeatherChanging + axis = dataFrame[0].plot() + axis.pcolorfast(axis.get_xlim(), axis.get_ylim(), + dataFrame[1].values[np.newaxis], + cmap=colormap, alpha=0.3) + + plt.show() + + diff --git a/Todos.md b/Todos.md index 14da210..d34f5ff 100644 --- a/Todos.md +++ b/Todos.md @@ -2,7 +2,7 @@ - [x] Automatically title graph by race name (no more hardcoding the graph name) - [x] Adjust for pitstop discrepancies - [x] Fetch rain races via API, not Reddit -- [ ] Paint back of graph for weather change window +- [x] Paint back of graph for weather change window - [ ] Adjust for position changes caused by crashes (keep out of calculation similarly to PCs due to pitstops ?) - [ ] Include safety car periods & driver crashes - [ ] Automatically determine if race is DWR or SWR diff --git a/main.py b/main.py index d462a51..b10339d 100644 --- a/main.py +++ b/main.py @@ -18,12 +18,10 @@ class Main: def main(self): - dataHandler: Main.DataHandlingPackage = Main.DataHandlingPackage() - year: int = 2015 - rainRaces: list[Session] = dataHandler.importer.getRainRacesSince(year) - print(f"Rain races since {max(year, 2018)}") - for rainRace in rainRaces: - print(rainRace) + #dataHandler = Main.DataHandlingPackage() + #dataHandler.plotter.plotBackgroundPaintTest() + + # self.printRainRaces() racesToAnalyse = [ SessionIdentifier(2022, "Imola", "R"), # Imola 2022 (DWR) @@ -34,6 +32,14 @@ class Main: self.overtakeAnalysis(racesToAnalyse) + def printRainRaces(self): + dataHandler: Main.DataHandlingPackage = Main.DataHandlingPackage() + year: int = 2015 + rainRaces: list[Session] = dataHandler.importer.getRainRacesSince(year) + print(f"Rain races since {max(year, 2018)}") + for rainRace in rainRaces: + print(rainRace) + def overtakeAnalysis(self, raceSessionIdentifiers: list[SessionIdentifier]): dataHandler: Main.DataHandlingPackage = self.DataHandlingPackage() -- GitLab