77
88import matplotlib .pyplot as plt
99import numpy as np
10+ from matplotlib .ticker import AutoMinorLocator
1011from scipy .optimize import minimize
1112from scipy .stats import kendalltau , spearmanr
1213from tqdm import tqdm
1314
1415from codeclash .analysis .metrics .elo import get_scores
1516from codeclash .analysis .significance import calculate_p_value
16- from codeclash .analysis .viz .utils import MODEL_TO_DISPLAY_NAME
17+ from codeclash .analysis .viz .utils import FONT_BOLD , MODEL_TO_DISPLAY_NAME
1718from codeclash .constants import LOCAL_LOG_DIR , RESULT_TIE
1819from codeclash .utils .log import add_file_handler , get_logger
1920
@@ -546,6 +547,9 @@ def create_elo_plots(self, output_dir: Path) -> None:
546547 all_indices = np .argsort (all_elos )[::- 1 ]
547548 player_order = [all_players [i ] for i in all_indices ]
548549
550+ # Translate to display names
551+ display_names = [MODEL_TO_DISPLAY_NAME .get (p , p ) for p in player_order ]
552+
549553 # Create mapping from player to y-position
550554 player_to_pos = {p : i for i , p in enumerate (player_order )}
551555
@@ -596,8 +600,8 @@ def create_elo_plots(self, output_dir: Path) -> None:
596600 zorder = 3 ,
597601 )
598602
599- ax .set_xlabel ("Elo Rating" , fontsize = 11 , fontweight = "bold" )
600- ax .set_title (game_name , fontsize = 14 , fontweight = "bold" )
603+ ax .set_xlabel ("Elo Rating" , fontproperties = FONT_BOLD , fontsize = 14 )
604+ ax .set_title (game_name , fontproperties = FONT_BOLD , fontsize = 16 )
601605 ax .grid (True , axis = "x" , alpha = 0.3 )
602606
603607 # Add value labels inside bars near x=0, include ±1σ when available
@@ -606,14 +610,14 @@ def create_elo_plots(self, output_dir: Path) -> None:
606610 label = f"{ elo :.0f} "
607611 if has_sigma and sig > 0 :
608612 label = f"{ elo :.0f} ± { sig :.0f} "
609- ax .text (20 , pos , label , va = "center" , ha = "left" , fontsize = 13 , fontweight = "bold" , color = "white" )
613+ ax .text (20 , pos , label , va = "center" , ha = "left" , fontproperties = FONT_BOLD , fontsize = 14 , color = "white" )
610614
611615 # Add reference line at ELO_BASE
612616 ax .axvline (ELO_BASE , color = "red" , linestyle = "--" , alpha = 0.5 , linewidth = 1 )
613617
614618 # Set y-axis labels on the first subplot
615619 axes [0 ].set_yticks (range (len (player_order )))
616- axes [0 ].set_yticklabels (player_order , fontsize = 13 )
620+ axes [0 ].set_yticklabels (display_names , fontproperties = FONT_BOLD , fontsize = 14 )
617621 axes [0 ].invert_yaxis ()
618622
619623 plt .tight_layout ()
@@ -690,10 +694,12 @@ def create_validation_plots(self, output_dir: Path, regularization: float = 0.01
690694 bbox = dict (boxstyle = "round" , facecolor = "wheat" , alpha = 0.8 ),
691695 )
692696
693- ax .set_xlabel ("BT Strength" , fontsize = 10 )
694- ax .set_ylabel ("Negative Log-Likelihood" , fontsize = 10 )
695- ax .set_title (f"{ player } " , fontsize = 11 , fontweight = "bold" )
696- ax .legend (fontsize = 8 , loc = "upper right" )
697+ ax .set_xlabel ("BT Strength" , fontproperties = FONT_BOLD , fontsize = 12 )
698+ ax .set_ylabel ("Negative Log-Likelihood" , fontproperties = FONT_BOLD , fontsize = 12 )
699+ display_name = MODEL_TO_DISPLAY_NAME .get (player , player )
700+ ax .set_title (display_name , fontproperties = FONT_BOLD , fontsize = 14 )
701+ legend = ax .legend (prop = FONT_BOLD , fontsize = 10 , loc = "upper right" )
702+ legend .set_frame_on (False )
697703 ax .grid (True , alpha = 0.3 )
698704
699705 # Hide unused subplots
@@ -768,20 +774,24 @@ def _create_rank_matrix_plot(
768774
769775 rank_matrix = (rank_matrix / self .n_bootstrap ) * 100
770776
771- fig , ax = plt .subplots (figsize = (max (10 , n * 0.8 ), max (8 , n * 0.6 )))
777+ # Translate player names to display names
778+ display_names = [MODEL_TO_DISPLAY_NAME .get (p , p ) for p in players ]
779+
780+ fig , ax = plt .subplots (figsize = (6 , 6 ))
772781 im = ax .imshow (rank_matrix , cmap = "YlOrRd" , aspect = "auto" , vmin = 0 , vmax = 100 )
773782
774783 ax .set_xticks (range (n ))
775- ax .set_xticklabels (players , rotation = 45 , ha = "right" , fontsize = 10 )
784+ ax .set_xticklabels (display_names , rotation = 45 , ha = "right" , fontproperties = FONT_BOLD , fontsize = 10 )
776785 ax .set_yticks (range (n ))
777- ax .set_yticklabels ([f"Rank { i + 1 } " for i in range (n )], fontsize = 10 )
786+ ax .set_yticklabels ([f"Rank { i + 1 } " for i in range (n )], fontproperties = FONT_BOLD , fontsize = 10 )
787+ ax .yaxis .set_minor_locator (AutoMinorLocator ())
778788
779- ax .set_xlabel ("Model" , fontsize = 12 , fontweight = "bold" )
780- ax .set_ylabel ("Rank" , fontsize = 12 , fontweight = "bold" )
789+ ax .set_xlabel ("Model" , fontproperties = FONT_BOLD , fontsize = 12 )
790+ ax .set_ylabel ("Rank" , fontproperties = FONT_BOLD , fontsize = 12 )
781791 ax .set_title (
782792 f"Rank Distribution ({ self .bootstrap_type } bootstrap, { self .n_bootstrap } samples)" ,
793+ fontproperties = FONT_BOLD ,
783794 fontsize = 14 ,
784- fontweight = "bold" ,
785795 )
786796
787797 for i in range (n ):
@@ -790,11 +800,18 @@ def _create_rank_matrix_plot(
790800 if value > 0 :
791801 text_color = "white" if value > 50 else "black"
792802 ax .text (
793- j , i , f"{ value :.1f} %" , ha = "center" , va = "center" , color = text_color , fontsize = 9 , fontweight = "bold"
803+ j ,
804+ i ,
805+ f"{ value :.1f} %" ,
806+ ha = "center" ,
807+ va = "center" ,
808+ color = text_color ,
809+ fontproperties = FONT_BOLD ,
810+ fontsize = 12 ,
794811 )
795812
796813 cbar = plt .colorbar (im , ax = ax )
797- cbar .set_label ("Percentage (%)" , fontsize = 11 , fontweight = "bold" )
814+ cbar .set_label ("Percentage (%)" , fontproperties = FONT_BOLD , fontsize = 14 )
798815
799816 plt .tight_layout ()
800817 self ._save_plot (output_dir , f"{ self .game } _rank_matrix_{ self .bootstrap_type } " )
@@ -806,7 +823,10 @@ def _create_elo_violin_plot(
806823 """Create a violin plot showing the distribution of Elo scores for each model."""
807824 elo_data = [elo_samples [p ] for p in players ]
808825
809- fig , ax = plt .subplots (figsize = (max (10 , len (players ) * 0.8 ), 8 ))
826+ # Translate player names to display names
827+ display_names = [MODEL_TO_DISPLAY_NAME .get (p , p ) for p in players ]
828+
829+ fig , ax = plt .subplots (figsize = (6 , 6 ))
810830
811831 parts = ax .violinplot (elo_data , positions = range (len (players )), showmeans = False , showmedians = False , widths = 0.7 )
812832
@@ -835,15 +855,17 @@ def _create_elo_violin_plot(
835855 )
836856
837857 ax .set_xticks (range (len (players )))
838- ax .set_xticklabels (players , rotation = 45 , ha = "right" , fontsize = 10 )
839- ax .set_ylabel ("Elo Rating" , fontsize = 12 , fontweight = "bold" )
858+ ax .set_xticklabels (display_names , rotation = 45 , ha = "right" , fontproperties = FONT_BOLD , fontsize = 12 )
859+ ax .set_ylabel ("Elo Rating" , fontproperties = FONT_BOLD , fontsize = 14 )
860+ ax .yaxis .set_minor_locator (AutoMinorLocator ())
840861 ax .set_title (
841862 f"Elo Distribution ({ self .bootstrap_type } bootstrap, { self .n_bootstrap } samples)" ,
842- fontsize = 14 ,
843- fontweight = "bold" ,
863+ fontproperties = FONT_BOLD ,
864+ fontsize = 16 ,
844865 )
845866 ax .grid (True , axis = "y" , alpha = 0.3 )
846- ax .legend (fontsize = 10 )
867+ legend = ax .legend (prop = FONT_BOLD , fontsize = 12 )
868+ legend .set_frame_on (False )
847869
848870 plt .tight_layout ()
849871 self ._save_plot (output_dir , f"{ self .game } _elo_violin_{ self .bootstrap_type } " )
@@ -1062,17 +1084,20 @@ def _plot_results(self, results_by_max_round: dict[int, dict[str, dict[str, floa
10621084 elos_list .append (results_by_max_round [max_round ][game_name ][player ])
10631085
10641086 if max_rounds_list :
1065- ax .plot (max_rounds_list , elos_list , marker = "o" , label = player , linewidth = 2 , markersize = 6 )
1087+ display_name = MODEL_TO_DISPLAY_NAME .get (player , player )
1088+ ax .plot (max_rounds_list , elos_list , marker = "o" , label = display_name , linewidth = 2 , markersize = 6 )
10661089
1067- ax .set_xlabel ("Max Round" , fontsize = 12 , fontweight = "bold" )
1068- ax .set_ylabel ("Elo Rating" , fontsize = 12 , fontweight = "bold" )
1069- ax .set_title (f"Elo vs Max Rounds: { game_name } " , fontsize = 14 , fontweight = "bold" )
1090+ ax .set_xlabel ("Max Round" , fontproperties = FONT_BOLD , fontsize = 14 )
1091+ ax .set_ylabel ("Elo Rating" , fontproperties = FONT_BOLD , fontsize = 14 )
1092+ ax .set_title (f"Elo vs Max Rounds: { game_name } " , fontproperties = FONT_BOLD , fontsize = 16 )
10701093 ax .grid (True , alpha = 0.3 )
1094+ ax .yaxis .set_minor_locator (AutoMinorLocator ())
10711095
10721096 # Add reference line at ELO_BASE
10731097 ax .axhline (ELO_BASE , color = "red" , linestyle = "--" , alpha = 0.5 , linewidth = 1 , label = f"Base Elo ({ ELO_BASE } )" )
10741098
1075- ax .legend (fontsize = 10 , loc = "best" )
1099+ legend = ax .legend (prop = FONT_BOLD , fontsize = 12 , loc = "best" )
1100+ legend .set_frame_on (False )
10761101
10771102 plt .tight_layout ()
10781103 safe_game_name = game_name .replace ("/" , "_" ).replace (" " , "_" )
@@ -1176,17 +1201,20 @@ def _plot_results(self, results_by_round: dict[int, dict[str, dict[str, float]]]
11761201 elos_list .append (results_by_round [round_num ][game_name ][player ])
11771202
11781203 if rounds_list :
1179- ax .plot (rounds_list , elos_list , marker = "o" , label = player , linewidth = 2 , markersize = 6 )
1204+ display_name = MODEL_TO_DISPLAY_NAME .get (player , player )
1205+ ax .plot (rounds_list , elos_list , marker = "o" , label = display_name , linewidth = 2 , markersize = 6 )
11801206
1181- ax .set_xlabel ("Round" , fontsize = 12 , fontweight = "bold" )
1182- ax .set_ylabel ("Elo Rating" , fontsize = 12 , fontweight = "bold" )
1183- ax .set_title (f"Elo at Specific Round: { game_name } " , fontsize = 14 , fontweight = "bold" )
1207+ ax .set_xlabel ("Round" , fontproperties = FONT_BOLD , fontsize = 14 )
1208+ ax .set_ylabel ("Elo Rating" , fontproperties = FONT_BOLD , fontsize = 14 )
1209+ ax .set_title (f"Elo at Specific Round: { game_name } " , fontproperties = FONT_BOLD , fontsize = 16 )
11841210 ax .grid (True , alpha = 0.3 )
1211+ ax .yaxis .set_minor_locator (AutoMinorLocator ())
11851212
11861213 # Add reference line at ELO_BASE
11871214 ax .axhline (ELO_BASE , color = "red" , linestyle = "--" , alpha = 0.5 , linewidth = 1 , label = f"Base Elo ({ ELO_BASE } )" )
11881215
1189- ax .legend (fontsize = 10 , loc = "best" )
1216+ legend = ax .legend (prop = FONT_BOLD , fontsize = 12 , loc = "best" )
1217+ legend .set_frame_on (False )
11901218
11911219 plt .tight_layout ()
11921220 safe_game_name = game_name .replace ("/" , "_" ).replace (" " , "_" )
0 commit comments