Skip to content
Snippets Groups Projects
Commit 94007bb7 authored by Marius Heidenreich's avatar Marius Heidenreich
Browse files

claude bessere plots

parent dc658c30
No related branches found
No related tags found
No related merge requests found
...@@ -19,6 +19,7 @@ class EloSystem: ...@@ -19,6 +19,7 @@ class EloSystem:
self.output_directory = output_directory self.output_directory = output_directory
self.teams = {} # Dictionary to store team Elo ratings self.teams = {} # Dictionary to store team Elo ratings
self.match_history = [] # List to store all match results for history tracking self.match_history = [] # List to store all match results for history tracking
self.competition_history = {} # Dictionary to store competition results
self.initialize_output_directory() self.initialize_output_directory()
def initialize_output_directory(self): def initialize_output_directory(self):
...@@ -63,7 +64,7 @@ class EloSystem: ...@@ -63,7 +64,7 @@ class EloSystem:
'competitions': 0, 'competitions': 0,
'history': [] 'history': []
} }
teams_in_competition.append(team_name) teams_in_competition.append((rank, team_name))
except StopIteration: except StopIteration:
# File is empty # File is empty
continue continue
...@@ -79,6 +80,7 @@ class EloSystem: ...@@ -79,6 +80,7 @@ class EloSystem:
team_name = row[1].strip() if len(row) > 1 else row[0].strip() team_name = row[1].strip() if len(row) > 1 else row[0].strip()
else: else:
# If no explicit ranking, use row index # If no explicit ranking, use row index
rank = len(teams_in_competition) + 1
team_name = row[0].strip() team_name = row[0].strip()
# Initialize the team if not seen before # Initialize the team if not seen before
...@@ -88,20 +90,36 @@ class EloSystem: ...@@ -88,20 +90,36 @@ class EloSystem:
'competitions': 0, 'competitions': 0,
'history': [] 'history': []
} }
teams_in_competition.append(team_name) teams_in_competition.append((rank, team_name))
# Sort teams by rank
teams_in_competition.sort(key=lambda x: x[0])
# Store competition results
date = datetime.now().strftime("%Y-%m-%d") # Use current date as competition date
self.competition_history[competition_name] = {
'date': date,
'results': teams_in_competition
}
# Extract just team names in order
team_names = [team[1] for team in teams_in_competition]
# Update competition count for each team # Update competition count for each team
for team_name in teams_in_competition: for team_name in team_names:
self.teams[team_name]['competitions'] += 1 self.teams[team_name]['competitions'] += 1
# Update Elo ratings based on this competition's results # Update Elo ratings based on this competition's results
self.update_elo_for_competition(teams_in_competition, competition_name) self.update_elo_for_competition(team_names, competition_name)
def update_elo_for_competition(self, teams_in_order, competition_name): def update_elo_for_competition(self, teams_in_order, competition_name):
"""Update Elo ratings for all teams in a competition""" """Update Elo ratings for all teams in a competition"""
# For each team, compare with teams ranked below them # For each team, compare with teams ranked below them
date = datetime.now().strftime("%Y-%m-%d") # Use current date as competition date date = datetime.now().strftime("%Y-%m-%d") # Use current date as competition date
# Store pre-competition Elo ratings
pre_competition_elo = {team: self.teams[team]['elo'] for team in teams_in_order}
for i in range(len(teams_in_order)): for i in range(len(teams_in_order)):
for j in range(i + 1, len(teams_in_order)): for j in range(i + 1, len(teams_in_order)):
team_a = teams_in_order[i] team_a = teams_in_order[i]
...@@ -110,6 +128,21 @@ class EloSystem: ...@@ -110,6 +128,21 @@ class EloSystem:
# Team A is ranked higher than Team B # Team A is ranked higher than Team B
self.update_elo_pair(team_a, team_b, 1, 0, competition_name, date) self.update_elo_pair(team_a, team_b, 1, 0, competition_name, date)
# Store post-competition Elo ratings and changes
for team in teams_in_order:
elo_change = self.teams[team]['elo'] - pre_competition_elo[team]
rank = teams_in_order.index(team) + 1
# Store in team history
self.teams[team]['history'].append({
'date': date,
'competition': competition_name,
'rank': rank,
'previous_elo': pre_competition_elo[team],
'new_elo': self.teams[team]['elo'],
'elo_change': elo_change
})
def update_elo_pair(self, team_a, team_b, score_a, score_b, competition_name, date): def update_elo_pair(self, team_a, team_b, score_a, score_b, competition_name, date):
"""Update Elo ratings for a pair of teams based on their match outcome""" """Update Elo ratings for a pair of teams based on their match outcome"""
# Get current Elo ratings # Get current Elo ratings
...@@ -139,13 +172,10 @@ class EloSystem: ...@@ -139,13 +172,10 @@ class EloSystem:
} }
self.match_history.append(match_info) self.match_history.append(match_info)
# Update team Elo ratings and history # Update team Elo ratings
self.teams[team_a]['elo'] = new_rating_a self.teams[team_a]['elo'] = new_rating_a
self.teams[team_b]['elo'] = new_rating_b self.teams[team_b]['elo'] = new_rating_b
self.teams[team_a]['history'].append({'date': date, 'elo': new_rating_a, 'competition': competition_name})
self.teams[team_b]['history'].append({'date': date, 'elo': new_rating_b, 'competition': competition_name})
def expected_score(self, rating_a, rating_b): def expected_score(self, rating_a, rating_b):
"""Calculate the expected score for a player with rating_a against a player with rating_b""" """Calculate the expected score for a player with rating_a against a player with rating_b"""
return 1 / (1 + math.pow(10, (rating_b - rating_a) / 400)) return 1 / (1 + math.pow(10, (rating_b - rating_a) / 400))
...@@ -227,7 +257,7 @@ class EloSystem: ...@@ -227,7 +257,7 @@ class EloSystem:
</head> </head>
<body> <body>
<h1>Team Elo Rankings</h1> <h1>Team Elo Rankings</h1>
<p>Rankings based on {len(self.match_history)} matches from {self.count_competitions()} competitions.</p> <p>Rankings based on {len(self.competition_history)} competitions.</p>
<div class="chart-container"> <div class="chart-container">
<img src="images/top_teams_elo.png" alt="Top Teams Elo Chart"> <img src="images/top_teams_elo.png" alt="Top Teams Elo Chart">
...@@ -277,9 +307,8 @@ class EloSystem: ...@@ -277,9 +307,8 @@ class EloSystem:
if team_data['history']: if team_data['history']:
self.create_team_elo_history_chart(team_name) self.create_team_elo_history_chart(team_name)
# Get matches involving this team # Filter history for this team's competitions
team_matches = [match for match in self.match_history team_competitions = sorted(team_data['history'], key=lambda x: x['date'], reverse=True)
if match['team_a'] == team_name or match['team_b'] == team_name]
html_content = f"""<!DOCTYPE html> html_content = f"""<!DOCTYPE html>
<html lang="en"> <html lang="en">
...@@ -360,6 +389,12 @@ class EloSystem: ...@@ -360,6 +389,12 @@ class EloSystem:
font-size: 14px; font-size: 14px;
color: #666; color: #666;
}} }}
.positive {{
color: green;
}}
.negative {{
color: red;
}}
</style> </style>
</head> </head>
<body> <body>
...@@ -377,21 +412,19 @@ class EloSystem: ...@@ -377,21 +412,19 @@ class EloSystem:
</div> </div>
""" """
# Calculate win rate if applicable # Calculate average ranking if available
if team_matches: if team_competitions:
wins = sum(1 for match in team_matches avg_rank = sum(comp['rank'] for comp in team_competitions) / len(team_competitions)
if (match['team_a'] == team_name and match['score_a'] > match['score_b']) best_rank = min(comp['rank'] for comp in team_competitions)
or (match['team_b'] == team_name and match['score_b'] > match['score_a']))
win_rate = (wins / len(team_matches)) * 100
html_content += f""" html_content += f"""
<div class="stat-box"> <div class="stat-box">
<div class="stat-value">{len(team_matches)}</div> <div class="stat-value">{avg_rank:.1f}</div>
<div class="stat-label">Total Matches</div> <div class="stat-label">Avg. Placement</div>
</div> </div>
<div class="stat-box"> <div class="stat-box">
<div class="stat-value">{win_rate:.1f}%</div> <div class="stat-value">{best_rank}</div>
<div class="stat-label">Win Rate</div> <div class="stat-label">Best Placement</div>
</div> </div>
""" """
...@@ -402,40 +435,31 @@ class EloSystem: ...@@ -402,40 +435,31 @@ class EloSystem:
<img src="images/{}_history.png" alt="{} Elo History"> <img src="images/{}_history.png" alt="{} Elo History">
</div> </div>
<h2>Match History</h2> <h2>Competition History</h2>
<table> <table>
<tr> <tr>
<th>Date</th> <th>Date</th>
<th>Competition</th> <th>Competition</th>
<th>Opponent</th> <th>Placement</th>
<th>Result</th> <th>Elo Before</th>
<th>Elo After</th>
<th>Elo Change</th> <th>Elo Change</th>
</tr> </tr>
""".format(self.clean_filename(team_name), team_name) """.format(self.clean_filename(team_name), team_name)
# Add rows for each match # Add rows for each competition
for match in sorted(team_matches, key=lambda x: x['date'], reverse=True): for comp in team_competitions:
if match['team_a'] == team_name: elo_change = comp['elo_change']
opponent = match['team_b'] change_class = "positive" if elo_change > 0 else "negative" if elo_change < 0 else ""
old_elo = match['old_elo_a']
new_elo = match['new_elo_a']
result = "Win" if match['score_a'] > match['score_b'] else "Loss"
else:
opponent = match['team_a']
old_elo = match['old_elo_b']
new_elo = match['new_elo_b']
result = "Win" if match['score_b'] > match['score_a'] else "Loss"
elo_change = new_elo - old_elo
change_color = "green" if elo_change > 0 else "red"
html_content += f""" html_content += f"""
<tr> <tr>
<td>{match['date']}</td> <td>{comp['date']}</td>
<td>{match['competition']}</td> <td>{comp['competition']}</td>
<td><a href="team_{self.clean_filename(opponent)}.html">{opponent}</a></td> <td>{comp['rank']}</td>
<td>{result}</td> <td>{int(comp['previous_elo'])}</td>
<td style="color: {change_color}">{'+' if elo_change > 0 else ''}{elo_change:.1f}</td> <td>{int(comp['new_elo'])}</td>
<td class="{change_class}">{'+' if elo_change > 0 else ''}{elo_change:.1f}</td>
</tr>""" </tr>"""
html_content += """ html_content += """
...@@ -515,15 +539,15 @@ class EloSystem: ...@@ -515,15 +539,15 @@ class EloSystem:
team_history.sort(key=lambda x: x['date']) team_history.sort(key=lambda x: x['date'])
dates = [entry['date'] for entry in team_history] dates = [entry['date'] for entry in team_history]
elo_values = [entry['elo'] for entry in team_history] elo_values = [entry['new_elo'] for entry in team_history]
# Create line chart # Create line chart
plt.plot(range(len(dates)), elo_values, marker='o', linestyle='-', color='blue') plt.plot(range(len(dates)), elo_values, marker='o', linestyle='-', color='blue')
# Add competition labels # Add competition labels
for i, entry in enumerate(team_history): for i, entry in enumerate(team_history):
plt.annotate(entry['competition'], plt.annotate(entry['competition'] + f" (#{entry['rank']})",
(i, entry['elo']), (i, entry['new_elo']),
textcoords="offset points", textcoords="offset points",
xytext=(0, 10), xytext=(0, 10),
ha='center', ha='center',
...@@ -541,10 +565,6 @@ class EloSystem: ...@@ -541,10 +565,6 @@ class EloSystem:
dpi=100) dpi=100)
plt.close() plt.close()
def count_competitions(self):
"""Count the number of unique competitions"""
return len(set(match['competition'] for match in self.match_history))
def clean_filename(self, filename): def clean_filename(self, filename):
"""Clean a string to make it suitable for use as a filename""" """Clean a string to make it suitable for use as a filename"""
# Replace spaces and special characters # Replace spaces and special characters
...@@ -556,7 +576,7 @@ def main(): ...@@ -556,7 +576,7 @@ def main():
import argparse import argparse
parser = argparse.ArgumentParser(description='Process competition results and generate Elo rankings website') parser = argparse.ArgumentParser(description='Process competition results and generate Elo rankings website')
parser.add_argument('--input', default='data', help='Directory containing CSV result files') parser.add_argument('--input', default='csv_files', help='Directory containing CSV result files')
parser.add_argument('--output', default='elo_website', help='Output directory for the website') parser.add_argument('--output', default='elo_website', help='Output directory for the website')
args = parser.parse_args() args = parser.parse_args()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment