Skip to content
Snippets Groups Projects
Commit 8852492a authored by maeries's avatar maeries
Browse files

added world ranking info to team page

parent 7e8ebf15
No related branches found
No related tags found
No related merge requests found
...@@ -77,7 +77,7 @@ class EloSystem: ...@@ -77,7 +77,7 @@ class EloSystem:
def get_competition_date(self, competition_id): def get_competition_date(self, competition_id):
date_string = self.competition_meta_data[self.competition_meta_data["id"] == int(competition_id)]['date'].values[0] date_string = self.competition_meta_data[self.competition_meta_data["id"] == int(competition_id)]['date'].values[0]
return datetime.strptime(date_string, "%Y-%m-%d") return datetime.strptime(date_string, "%Y-%m-%d")
def get_competition_type(self, competition_id): def get_competition_type(self, competition_id):
return self.competition_meta_data[self.competition_meta_data["id"] == int(competition_id)]['kind'].values[0].strip() return self.competition_meta_data[self.competition_meta_data["id"] == int(competition_id)]['kind'].values[0].strip()
...@@ -155,6 +155,9 @@ class EloSystem: ...@@ -155,6 +155,9 @@ class EloSystem:
# For each team, compare with teams ranked below them # For each team, compare with teams ranked below them
date = self.get_competition_date(competition_id) # Use current date as competition date date = self.get_competition_date(competition_id) # Use current date as competition date
old_world_ranking = sorted(self.teams.items(), key=lambda x: x[1]['elo'], reverse=True)
old_world_ranking = tuple(name for name, _ in old_world_ranking)
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]
...@@ -165,29 +168,41 @@ class EloSystem: ...@@ -165,29 +168,41 @@ class EloSystem:
# Store post-competition Elo ratings and changes # Store post-competition Elo ratings and changes
for team in teams_in_order: for team in teams_in_order:
rank = teams_in_order.index(team) + 1 placement = teams_in_order.index(team) + 1
previous_elo = self.teams[team]['elo'] previous_elo = self.teams[team]['elo']
elo_change = self.teams[team]['delta_elo'] elo_change = self.teams[team]['delta_elo']
old_rank = old_world_ranking.index(team) + 1
new_rank = 0
# Store in team history # Store in team history
self.teams[team]['history'].append({ self.teams[team]['history'].append({
'date': date.strftime("%Y-%m-%d"), 'date': date.strftime("%Y-%m-%d"),
'competition': self.get_competition_name(competition_id), 'competition': self.get_competition_name(competition_id),
'competition_id': competition_id, 'competition_id': competition_id,
'rank': rank, 'placement': placement,
'participants': len(teams_in_order), 'participants': len(teams_in_order),
'previous_elo': previous_elo, 'previous_elo': previous_elo,
'new_elo': self.teams[team]['elo'] + self.teams[team]['delta_elo'], 'new_elo': self.teams[team]['elo'] + self.teams[team]['delta_elo'],
'elo_change': elo_change 'elo_change': elo_change,
'old_rank': old_rank,
'new_rank': new_rank,
'rank_change': new_rank - old_rank
}) })
# Store in competition history # Store in competition history
self.competition_history[competition_id]['results'][rank-1][2] = previous_elo self.competition_history[competition_id]['results'][placement-1][2] = previous_elo
self.competition_history[competition_id]['results'][rank-1][3] = elo_change self.competition_history[competition_id]['results'][placement-1][3] = elo_change
self.teams[team]['elo'] = self.teams[team]['elo'] + self.teams[team]['delta_elo'] self.teams[team]['elo'] = self.teams[team]['elo'] + self.teams[team]['delta_elo']
self.teams[team]['delta_elo'] = 0 self.teams[team]['delta_elo'] = 0
for team in teams_in_order:
new_world_ranking = sorted(self.teams.items(), key=lambda x: x[1]['elo'], reverse=True)
new_world_ranking = tuple(name for name, _ in new_world_ranking)
new_rank = new_world_ranking.index(team) + 1
self.teams[team]['history'][-1]['new_rank'] = new_rank
self.teams[team]['history'][-1]['rank_change'] = new_rank - self.teams[team]['history'][-1]['old_rank']
def update_elo_pair(self, team_a, team_b, score_a, score_b, competition_id, date): def update_elo_pair(self, team_a, team_b, score_a, score_b, competition_id, 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
...@@ -306,36 +321,36 @@ class EloSystem: ...@@ -306,36 +321,36 @@ class EloSystem:
for i, bar in enumerate(bars): for i, bar in enumerate(bars):
plt.text(bar.get_width() + 5, bar.get_y() + bar.get_height() / 2, plt.text(bar.get_width() + 5, bar.get_y() + bar.get_height() / 2,
f"{int(elo_ratings[i])}", va='center') f"{int(elo_ratings[i])}", va='center')
# Create custom colormap # Create custom colormap
colors = [hex_to_normalized_rgb(self.LINK_COLOR), hex_to_normalized_rgb(self.BORDER_COLOR)] # RGB values for #ffff1e and #ffc400 colors = [hex_to_normalized_rgb(self.LINK_COLOR), hex_to_normalized_rgb(self.BORDER_COLOR)] # RGB values for #ffff1e and #ffc400
custom_yellow_cmap = LinearSegmentedColormap.from_list('custom_yellow', colors) custom_yellow_cmap = LinearSegmentedColormap.from_list('custom_yellow', colors)
for bar in bars: for bar in bars:
# Get the coordinates of the bar # Get the coordinates of the bar
x0, y0 = bar.get_xy() x0, y0 = bar.get_xy()
width = bar.get_width() width = bar.get_width()
height = bar.get_height() height = bar.get_height()
# Create a gradient for the bar # Create a gradient for the bar
gradient = np.linspace(0, 1, 100).reshape(1, -1) gradient = np.linspace(0, 1, 100).reshape(1, -1)
# Get colors from the colormap # Get colors from the colormap
colors = custom_yellow_cmap(gradient) colors = custom_yellow_cmap(gradient)
# Set the bar's face color to the gradient # Set the bar's face color to the gradient
bar.set_facecolor('none') # Remove default color bar.set_facecolor('none') # Remove default color
# Add the gradient rectangle # Add the gradient rectangle
gradient_rect = patches.Rectangle((x0, y0), width, height, gradient_rect = patches.Rectangle((x0, y0), width, height,
linewidth=0, linewidth=0,
fill=True, fill=True,
facecolor=custom_yellow_cmap(0.5)) facecolor=custom_yellow_cmap(0.5))
# To create a gradient, add an axial gradient transform # To create a gradient, add an axial gradient transform
gradient_rect.set_facecolor('none') gradient_rect.set_facecolor('none')
ax.add_patch(gradient_rect) ax.add_patch(gradient_rect)
# Create multiple thin rectangles to simulate a gradient # Create multiple thin rectangles to simulate a gradient
steps = 50 steps = 50
for i in range(steps): for i in range(steps):
...@@ -343,8 +358,8 @@ class EloSystem: ...@@ -343,8 +358,8 @@ class EloSystem:
rect_width = width/steps rect_width = width/steps
color = custom_yellow_cmap(i/steps) color = custom_yellow_cmap(i/steps)
rect = patches.Rectangle((left, y0), rect_width, height, rect = patches.Rectangle((left, y0), rect_width, height,
linewidth=0, linewidth=0,
color=color) color=color)
ax.add_patch(rect) ax.add_patch(rect)
plt.xlabel('Elo Rating') plt.xlabel('Elo Rating')
...@@ -368,7 +383,7 @@ class EloSystem: ...@@ -368,7 +383,7 @@ class EloSystem:
# Create histogram # Create histogram
counts, bin_edges, _ = plt.hist(elo_ratings, bins=20, alpha=0) counts, bin_edges, _ = plt.hist(elo_ratings, bins=20, alpha=0)
# Draw bars with gradients # Draw bars with gradients
bin_width = bin_edges[1] - bin_edges[0] bin_width = bin_edges[1] - bin_edges[0]
for i in range(len(counts)): for i in range(len(counts)):
...@@ -377,7 +392,7 @@ class EloSystem: ...@@ -377,7 +392,7 @@ class EloSystem:
bottom = 0 bottom = 0
width = bin_width width = bin_width
height = counts[i] height = counts[i]
# Create the gradient effect by stacking multiple thin rectangles # Create the gradient effect by stacking multiple thin rectangles
gradient_steps = 50 gradient_steps = 50
for step in range(gradient_steps): for step in range(gradient_steps):
...@@ -387,10 +402,10 @@ class EloSystem: ...@@ -387,10 +402,10 @@ class EloSystem:
# Calculate height of this piece of the gradient # Calculate height of this piece of the gradient
rect_bottom = bottom + (step / gradient_steps) * height rect_bottom = bottom + (step / gradient_steps) * height
rect_height = height / gradient_steps rect_height = height / gradient_steps
# Get color from our custom colormap # Get color from our custom colormap
color = custom_yellow_cmap(step / gradient_steps) color = custom_yellow_cmap(step / gradient_steps)
# Add the rectangle patch # Add the rectangle patch
rect = patches.Rectangle( rect = patches.Rectangle(
(rect_left, rect_bottom), (rect_left, rect_bottom),
...@@ -401,7 +416,7 @@ class EloSystem: ...@@ -401,7 +416,7 @@ class EloSystem:
edgecolor=None edgecolor=None
) )
plt.gca().add_patch(rect) plt.gca().add_patch(rect)
# Add black edges to each bar # Add black edges to each bar
for i in range(len(counts)): for i in range(len(counts)):
left = bin_edges[i] left = bin_edges[i]
...@@ -416,7 +431,7 @@ class EloSystem: ...@@ -416,7 +431,7 @@ class EloSystem:
linewidth=1 linewidth=1
) )
plt.gca().add_patch(rect) plt.gca().add_patch(rect)
# Set axis limits to make sure the entire histogram is visible # Set axis limits to make sure the entire histogram is visible
plt.xlim(bin_edges[0], bin_edges[-1]) plt.xlim(bin_edges[0], bin_edges[-1])
plt.ylim(0, max(counts) * 1.1) plt.ylim(0, max(counts) * 1.1)
...@@ -448,7 +463,7 @@ class EloSystem: ...@@ -448,7 +463,7 @@ class EloSystem:
# Add competition labels # Add competition labels
for i, entry in enumerate(team_history): for i, entry in enumerate(team_history):
plt.annotate(entry['competition'] + f" (#{entry['rank']})", plt.annotate(entry['competition'] + f" (#{entry['placement']})",
(i, entry['new_elo']), (i, entry['new_elo']),
textcoords="offset points", textcoords="offset points",
xytext=(0, 10), xytext=(0, 10),
......
...@@ -149,8 +149,8 @@ def get_team_page_html(self, team_name, team_data, team_competitions): ...@@ -149,8 +149,8 @@ def get_team_page_html(self, team_name, team_data, team_competitions):
# Calculate average ranking if available # Calculate average ranking if available
if team_competitions: if team_competitions:
avg_rank = sum(comp['rank'] for comp in team_competitions) / len(team_competitions) avg_rank = sum(comp['placement'] for comp in team_competitions) / len(team_competitions)
best_rank = min(comp['rank'] for comp in team_competitions) best_rank = min(comp['placement'] for comp in team_competitions)
html_content += f""" html_content += f"""
<div class="stat-box"> <div class="stat-box">
...@@ -175,8 +175,11 @@ def get_team_page_html(self, team_name, team_data, team_competitions): ...@@ -175,8 +175,11 @@ def get_team_page_html(self, team_name, team_data, team_competitions):
<table> <table>
<tr> <tr>
<th>Date</th> <th>Date</th>
<th>Competition</th> <th>Comp</th>
<th>Placement</th> <th>Placement</th>
<th>Rank Before</th>
<th>Rank After</th>
<th>Rank Change</th>
<th>Elo Before</th> <th>Elo Before</th>
<th>Elo After</th> <th>Elo After</th>
<th>Elo Change</th> <th>Elo Change</th>
...@@ -186,16 +189,21 @@ def get_team_page_html(self, team_name, team_data, team_competitions): ...@@ -186,16 +189,21 @@ def get_team_page_html(self, team_name, team_data, team_competitions):
# Add rows for each competition # Add rows for each competition
for comp in team_competitions: for comp in team_competitions:
elo_change = comp['elo_change'] elo_change = comp['elo_change']
change_class = "positive" if elo_change > 0 else "negative" if elo_change < 0 else "" elo_change_class = "positive" if elo_change > 0 else "negative" if elo_change < 0 else ""
rank_change = comp['rank_change']
rank_change_class = "positive" if rank_change < 0 else "negative" if rank_change > 0 else ""
html_content += f""" html_content += f"""
<tr> <tr>
<td>{comp['date']}</td> <td>{comp['date']}</td>
<td><a href=../comp/{comp['competition_id']}.html>{comp['competition']}</a></td> <td><a href=../comp/{comp['competition_id']}.html>{comp['competition']}</a></td>
<td>{comp['rank']} / {comp['participants']}</td> <td>{comp['placement']} / {comp['participants']}</td>
<td>{comp['old_rank']}</td>
<td>{comp['new_rank']}</td>
<td class="{rank_change_class}">{'+' if rank_change > 0 else ''}{comp['rank_change']}</td>
<td>{int(comp['previous_elo'])}</td> <td>{int(comp['previous_elo'])}</td>
<td>{int(comp['new_elo'])}</td> <td>{int(comp['new_elo'])}</td>
<td class="{change_class}">{'+' if elo_change > 0 else ''}{elo_change:.1f}</td> <td class="{elo_change_class}">{'+' if elo_change > 0 else ''}{elo_change:.1f}</td>
</tr>""" </tr>"""
html_content += """ html_content += """
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment