leaderboard / custom-select-columns.py
Aaron Mueller
updated filtering, add F= tab
1d8e193
import gradio as gr
import pandas as pd
from typing import List, Dict, Union, Optional
class SmartSelectColumns(gr.SelectColumns):
"""
Enhanced SelectColumns component that supports substring matching and column mapping.
Inherits from gr.SelectColumns but adds additional filtering capabilities.
"""
def __init__(
self,
*args,
column_filters: Optional[Dict[str, List[str]]] = None,
column_mapping: Optional[Dict[str, str]] = None,
**kwargs
):
"""
Initialize the SmartSelectColumns component.
Args:
column_filters: Dict mapping filter names to lists of substrings to match
column_mapping: Dict mapping display names to actual column names
*args, **kwargs: Arguments passed to parent SelectColumns
"""
super().__init__(*args, **kwargs)
self.column_filters = column_filters or {}
self.column_mapping = column_mapping or {}
def preprocess(self, x: List[str]) -> List[str]:
"""Transform selected display names back to actual column names."""
if self.column_mapping:
reverse_mapping = {v: k for k, v in self.column_mapping.items()}
return [reverse_mapping.get(col, col) for col in x]
return x
def get_filtered_columns(self, df: pd.DataFrame) -> Dict[str, List[str]]:
"""
Get columns filtered by substring matches.
Args:
df: Input DataFrame
Returns:
Dict mapping filter names to lists of matching columns
"""
filtered_cols = {}
for filter_name, substrings in self.column_filters.items():
matching_cols = []
for col in df.columns:
if any(substr.lower() in col.lower() for substr in substrings):
matching_cols.append(col)
filtered_cols[filter_name] = matching_cols
return filtered_cols
def update(
self,
value: Union[pd.DataFrame, Dict[str, List[str]]],
interactive: Optional[bool] = None
) -> Dict:
"""
Update the component with new values.
Args:
value: Either a DataFrame or dict of predefined column groups
interactive: Whether the component should be interactive
Returns:
Dict containing the update configuration
"""
if isinstance(value, pd.DataFrame):
# Get filtered column groups
filtered_cols = self.get_filtered_columns(value)
# Create display names for columns if mapping exists
choices = list(value.columns)
if self.column_mapping:
choices = [self.column_mapping.get(col, col) for col in choices]
return {
"choices": choices,
"filtered_cols": filtered_cols,
"interactive": interactive if interactive is not None else self.interactive
}
return super().update(value, interactive)
# Example usage
if __name__ == "__main__":
df = pd.DataFrame({
"ioi_score_1": [1, 2, 3],
"ioi_score_2": [4, 5, 6],
"other_metric": [7, 8, 9],
"performance_1": [10, 11, 12]
})
# Define filters and mappings
column_filters = {
"IOI": ["ioi"],
"Performance Metrics": ["performance"]
}
column_mapping = {
"ioi_score_1": "IOI Score (Type 1)",
"ioi_score_2": "IOI Score (Type 2)",
"other_metric": "Other Metric",
"performance_1": "Performance Metric 1"
}
# Create interface
with gr.Blocks() as demo:
select_cols = SmartSelectColumns(
column_filters=column_filters,
column_mapping=column_mapping,
multiselect=True
)
# Update component with DataFrame
select_cols.update(df)
demo.launch()
import gradio as gr
import pandas as pd
from typing import List, Dict, Union, Optional, Any
from dataclasses import fields
class SmartSelectColumns(gr.SelectColumns):
"""
Enhanced SelectColumns component for Gradio Leaderboard with smart filtering and mapping capabilities.
"""
def __init__(
self,
column_filters: Optional[Dict[str, List[str]]] = None,
column_mapping: Optional[Dict[str, str]] = None,
initial_selected: Optional[List[str]] = None,
*args,
**kwargs
):
"""
Initialize SmartSelectColumns with enhanced functionality.
Args:
column_filters: Dict mapping filter names to lists of substrings to match
column_mapping: Dict mapping actual column names to display names
initial_selected: List of column names to be initially selected
*args, **kwargs: Additional arguments passed to parent SelectColumns
"""
super().__init__(*args, **kwargs)
self.column_filters = column_filters or {}
self.column_mapping = column_mapping or {}
self.reverse_mapping = {v: k for k, v in self.column_mapping.items()} if column_mapping else {}
self.initial_selected = initial_selected or []
def preprocess(self, x: List[str]) -> List[str]:
"""
Transform selected display names back to actual column names.
Args:
x: List of selected display names
Returns:
List of actual column names
"""
return [self.reverse_mapping.get(col, col) for col in x]
def postprocess(self, y: List[str]) -> List[str]:
"""
Transform actual column names to display names.
Args:
y: List of actual column names
Returns:
List of display names
"""
return [self.column_mapping.get(col, col) for col in y]
def get_filtered_columns(self, df: pd.DataFrame) -> Dict[str, List[str]]:
"""
Get columns filtered by substring matches.
Args:
df: Input DataFrame
Returns:
Dict mapping filter names to lists of matching display names
"""
filtered_cols = {}
for filter_name, substrings in self.column_filters.items():
matching_cols = []
for col in df.columns:
if any(substr.lower() in col.lower() for substr in substrings):
display_name = self.column_mapping.get(col, col)
matching_cols.append(display_name)
filtered_cols[filter_name] = matching_cols
return filtered_cols
def update(
self,
value: Union[pd.DataFrame, Dict[str, List[str]], Any],
interactive: Optional[bool] = None
) -> Dict:
"""
Update component with new values, supporting DataFrame fields.
Args:
value: DataFrame, dict of columns, or fields object
interactive: Whether component should be interactive
Returns:
Dict containing update configuration
"""
if isinstance(value, pd.DataFrame):
filtered_cols = self.get_filtered_columns(value)
choices = [self.column_mapping.get(col, col) for col in value.columns]
# Set initial selection if provided
value = self.initial_selected if self.initial_selected else choices
return {
"choices": choices,
"value": value,
"filtered_cols": filtered_cols,
"interactive": interactive if interactive is not None else self.interactive
}
# Handle fields object (e.g., from dataclass)
if hasattr(value, '__dataclass_fields__'):
field_names = [field.name for field in fields(value)]
choices = [self.column_mapping.get(name, name) for name in field_names]
return {
"choices": choices,
"value": self.initial_selected if self.initial_selected else choices,
"interactive": interactive if interactive is not None else self.interactive
}
return super().update(value, interactive)
def initialize_leaderboard(df: pd.DataFrame, column_class: Any,
filters: Dict[str, List[str]],
mappings: Dict[str, str],
initial_columns: Optional[List[str]] = None) -> gr.Leaderboard:
"""
Initialize a Gradio Leaderboard with SmartSelectColumns.
Args:
df: Input DataFrame
column_class: Class containing column definitions (e.g., AutoEvalColumn_mib_subgraph)
filters: Column filters for substring matching
mappings: Column name mappings (actual -> display)
initial_columns: List of columns to show initially
Returns:
Configured Leaderboard instance
"""
# Define filters and mappings
filters = {
"IOI Metrics": ["ioi"],
"Performance Metrics": ["performance"]
}
mappings = {
"ioi_score_1": "IOI Score (Type 1)",
"ioi_score_2": "IOI Score (Type 2)",
"other_metric": "Other Metric",
"performance_1": "Performance Metric 1"
}
# Example usage
if __name__ == "__main__":
# Sample data
df = pd.DataFrame({
"ioi_score_1": [1, 2, 3],
"ioi_score_2": [4, 5, 6],
"other_metric": [7, 8, 9],
"performance_1": [10, 11, 12],
"Method": ["A", "B", "C"]
})
# Define filters and mappings
filters = {
"IOI Metrics": ["ioi"],
"gemma2.5": ["gemma2_5`"]
}
mappings = {
"ioi_score_1": "IOI Score (Type 1)",
"ioi_score_2": "IOI Score (Type 2)",
"other_metric": "Other Metric",
"performance_1": "Performance Metric 1"
}
# Create demo interface
with gr.Blocks() as demo:
# Initialize leaderboard with smart columns
leaderboard = initialize_leaderboard(
df=df,
column_class=None, # Replace with your actual column class
filters=filters,
mappings=mappings,
initial_columns=["Method", "IOI Score (Type 1)"]
)
# Create renamed DataFrame with display names
renamed_df = df.rename(columns=mappings)
initial_columns=["Method", "IOI Score (Type 1)"]
initial_columns=?
# Initialize SmartSelectColumns
smart_columns = SmartSelectColumns(
column_filters=filters,
column_mapping=mappings,
initial_selected=initial_columns,
multiselect=True
)
column_class=None
return gr.Leaderboard(
value=renamed_df,
datatype=[c.type for c in fields(column_class)],
select_columns=smart_columns,
search_columns=["Method"],
hide_columns=[],
interactive=False
)
demo.launch()
from gradio_leaderboard import SelectColumns, Leaderboard
import pandas as pd
from typing import List, Dict, Union, Optional, Any
from dataclasses import fields
class SmartSelectColumns(SelectColumns):
"""
Enhanced SelectColumns component for gradio_leaderboard with explicit column grouping.
"""
def __init__(
self,
column_groups: Optional[Dict[str, List[str]]] = None,
column_mapping: Optional[Dict[str, str]] = None,
initial_selected: Optional[List[str]] = None,
**kwargs
):
"""
Initialize SmartSelectColumns with enhanced functionality.
Args:
column_groups: Dict mapping group names to lists of columns in that group
column_mapping: Dict mapping actual column names to display names
initial_selected: List of columns to show initially
"""
super().__init__(**kwargs)
self.column_groups = column_groups or {}
self.column_mapping = column_mapping or {}
self.reverse_mapping = {v: k for k, v in self.column_mapping.items()} if column_mapping else {}
self.initial_selected = initial_selected or []
def preprocess_value(self, x: List[str]) -> List[str]:
"""Transform selected display names back to actual column names."""
return [self.reverse_mapping.get(col, col) for col in x]
def postprocess_value(self, y: List[str]) -> List[str]:
"""Transform actual column names to display names."""
return [self.column_mapping.get(col, col) for col in y]
def update(
self,
value: Union[pd.DataFrame, Dict[str, List[str]], Any]
) -> Dict:
"""Update component with new values."""
if isinstance(value, pd.DataFrame):
# Get all column names and convert to display names
choices = [self.column_mapping.get(col, col) for col in value.columns]
# Use initial selection or default columns
selected = self.initial_selected if self.initial_selected else choices
# Convert column groups to use display names
filtered_cols = {}
for group_name, columns in self.column_groups.items():
filtered_cols[group_name] = [
self.column_mapping.get(col, col)
for col in columns
if col in value.columns
]
return {
"choices": choices,
"value": selected,
"filtered_cols": filtered_cols
}
# Handle fields object
if hasattr(value, '__dataclass_fields__'):
field_names = [field.name for field in fields(value)]
choices = [self.column_mapping.get(name, name) for name in field_names]
return {
"choices": choices,
"value": self.initial_selected if self.initial_selected else choices
}
return super().update(value)
# Example usage
if __name__ == "__main__":
# Sample DataFrame
# df = pd.DataFrame({
# "eval_name": ["test1", "test2", "test3"],
# "Method": ["method1", "method2", "method3"],
# "ioi_llama3": [0.1, 0.2, 0.3],
# "ioi_qwen2_5": [0.4, 0.5, 0.6],
# "ioi_gpt2": [0.7, 0.8, 0.9],
# "mcqa_llama3": [0.2, 0.3, 0.4],
# "Average": [0.35, 0.45, 0.55]
# })
# Complete column groups for both benchmarks and models
column_groups = {
# Benchmark groups
"Benchmark group for ioi": ["ioi_gpt2", "ioi_qwen2_5", "ioi_gemma2", "ioi_llama3"],
"Benchmark group for mcqa": ["mcqa_qwen2_5", "mcqa_gemma2", "mcqa_llama3"],
"Benchmark group for arithmetic_addition": ["arithmetic_addition_llama3"],
"Benchmark group for arithmetic_subtraction": ["arithmetic_subtraction_llama3"],
"Benchmark group for arc_easy": ["arc_easy_gemma2", "arc_easy_llama3"],
"Benchmark group for arc_challenge": ["arc_challenge_llama3"],
# Model groups
"Model group for qwen2_5": ["ioi_qwen2_5", "mcqa_qwen2_5"],
"Model group for gpt2": ["ioi_gpt2"],
"Model group for gemma2": ["ioi_gemma2", "mcqa_gemma2", "arc_easy_gemma2"],
"Model group for llama3": [
"ioi_llama3",
"mcqa_llama3",
"arithmetic_addition_llama3",
"arithmetic_subtraction_llama3",
"arc_easy_llama3",
"arc_challenge_llama3"
]
}
# Complete mappings for more readable display names
mappings = {
# IOI benchmark mappings
"ioi_llama3": "IOI (LLaMA-3)",
"ioi_qwen2_5": "IOI (Qwen-2.5)",
"ioi_gpt2": "IOI (GPT-2)",
"ioi_gemma2": "IOI (Gemma-2)",
# MCQA benchmark mappings
"mcqa_llama3": "MCQA (LLaMA-3)",
"mcqa_qwen2_5": "MCQA (Qwen-2.5)",
"mcqa_gemma2": "MCQA (Gemma-2)",
# Arithmetic benchmark mappings
"arithmetic_addition_llama3": "Arithmetic Addition (LLaMA-3)",
"arithmetic_subtraction_llama3": "Arithmetic Subtraction (LLaMA-3)",
# ARC benchmark mappings
"arc_easy_llama3": "ARC Easy (LLaMA-3)",
"arc_easy_gemma2": "ARC Easy (Gemma-2)",
"arc_challenge_llama3": "ARC Challenge (LLaMA-3)",
# Other columns
"eval_name": "Evaluation Name",
"Method": "Method",
"Average": "Average Score"
}
# Create SmartSelectColumns instance
smart_columns = SmartSelectColumns(
column_groups=column_groups,
column_mapping=mappings,
initial_selected=["Method", "Average"]
)
# Create Leaderboard directly
leaderboard = Leaderboard(
value=df,
datatype=[c.type for c in fields(AutoEvalColumn_mib_subgraph)],
select_columns=smart_columns,
search_columns=["Method"],
hide_columns=[],
interactive=False
)
from gradio_leaderboard import SelectColumns, Leaderboard
import pandas as pd
from typing import List, Dict, Union, Optional, Any
from dataclasses import fields
class SmartSelectColumns(SelectColumns):
"""
Enhanced SelectColumns component for gradio_leaderboard with dynamic column filtering.
"""
def __init__(
self,
benchmark_keywords: Optional[List[str]] = None,
model_keywords: Optional[List[str]] = None,
column_mapping: Optional[Dict[str, str]] = None,
initial_selected: Optional[List[str]] = None,
**kwargs
):
"""
Initialize SmartSelectColumns with dynamic filtering.
Args:
benchmark_keywords: List of benchmark names to filter by (e.g., ["ioi", "mcqa"])
model_keywords: List of model names to filter by (e.g., ["llama3", "qwen2_5"])
column_mapping: Dict mapping actual column names to display names
initial_selected: List of columns to show initially
"""
super().__init__(**kwargs)
self.benchmark_keywords = benchmark_keywords or []
self.model_keywords = model_keywords or []
self.column_mapping = column_mapping or {}
self.reverse_mapping = {v: k for k, v in self.column_mapping.items()} if column_mapping else {}
self.initial_selected = initial_selected or []
def preprocess_value(self, x: List[str]) -> List[str]:
"""Transform selected display names back to actual column names."""
return [self.reverse_mapping.get(col, col) for col in x]
def postprocess_value(self, y: List[str]) -> List[str]:
"""Transform actual column names to display names."""
return [self.column_mapping.get(col, col) for col in y]
def get_filtered_groups(self, df: pd.DataFrame) -> Dict[str, List[str]]:
"""
Dynamically create column groups based on keywords.
"""
filtered_groups = {}
# Create benchmark groups
for benchmark in self.benchmark_keywords:
matching_cols = [
col for col in df.columns
if benchmark in col.lower()
]
if matching_cols:
group_name = f"Benchmark group for {benchmark}"
filtered_groups[group_name] = [
self.column_mapping.get(col, col)
for col in matching_cols
]
# Create model groups
for model in self.model_keywords:
matching_cols = [
col for col in df.columns
if model in col.lower()
]
if matching_cols:
group_name = f"Model group for {model}"
filtered_groups[group_name] = [
self.column_mapping.get(col, col)
for col in matching_cols
]
return filtered_groups
def update(
self,
value: Union[pd.DataFrame, Dict[str, List[str]], Any]
) -> Dict:
"""Update component with new values."""
if isinstance(value, pd.DataFrame):
# Get all column names and convert to display names
choices = [self.column_mapping.get(col, col) for col in value.columns]
# Use initial selection or default columns
selected = self.initial_selected if self.initial_selected else choices
# Get dynamically filtered groups
filtered_cols = self.get_filtered_groups(value)
return {
"choices": choices,
"value": selected,
"filtered_cols": filtered_cols
}
# Handle fields object
if hasattr(value, '__dataclass_fields__'):
field_names = [field.name for field in fields(value)]
choices = [self.column_mapping.get(name, name) for name in field_names]
return {
"choices": choices,
"value": self.initial_selected if self.initial_selected else choices
}
return super().update(value)
# Example usage
if __name__ == "__main__":
# Sample DataFrame
df = pd.DataFrame({
"eval_name": ["test1", "test2", "test3"],
"Method": ["method1", "method2", "method3"],
"ioi_llama3": [0.1, 0.2, 0.3],
"ioi_qwen2_5": [0.4, 0.5, 0.6],
"ioi_gpt2": [0.7, 0.8, 0.9],
"mcqa_llama3": [0.2, 0.3, 0.4],
"Average": [0.35, 0.45, 0.55]
})
# Define keywords for filtering
benchmark_keywords = ["ioi", "mcqa", "arithmetic_addition", "arithmetic_subtraction", "arc_easy", "arc_challenge"]
model_keywords = ["qwen2_5", "gpt2", "gemma2", "llama3"]
# Optional: Define display names
mappings = {
"ioi_llama3": "IOI (LLaMA-3)",
"ioi_qwen2_5": "IOI (Qwen-2.5)",
"ioi_gpt2": "IOI (GPT-2)",
"ioi_gemma2": "IOI (Gemma-2)",
"mcqa_llama3": "MCQA (LLaMA-3)",
"mcqa_qwen2_5": "MCQA (Qwen-2.5)",
"mcqa_gemma2": "MCQA (Gemma-2)",
"arithmetic_addition_llama3": "Arithmetic Addition (LLaMA-3)",
"arithmetic_subtraction_llama3": "Arithmetic Subtraction (LLaMA-3)",
"arc_easy_llama3": "ARC Easy (LLaMA-3)",
"arc_easy_gemma2": "ARC Easy (Gemma-2)",
"arc_challenge_llama3": "ARC Challenge (LLaMA-3)",
"eval_name": "Evaluation Name",
"Method": "Method",
"Average": "Average Score"
}
# Create SmartSelectColumns instance
smart_columns = SmartSelectColumns(
benchmark_keywords=benchmark_keywords,
model_keywords=model_keywords,
column_mapping=mappings,
initial_selected=["Method", "Average"]
)
# Create Leaderboard
leaderboard = Leaderboard(
value=df,
datatype=[c.type for c in fields(AutoEvalColumn_mib_subgraph)],
select_columns=smart_columns,
search_columns=["Method"],
hide_columns=[],
interactive=False
)
Debugging DataFrame columns: ['eval_name', 'Method', 'ioi_llama3', 'ioi_qwen2_5', 'ioi_gpt2', 'ioi_gemma2', 'mcqa_llama3', 'mcqa_qwen2_5', 'mcqa_gemma2', 'arithmetic_addition_llama3', 'arithmetic_subtraction_llama3', 'arc_easy_llama3', 'arc_easy_gemma2', 'arc_challenge_llama3', 'Average']
Benchmark group for ioi: ['ioi_gpt2', 'ioi_qwen2_5', 'ioi_gemma2', 'ioi_llama3']
Benchmark group for mcqa: ['mcqa_qwen2_5', 'mcqa_gemma2', 'mcqa_llama3']
Benchmark group for arithmetic_addition: ['arithmetic_addition_llama3']
Benchmark group for arithmetic_subtraction: ['arithmetic_subtraction_llama3']
Benchmark group for arc_easy: ['arc_easy_gemma2', 'arc_easy_llama3']
Benchmark group for arc_challenge: ['arc_challenge_llama3']
Model group for qwen2_5: ['ioi_qwen2_5', 'mcqa_qwen2_5']
Model group for gpt2: ['ioi_gpt2']
Model group for gemma2: ['ioi_gemma2', 'mcqa_gemma2', 'arc_easy_gemma2']
Model group for llama3: ['ioi_llama3', 'mcqa_llama3', 'arithmetic_addition_llama3', 'arithmetic_subtraction_llama3', 'arc_easy_llama3', 'arc_challenge_llama3']
All available columns: ['ioi_gpt2', 'ioi_qwen2_5', 'ioi_gemma2', 'ioi_llama3', 'mcqa_qwen2_5', 'mcqa_gemma2', 'mcqa_llama3', 'arithmetic_addition_llama3', 'arithmetic_subtraction_llama3', 'arc_easy_gemma2', 'arc_easy_llama3', 'arc_challenge_llama3', 'ioi_qwen2_5', 'mcqa_qwen2_5', 'ioi_gpt2', 'ioi_gemma2', 'mcqa_gemma2', 'arc_easy_gemma2', 'ioi_llama3', 'mcqa_llama3', 'arithmetic_addition_llama3', 'arithmetic_subtraction_llama3', 'arc_easy_llama3', 'arc_challenge_llama3']
* Running on local URL: http://0.0.0.0:7860
/usr/local/lib/python3.10/site-packages/gradio/blocks.py:2634: UserWarning: Setting share=True is not supported on Hugging Face Spaces
warnings.warn(
To create a public link, set `share=True` in `launch()`.
model_id: llama3, gemma2, gpt2, qwen2.5,