Spaces:
Running
Running
Yuxuan-Zhang-Dexter
commited on
Commit
·
c998efb
1
Parent(s):
68f8427
update bar chart
Browse files- app.py +160 -7
- data_visualization.py +23 -5
app.py
CHANGED
@@ -118,17 +118,41 @@ def prepare_dataframe_for_display(df, for_game=None):
|
|
118 |
# Filter out models that didn't participate
|
119 |
display_df = display_df[~display_df[score_col].isna()]
|
120 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
return display_df
|
122 |
|
123 |
# Helper function to ensure leaderboard updates maintain consistent height
|
124 |
def update_df_with_height(df):
|
125 |
"""Update DataFrame with consistent height parameter."""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
return gr.update(value=df,
|
127 |
show_row_numbers=True,
|
128 |
show_fullscreen_button=True,
|
129 |
-
|
130 |
-
|
131 |
-
|
|
|
132 |
|
133 |
def update_leaderboard(mario_overall, mario_details,
|
134 |
sokoban_overall, sokoban_details,
|
@@ -472,6 +496,32 @@ def create_timeline_slider():
|
|
472 |
|
473 |
def build_app():
|
474 |
with gr.Blocks(css="""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
475 |
.visualization-container .js-plotly-plot {
|
476 |
margin-left: auto !important;
|
477 |
margin-right: auto !important;
|
@@ -595,6 +645,53 @@ def build_app():
|
|
595 |
width: 100%;
|
596 |
border-collapse: separate;
|
597 |
border-spacing: 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
598 |
}
|
599 |
|
600 |
/* Make headers sticky */
|
@@ -604,13 +701,19 @@ def build_app():
|
|
604 |
background-color: #f8f9fa !important;
|
605 |
z-index: 10 !important;
|
606 |
font-weight: bold;
|
607 |
-
padding:
|
608 |
border-bottom: 2px solid #e9ecef;
|
|
|
|
|
|
|
|
|
|
|
|
|
609 |
}
|
610 |
|
611 |
/* Simple cell styling */
|
612 |
.table-container td {
|
613 |
-
padding:
|
614 |
border-bottom: 1px solid #e9ecef;
|
615 |
}
|
616 |
|
@@ -630,6 +733,41 @@ def build_app():
|
|
630 |
overflow: visible !important;
|
631 |
margin-bottom: 20px;
|
632 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
633 |
""") as demo:
|
634 |
gr.Markdown("# 🎮 Game Arena: Gaming Agent 🎲")
|
635 |
|
@@ -719,6 +857,14 @@ def build_app():
|
|
719 |
# Format the DataFrame for display
|
720 |
initial_display_df = prepare_dataframe_for_display(initial_df)
|
721 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
722 |
# Create a standard DataFrame component with enhanced styling
|
723 |
with gr.Row():
|
724 |
leaderboard_df = gr.DataFrame(
|
@@ -731,7 +877,8 @@ def build_app():
|
|
731 |
show_fullscreen_button=True,
|
732 |
line_breaks=True,
|
733 |
max_height=700,
|
734 |
-
show_search="search"
|
|
|
735 |
)
|
736 |
|
737 |
# Add the score note below the table
|
@@ -815,4 +962,10 @@ def build_app():
|
|
815 |
if __name__ == "__main__":
|
816 |
demo_app = build_app()
|
817 |
# Add file serving configuration
|
818 |
-
demo_app.launch(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
118 |
# Filter out models that didn't participate
|
119 |
display_df = display_df[~display_df[score_col].isna()]
|
120 |
|
121 |
+
# Add line breaks to column headers
|
122 |
+
new_columns = {}
|
123 |
+
for col in display_df.columns:
|
124 |
+
if col.endswith(' Score'):
|
125 |
+
# Replace 'Game Name Score' with 'Game Name\nScore'
|
126 |
+
game_name = col.replace(' Score', '')
|
127 |
+
new_col = f"{game_name}\nScore"
|
128 |
+
new_columns[col] = new_col
|
129 |
+
elif col == 'Organization':
|
130 |
+
new_columns[col] = 'Organi-\nzation'
|
131 |
+
|
132 |
+
# Rename columns with new line breaks
|
133 |
+
if new_columns:
|
134 |
+
display_df = display_df.rename(columns=new_columns)
|
135 |
+
|
136 |
return display_df
|
137 |
|
138 |
# Helper function to ensure leaderboard updates maintain consistent height
|
139 |
def update_df_with_height(df):
|
140 |
"""Update DataFrame with consistent height parameter."""
|
141 |
+
# Create column widths array
|
142 |
+
col_widths = ["40px"] # Row number column width
|
143 |
+
col_widths.append("230px") # Player column - reduced by 20px
|
144 |
+
col_widths.append("120px") # Organization column
|
145 |
+
# Add game score columns
|
146 |
+
for _ in range(len(df.columns) - 2):
|
147 |
+
col_widths.append("120px")
|
148 |
+
|
149 |
return gr.update(value=df,
|
150 |
show_row_numbers=True,
|
151 |
show_fullscreen_button=True,
|
152 |
+
line_breaks=True,
|
153 |
+
show_search="search",
|
154 |
+
max_height=700,
|
155 |
+
column_widths=col_widths)
|
156 |
|
157 |
def update_leaderboard(mario_overall, mario_details,
|
158 |
sokoban_overall, sokoban_details,
|
|
|
496 |
|
497 |
def build_app():
|
498 |
with gr.Blocks(css="""
|
499 |
+
/* Fix for disappearing scrollbar */
|
500 |
+
html, body {
|
501 |
+
overflow-y: scroll !important;
|
502 |
+
height: 100% !important;
|
503 |
+
min-height: 100vh !important;
|
504 |
+
}
|
505 |
+
|
506 |
+
/* Prevent content from shrinking to center */
|
507 |
+
.gradio-container {
|
508 |
+
width: 100% !important;
|
509 |
+
max-width: 1200px !important;
|
510 |
+
margin-left: auto !important;
|
511 |
+
margin-right: auto !important;
|
512 |
+
min-height: 100vh !important;
|
513 |
+
}
|
514 |
+
|
515 |
+
/* Force table to maintain width */
|
516 |
+
.table-container {
|
517 |
+
width: 100% !important;
|
518 |
+
min-width: 100% !important;
|
519 |
+
}
|
520 |
+
|
521 |
+
.table-container table {
|
522 |
+
width: 100% !important;
|
523 |
+
}
|
524 |
+
|
525 |
.visualization-container .js-plotly-plot {
|
526 |
margin-left: auto !important;
|
527 |
margin-right: auto !important;
|
|
|
645 |
width: 100%;
|
646 |
border-collapse: separate;
|
647 |
border-spacing: 0;
|
648 |
+
table-layout: fixed !important;
|
649 |
+
}
|
650 |
+
|
651 |
+
/* Targeting row number column directly */
|
652 |
+
table th[role="cell"][aria-colindex="1"],
|
653 |
+
table td[role="cell"][aria-colindex="1"],
|
654 |
+
table col[data-col-index="0"],
|
655 |
+
.table-container tr > *:first-child[aria-colindex="1"],
|
656 |
+
th[scope="row"],
|
657 |
+
th[aria-sort],
|
658 |
+
td[data-index],
|
659 |
+
th[data-row-header] {
|
660 |
+
width: 30px !important;
|
661 |
+
min-width: 30px !important;
|
662 |
+
max-width: 30px !important;
|
663 |
+
padding: 2px 4px !important;
|
664 |
+
font-size: 0.85em !important;
|
665 |
+
text-align: center !important;
|
666 |
+
overflow: hidden !important;
|
667 |
+
text-overflow: ellipsis !important;
|
668 |
+
white-space: nowrap !important;
|
669 |
+
}
|
670 |
+
|
671 |
+
/* Column width customization - adjust for row numbers being first column */
|
672 |
+
.table-container th:nth-child(2),
|
673 |
+
.table-container td:nth-child(2) {
|
674 |
+
width: 230px !important;
|
675 |
+
min-width: 200px !important;
|
676 |
+
max-width: 280px !important;
|
677 |
+
padding-left: 8px !important;
|
678 |
+
padding-right: 8px !important;
|
679 |
+
}
|
680 |
+
|
681 |
+
.table-container th:nth-child(3),
|
682 |
+
.table-container td:nth-child(3) {
|
683 |
+
width: 120px !important;
|
684 |
+
min-width: 100px !important;
|
685 |
+
max-width: 140px !important;
|
686 |
+
}
|
687 |
+
|
688 |
+
/* Game score columns */
|
689 |
+
.table-container th:nth-child(n+4),
|
690 |
+
.table-container td:nth-child(n+4) {
|
691 |
+
width: 120px !important;
|
692 |
+
min-width: 100px !important;
|
693 |
+
max-width: 140px !important;
|
694 |
+
text-align: center !important;
|
695 |
}
|
696 |
|
697 |
/* Make headers sticky */
|
|
|
701 |
background-color: #f8f9fa !important;
|
702 |
z-index: 10 !important;
|
703 |
font-weight: bold;
|
704 |
+
padding: 16px 10px !important;
|
705 |
border-bottom: 2px solid #e9ecef;
|
706 |
+
white-space: pre-wrap !important;
|
707 |
+
word-wrap: break-word !important;
|
708 |
+
line-height: 1.2 !important;
|
709 |
+
height: auto !important;
|
710 |
+
min-height: 60px !important;
|
711 |
+
vertical-align: middle !important;
|
712 |
}
|
713 |
|
714 |
/* Simple cell styling */
|
715 |
.table-container td {
|
716 |
+
padding: 8px 8px;
|
717 |
border-bottom: 1px solid #e9ecef;
|
718 |
}
|
719 |
|
|
|
733 |
overflow: visible !important;
|
734 |
margin-bottom: 20px;
|
735 |
}
|
736 |
+
|
737 |
+
/* Additional specific selectors for row numbers */
|
738 |
+
.gradio-dataframe thead tr th[id="0"],
|
739 |
+
.gradio-dataframe tbody tr td:nth-child(1),
|
740 |
+
[data-testid="dataframe"] thead tr th[id="0"],
|
741 |
+
[data-testid="dataframe"] tbody tr td:nth-child(1),
|
742 |
+
.svelte-1gfkn6j thead tr th:first-child,
|
743 |
+
.svelte-1gfkn6j tbody tr td:first-child {
|
744 |
+
width: 40px !important;
|
745 |
+
min-width: 40px !important;
|
746 |
+
max-width: 40px !important;
|
747 |
+
padding: 4px !important;
|
748 |
+
text-align: center !important;
|
749 |
+
font-size: 0.85em !important;
|
750 |
+
}
|
751 |
+
|
752 |
+
/* Fix overflow issues */
|
753 |
+
.table-container {
|
754 |
+
overflow: auto !important;
|
755 |
+
max-height: 700px !important;
|
756 |
+
}
|
757 |
+
|
758 |
+
body, html {
|
759 |
+
overflow-x: hidden !important;
|
760 |
+
overflow-y: auto !important;
|
761 |
+
height: 100% !important;
|
762 |
+
width: 100% !important;
|
763 |
+
margin: 0 !important;
|
764 |
+
padding: 0 !important;
|
765 |
+
}
|
766 |
+
|
767 |
+
.gradio-container {
|
768 |
+
overflow: visible !important;
|
769 |
+
max-height: none !important;
|
770 |
+
}
|
771 |
""") as demo:
|
772 |
gr.Markdown("# 🎮 Game Arena: Gaming Agent 🎲")
|
773 |
|
|
|
857 |
# Format the DataFrame for display
|
858 |
initial_display_df = prepare_dataframe_for_display(initial_df)
|
859 |
|
860 |
+
# Custom column widths including row numbers
|
861 |
+
col_widths = ["40px"] # Row number column width
|
862 |
+
col_widths.append("230px") # Player column - reduced by 20px
|
863 |
+
col_widths.append("120px") # Organization column
|
864 |
+
# Add game score columns
|
865 |
+
for _ in range(len(initial_display_df.columns) - 2):
|
866 |
+
col_widths.append("120px")
|
867 |
+
|
868 |
# Create a standard DataFrame component with enhanced styling
|
869 |
with gr.Row():
|
870 |
leaderboard_df = gr.DataFrame(
|
|
|
877 |
show_fullscreen_button=True,
|
878 |
line_breaks=True,
|
879 |
max_height=700,
|
880 |
+
show_search="search",
|
881 |
+
column_widths=col_widths
|
882 |
)
|
883 |
|
884 |
# Add the score note below the table
|
|
|
962 |
if __name__ == "__main__":
|
963 |
demo_app = build_app()
|
964 |
# Add file serving configuration
|
965 |
+
demo_app.launch(
|
966 |
+
debug=True,
|
967 |
+
show_error=True,
|
968 |
+
share=True,
|
969 |
+
height="100%",
|
970 |
+
width="100%"
|
971 |
+
)
|
data_visualization.py
CHANGED
@@ -203,7 +203,21 @@ def create_group_bar_chart(df):
|
|
203 |
|
204 |
# Build consistent game order (X-axis)
|
205 |
sorted_games = [game for game in GAME_ORDER if f"norm_{game} Score" in df.columns]
|
206 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
207 |
# Group models by prefix, then sort alphabetically
|
208 |
model_groups = {}
|
209 |
for player in df["Player"].unique():
|
@@ -233,13 +247,13 @@ def create_group_bar_chart(df):
|
|
233 |
|
234 |
if not has_data:
|
235 |
continue
|
236 |
-
|
237 |
fig.add_trace(go.Bar(
|
238 |
name=simplify_model_name(player),
|
239 |
-
x=sorted_games,
|
240 |
y=y_vals,
|
241 |
marker_color=MODEL_COLORS.get(player, '#808080'),
|
242 |
-
hovertemplate="
|
243 |
))
|
244 |
|
245 |
fig.update_layout(
|
@@ -252,9 +266,13 @@ def create_group_bar_chart(df):
|
|
252 |
yaxis_title="Normalized Score",
|
253 |
xaxis=dict(
|
254 |
categoryorder='array',
|
255 |
-
categoryarray=sorted_games
|
|
|
256 |
),
|
257 |
barmode='group',
|
|
|
|
|
|
|
258 |
legend=dict(
|
259 |
font=dict(size=9),
|
260 |
itemsizing='trace',
|
|
|
203 |
|
204 |
# Build consistent game order (X-axis)
|
205 |
sorted_games = [game for game in GAME_ORDER if f"norm_{game} Score" in df.columns]
|
206 |
+
|
207 |
+
# Format game names with line breaks
|
208 |
+
formatted_games = []
|
209 |
+
for game in sorted_games:
|
210 |
+
if len(game) > 10 and ' ' in game:
|
211 |
+
parts = game.split(' ')
|
212 |
+
midpoint = len(parts) // 2
|
213 |
+
formatted_name = ' '.join(parts[:midpoint]) + '<br>' + ' '.join(parts[midpoint:])
|
214 |
+
formatted_games.append(formatted_name)
|
215 |
+
else:
|
216 |
+
formatted_games.append(game)
|
217 |
+
|
218 |
+
# Create mapping from original to formatted names
|
219 |
+
game_display_map = dict(zip(sorted_games, formatted_games))
|
220 |
+
|
221 |
# Group models by prefix, then sort alphabetically
|
222 |
model_groups = {}
|
223 |
for player in df["Player"].unique():
|
|
|
247 |
|
248 |
if not has_data:
|
249 |
continue
|
250 |
+
|
251 |
fig.add_trace(go.Bar(
|
252 |
name=simplify_model_name(player),
|
253 |
+
x=[game_display_map[game] for game in sorted_games],
|
254 |
y=y_vals,
|
255 |
marker_color=MODEL_COLORS.get(player, '#808080'),
|
256 |
+
hovertemplate="<b>%{fullData.name}</b><br>Score: %{y:.1f}<extra></extra>"
|
257 |
))
|
258 |
|
259 |
fig.update_layout(
|
|
|
266 |
yaxis_title="Normalized Score",
|
267 |
xaxis=dict(
|
268 |
categoryorder='array',
|
269 |
+
categoryarray=[game_display_map[g] for g in sorted_games],
|
270 |
+
tickangle=0 # Keep text horizontal since we're using line breaks
|
271 |
),
|
272 |
barmode='group',
|
273 |
+
bargap=0.2, # Gap between game categories
|
274 |
+
bargroupgap=0.05, # Gap between bars in a group
|
275 |
+
uniformtext=dict(mode='hide', minsize=8), # Hide text that doesn't fit
|
276 |
legend=dict(
|
277 |
font=dict(size=9),
|
278 |
itemsizing='trace',
|