Mars-Bench / app.py
gremlin97's picture
Make Model column header bold in leaderboard table
5e434f3
import gradio as gr
import pandas as pd
import os
# Load data from CSV files
DATA_DIR = "data"
def load_csv_data(filename):
"""Load data from CSV file"""
filepath = os.path.join(DATA_DIR, filename)
if os.path.exists(filepath):
return pd.read_csv(filepath)
else:
return pd.DataFrame()
# Load datasets
CLASSIFICATION_DF = load_csv_data("classification.csv")
DETECTION_DF = load_csv_data("detection.csv")
SEGMENTATION_DF = load_csv_data("segmentation.csv")
def filter_and_search(df, search, datasets, models, organizations, columns):
filtered = df.copy()
if search:
mask = filtered.apply(lambda row: row.astype(str).str.contains(search, case=False).any(), axis=1)
filtered = filtered[mask]
if datasets:
filtered = filtered[filtered["Dataset"].isin(datasets)]
if models:
filtered = filtered[filtered["Model"].isin(models)]
if organizations:
filtered = filtered[filtered["Organization"].isin(organizations)]
if columns:
display_cols = [col for col in columns if col in filtered.columns]
filtered = filtered[display_cols]
return filtered
def build_tab(df, name):
"""Build a leaderboard tab from a DataFrame"""
if df.empty:
return gr.TabItem(name)
# Pivot the dataframe to have columns like "Dataset1 (Metric1)", "Dataset1 (Metric2)", etc.
datasets = sorted(df["Dataset"].unique().tolist())
models = sorted(df["Model"].unique().tolist())
organizations = sorted(df["Organization"].unique().tolist())
metric_cols = [col for col in df.columns if col not in ["Model", "Organization", "Dataset", "Author", "Author Link"]]
# Create pivoted dataframe
pivoted_data = []
for model in models:
for org in organizations:
model_org_data = df[(df["Model"] == model) & (df["Organization"] == org)]
if not model_org_data.empty:
# Get Author and Author Link from the first entry (they should be the same for model+org)
author = model_org_data["Author"].values[0]
author_link = model_org_data["Author Link"].values[0]
# Format as markdown link if author_link exists
if pd.notna(author_link) and author_link.strip():
author_display = f"[{author}]({author_link})"
else:
author_display = author
row = {"Model": model, "Organization": org, "Author": author_display}
for dataset in datasets:
dataset_data = model_org_data[model_org_data["Dataset"] == dataset]
if not dataset_data.empty:
for metric in metric_cols:
col_name = f"{dataset} ({metric})"
row[col_name] = dataset_data[metric].values[0]
else:
for metric in metric_cols:
col_name = f"{dataset} ({metric})"
row[col_name] = "-"
pivoted_data.append(row)
pivoted_df = pd.DataFrame(pivoted_data)
# Build column list for selector
metric_combo_cols = []
for dataset in datasets:
for metric in metric_cols:
metric_combo_cols.append(f"{dataset} ({metric})")
all_cols = ["Model", "Organization", "Author"] + metric_combo_cols
with gr.TabItem(name, elem_id="llm-benchmark-tab-table"):
with gr.Row():
with gr.Column(scale=4):
search_bar = gr.Textbox(
label="Search",
placeholder="Separate multiple queries with ';'",
elem_id="search-bar"
)
# Column selector for base columns only (not dataset+metric combos)
base_cols = ["Model", "Organization", "Author"]
col_selector = gr.CheckboxGroup(
choices=base_cols,
value=base_cols,
label="Select Columns to Display:",
elem_classes="column-select"
)
# Set datatype to 'markdown' for Author column to enable clickable links
datatypes = []
for col in pivoted_df.columns:
if col == "Author":
datatypes.append("markdown")
else:
datatypes.append("str")
table = gr.Dataframe(
value=pivoted_df,
elem_id="leaderboard-table",
interactive=False,
wrap=True,
datatype=datatypes
)
with gr.Column(scale=1):
gr.Markdown("**Model types**")
model_filter = gr.CheckboxGroup(
choices=models,
value=models,
label="",
elem_classes="filter-group"
)
gr.Markdown("**Organizations**")
org_filter = gr.CheckboxGroup(
choices=organizations,
value=organizations,
label="",
elem_classes="filter-group"
)
gr.Markdown("**Datasets**")
dataset_filter = gr.CheckboxGroup(
choices=datasets,
value=datasets,
label="",
elem_classes="filter-group"
)
gr.Markdown("**Metrics**")
metric_filter = gr.CheckboxGroup(
choices=metric_cols,
value=metric_cols,
label="",
elem_classes="filter-group"
)
def update(search, md, org, dset, metrics, cols):
filtered = pivoted_df.copy()
if search:
mask = filtered.apply(lambda row: row.astype(str).str.contains(search, case=False).any(), axis=1)
filtered = filtered[mask]
if md:
filtered = filtered[filtered["Model"].isin(md)]
if org:
filtered = filtered[filtered["Organization"].isin(org)]
# Build display columns based on selected base columns and dataset/metric filters
display_cols = []
# Add selected base columns
for col in cols:
if col in base_cols:
display_cols.append(col)
# Add metric columns that match selected datasets and metrics
for col in metric_combo_cols:
# Check if this column matches selected datasets and metrics
col_dataset = col.split(" (")[0]
col_metric = col.split(" (")[1].rstrip(")")
if col_dataset in dset and col_metric in metrics:
display_cols.append(col)
filtered = filtered[display_cols]
return filtered
search_bar.change(update, [search_bar, model_filter, org_filter, dataset_filter, metric_filter, col_selector], table)
model_filter.change(update, [search_bar, model_filter, org_filter, dataset_filter, metric_filter, col_selector], table)
org_filter.change(update, [search_bar, model_filter, org_filter, dataset_filter, metric_filter, col_selector], table)
dataset_filter.change(update, [search_bar, model_filter, org_filter, dataset_filter, metric_filter, col_selector], table)
metric_filter.change(update, [search_bar, model_filter, org_filter, dataset_filter, metric_filter, col_selector], table)
col_selector.change(update, [search_bar, model_filter, org_filter, dataset_filter, metric_filter, col_selector], table)
custom_css = """
.markdown-text {
font-size: 16px !important;
}
#leaderboard-table {
margin-top: 15px;
}
#leaderboard-table table {
width: 100%;
table-layout: auto;
}
#leaderboard-table thead th {
font-weight: bold;
text-align: center;
padding: 12px 8px;
white-space: normal;
word-wrap: break-word;
}
#leaderboard-table tbody td {
text-align: center;
padding: 10px 8px;
white-space: nowrap;
}
#leaderboard-table tbody td:first-child {
text-align: left;
font-weight: 500;
min-width: 120px;
max-width: 200px;
white-space: nowrap;
}
#leaderboard-table thead th:first-child {
text-align: left;
font-weight: bold;
min-width: 120px;
max-width: 200px;
white-space: nowrap;
}
#leaderboard-table tbody td:nth-child(2),
#leaderboard-table thead th:nth-child(2) {
text-align: left;
min-width: 100px;
}
#leaderboard-table tbody td:nth-child(3),
#leaderboard-table thead th:nth-child(3) {
text-align: left;
min-width: 120px;
}
/* Style links in Author column */
#leaderboard-table a {
color: #0066cc;
text-decoration: none;
}
#leaderboard-table a:hover {
text-decoration: underline;
}
#search-bar {
margin-bottom: 0px;
}
#search-bar textarea {
border: 1px solid #e0e0e0 !important;
border-radius: 8px !important;
}
.tab-buttons button {
font-size: 20px;
}
.filter-group {
margin-bottom: 1em;
}
.filter-group label {
font-size: 14px;
}
.column-select {
margin-bottom: 1.5em;
}
.column-select label {
display: flex;
flex-wrap: wrap;
gap: 0.5em;
}
.column-select label > span {
display: inline-flex;
align-items: center;
}
"""
TITLE = """<h1 align="center" id="space-title">Mars-Bench Leaderboard</h1>"""
INTRO = """
A comprehensive benchmark for evaluating computer vision models on Mars-specific datasets.
This leaderboard tracks model performance across three key tasks: classification, segmentation, and object detection.
"""
demo = gr.Blocks(css=custom_css, title="Mars-Bench Leaderboard")
with demo:
gr.HTML(TITLE)
gr.Markdown(INTRO, elem_classes="markdown-text")
with gr.Tabs(elem_classes="tab-buttons"):
build_tab(CLASSIFICATION_DF, "🏅 Classification")
build_tab(SEGMENTATION_DF, "🏅 Segmentation")
build_tab(DETECTION_DF, "🏅 Object Detection")
with gr.TabItem("📝 Submit", elem_id="submit-tab"):
gr.Markdown("""
# Submit Your Model Results
To submit your model's results to Mars-Bench, please provide the following information.
All submissions will be reviewed before being added to the leaderboard.
""")
gr.Markdown("""
### How to submit:
1. Fill out the form below
2. Click "Generate Submission Text"
3. Copy the generated text
4. Go to the [Community tab](https://huggingface.co/spaces/gremlin97/MarsBoard/discussions)
5. Click "New discussion"
6. Paste the text and submit
---
""")
with gr.Row():
with gr.Column():
submit_task = gr.Dropdown(
choices=["Classification", "Segmentation", "Object Detection"],
label="Task Type",
info="Select the task category"
)
submit_model = gr.Textbox(
label="Model Name",
placeholder="e.g., ResNet-50",
info="Name of your model"
)
submit_org = gr.Textbox(
label="Organization",
placeholder="e.g., Microsoft, Google",
info="Your organization or affiliation"
)
submit_dataset = gr.Textbox(
label="Dataset",
placeholder="e.g., DoMars16, Mars Crater",
info="Dataset used for evaluation"
)
with gr.Column():
submit_author = gr.Textbox(
label="Author",
placeholder="e.g., K. He",
info="Name of the author"
)
submit_author_link = gr.Textbox(
label="Author Page Link (Optional)",
placeholder="https://scholar.google.com/... or https://github.com/...",
info="Link to author's Google Scholar, GitHub, or personal page"
)
submit_metrics = gr.Textbox(
label="Metrics (JSON format)",
placeholder='{"Accuracy": 95.8, "F1-Score": 94.9}',
info="Provide metrics in JSON format",
lines=3
)
submit_paper = gr.Textbox(
label="Paper Link (Optional)",
placeholder="https://arxiv.org/abs/...",
info="Link to your research paper"
)
submit_code = gr.Textbox(
label="Code Repository (Optional)",
placeholder="https://github.com/...",
info="Link to your code repository"
)
submit_email = gr.Textbox(
label="Contact Email",
placeholder="your.email@example.com",
info="We'll contact you about your submission"
)
submit_notes = gr.Textbox(
label="Additional Notes (Optional)",
placeholder="Training details, hyperparameters, reproduction instructions...",
lines=4,
info="Any additional information"
)
generate_btn = gr.Button("Generate Submission Text", variant="primary", size="lg")
submission_output = gr.Textbox(
label="Copy this text and create a new discussion in the Community tab",
lines=15,
interactive=True
)
gr.Markdown("""
We'll review your submission and add it to the leaderboard if approved.
""")
def generate_submission_text(task, model, org, dataset, author, author_link, metrics, paper, code, email, notes):
if not all([task, model, org, dataset, author, metrics, email]):
return "❌ Error: Please fill in all required fields (Task Type, Model Name, Organization, Dataset, Author, Metrics, Contact Email)"
submission_text = f"""## New Model Submission
**Task Type:** {task}
**Model Name:** {model}
**Organization:** {org}
**Dataset:** {dataset}
**Author:** {author}
**Author Page Link:** {author_link if author_link else "N/A"}
### Metrics
```json
{metrics}
```
### Links
- **Paper:** {paper if paper else "N/A"}
- **Code:** {code if code else "N/A"}
### Contact
**Email:** {email}
### Additional Notes
{notes if notes else "N/A"}
---
*Please review this submission for inclusion in Mars-Bench.*
"""
return submission_text
generate_btn.click(
generate_submission_text,
inputs=[submit_task, submit_model, submit_org, submit_dataset, submit_author,
submit_author_link, submit_metrics, submit_paper, submit_code, submit_email, submit_notes],
outputs=submission_output
)
if __name__ == "__main__":
demo.launch()