Skip to content

Commit f2c756d

Browse files
committed
Enh(viz): llm as judge plot by arena
1 parent d5cce6c commit f2c756d

1 file changed

Lines changed: 40 additions & 24 deletions

File tree

codeclash/analysis/llm_as_judge/grounding_validation_triple_plot.py

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
import matplotlib.pyplot as plt
88
import numpy as np
99
import pandas as pd
10+
from matplotlib.ticker import AutoMinorLocator
1011

11-
from codeclash.analysis.viz.utils import FONT_BOLD, FONT_REG, MODEL_TO_DISPLAY_NAME
12+
from codeclash.analysis.viz.utils import FONT_BOLD, MODEL_TO_DISPLAY_NAME
1213

1314

1415
class GroundingValidationPlotter:
@@ -51,8 +52,10 @@ class GroundingValidationPlotter:
5152
("forestgreen", 0.3), # Simulations only
5253
]
5354

54-
def __init__(self, df: pd.DataFrame):
55+
def __init__(self, df: pd.DataFrame, *, fix_xlim: bool = False, title: str | None = None):
5556
self.df = df
57+
self.fix_xlim = fix_xlim
58+
self.title = title
5659

5760
# Aggregate hallucination columns by claim
5861
h_cols = [col for col in self.df.columns if col.startswith("h_")]
@@ -76,20 +79,20 @@ def __init__(self, df: pd.DataFrame):
7679
self.n_models = len(self.models)
7780

7881
# Create figure with 3 subplots sharing y-axis
79-
self.fig, self.axes = plt.subplots(1, 3, figsize=(12, 4), sharey=True)
82+
fig_height = 4.5 if self.title else 4
83+
self.fig, self.axes = plt.subplots(1, 3, figsize=(12, fig_height), sharey=True)
8084
self.y_positions = np.arange(self.n_models)
8185

8286
def _get_l_reason_breakdown(self, row) -> str:
8387
"""Categorize loss reason hallucinations."""
88+
if row["h_loss_reason"] == 0:
89+
return ""
90+
if row["h_loss_reason"] == row["h_loss_reason__none"]:
91+
return "no source"
8492
c0 = ["h_loss_reason__log", "h_loss_reason__execution_output.analysis"]
8593
if any([row[c] > 0 for c in c0]):
8694
return "logs/analysis"
87-
elif row["h_loss_reason__none"] > 0:
88-
if row["h_loss_reason"] > row["h_loss_reason__none"]:
89-
# There's other cols that are also > 0
90-
return "docs/tests/other"
91-
return "no source"
92-
return ""
95+
return "other"
9396

9497
def _add_stacked_bar_labels(self, ax, stacked_values: list[list[float]], min_value_to_show: float = 5.0):
9598
"""Add percentage labels inside stacked bars.
@@ -203,7 +206,7 @@ def plot_grounding_analysis(self):
203206
ax.set_title("(a) Groundedness of edits", fontproperties=font_title, pad=self.title_pad)
204207

205208
# Legend
206-
font_legend = FONT_REG.copy()
209+
font_legend = FONT_BOLD.copy()
207210
font_legend.set_size(self.legend_fontsize)
208211
leg = ax.legend(
209212
frameon=False,
@@ -216,21 +219,23 @@ def plot_grounding_analysis(self):
216219

217220
# Y-axis
218221
ax.set_yticks(self.y_positions)
219-
font_ytick = FONT_REG.copy()
222+
font_ytick = FONT_BOLD.copy()
220223
font_ytick.set_size(self.ytick_label_fontsize)
221224
ax.set_yticklabels(self.models, fontproperties=font_ytick)
222225

223226
# X-axis
224-
font_label = FONT_REG.copy()
227+
font_label = FONT_BOLD.copy()
225228
font_label.set_size(self.label_fontsize)
226229
ax.set_xlabel("Percentage of rounds", fontproperties=font_label)
227230
ax.tick_params(axis="y", length=0)
228231
ax.tick_params(axis="x", labelsize=self.xtick_label_fontsize)
229-
font_xtick = FONT_REG.copy()
232+
font_xtick = FONT_BOLD.copy()
230233
font_xtick.set_size(self.xtick_label_fontsize)
231234
for label in ax.get_xticklabels():
232235
label.set_fontproperties(font_xtick)
233-
ax.xaxis.set_minor_locator(plt.MultipleLocator(5))
236+
ax.xaxis.set_minor_locator(AutoMinorLocator())
237+
if self.fix_xlim:
238+
ax.set_xlim(0, 100)
234239
ax.spines["top"].set_visible(False)
235240
ax.spines["right"].set_visible(False)
236241

@@ -310,7 +315,7 @@ def plot_validation_feedback(self):
310315
ax.set_title("(c) Validation of edits", fontproperties=font_title, pad=self.title_pad)
311316

312317
# Legend
313-
font_legend = FONT_REG.copy()
318+
font_legend = FONT_BOLD.copy()
314319
font_legend.set_size(self.legend_fontsize)
315320
leg = ax.legend(
316321
frameon=False,
@@ -325,16 +330,18 @@ def plot_validation_feedback(self):
325330
leg.set_in_layout(False)
326331

327332
# X-axis
328-
font_label = FONT_REG.copy()
333+
font_label = FONT_BOLD.copy()
329334
font_label.set_size(self.label_fontsize)
330335
ax.set_xlabel("Percentage of rounds", fontproperties=font_label)
331336
ax.tick_params(axis="y", length=0)
332337
ax.tick_params(axis="x", labelsize=self.xtick_label_fontsize)
333-
font_xtick = FONT_REG.copy()
338+
font_xtick = FONT_BOLD.copy()
334339
font_xtick.set_size(self.xtick_label_fontsize)
335340
for label in ax.get_xticklabels():
336341
label.set_fontproperties(font_xtick)
337-
ax.xaxis.set_minor_locator(plt.MultipleLocator(5))
342+
ax.xaxis.set_minor_locator(AutoMinorLocator())
343+
if self.fix_xlim:
344+
ax.set_xlim(0, 100)
338345
ax.spines["top"].set_visible(False)
339346
ax.spines["right"].set_visible(False)
340347

@@ -349,7 +356,7 @@ def plot_hallucination_categories(self):
349356
model_df = self.df[self.df["model_name"] == model]
350357
total_rounds = len(model_df)
351358

352-
mis_count = ((model_df["hal_cat1"] == "logs/analysis") | (model_df["hal_cat1"] == "docs/tests/other")).sum()
359+
mis_count = ((model_df["hal_cat1"] == "logs/analysis") | (model_df["hal_cat1"] == "other")).sum()
353360
no_src_count = (model_df["hal_cat1"] == "no source").sum()
354361

355362
misinterpretation.append((mis_count / total_rounds * 100) if total_rounds > 0 else 0)
@@ -394,7 +401,7 @@ def plot_hallucination_categories(self):
394401
ax.set_title("(b) Hallucinated Loss Causality", fontproperties=font_title, pad=self.title_pad)
395402

396403
# Legend
397-
font_legend = FONT_REG.copy()
404+
font_legend = FONT_BOLD.copy()
398405
font_legend.set_size(self.legend_fontsize)
399406
leg = ax.legend(
400407
frameon=False,
@@ -409,16 +416,18 @@ def plot_hallucination_categories(self):
409416
leg.set_in_layout(False)
410417

411418
# X-axis
412-
font_label = FONT_REG.copy()
419+
font_label = FONT_BOLD.copy()
413420
font_label.set_size(self.label_fontsize)
414421
ax.set_xlabel("Percentage of rounds", fontproperties=font_label)
415422
ax.tick_params(axis="y", length=0)
416423
ax.tick_params(axis="x", labelsize=self.xtick_label_fontsize)
417-
font_xtick = FONT_REG.copy()
424+
font_xtick = FONT_BOLD.copy()
418425
font_xtick.set_size(self.xtick_label_fontsize)
419426
for label in ax.get_xticklabels():
420427
label.set_fontproperties(font_xtick)
421-
ax.xaxis.set_minor_locator(plt.MultipleLocator(5))
428+
ax.xaxis.set_minor_locator(AutoMinorLocator())
429+
if self.fix_xlim:
430+
ax.set_xlim(0, 50)
422431
ax.spines["top"].set_visible(False)
423432
ax.spines["right"].set_visible(False)
424433

@@ -427,6 +436,12 @@ def create_plot(self):
427436
self.plot_grounding_analysis()
428437
self.plot_hallucination_categories()
429438
self.plot_validation_feedback()
439+
440+
if self.title:
441+
font_suptitle = FONT_BOLD.copy()
442+
font_suptitle.set_size(18)
443+
self.fig.suptitle(self.title, fontproperties=font_suptitle, y=0.95)
444+
430445
self.fig.tight_layout()
431446

432447
def save(self, output_path: Path):
@@ -472,7 +487,8 @@ def main():
472487
game_df = df[df["game_name"] == game_name].copy()
473488
game_output = output_dir / f"{output_stem}_{game_name}.pdf"
474489

475-
plotter = GroundingValidationPlotter(game_df)
490+
display_title = "Poker" if game_name == "HuskyBench" else game_name
491+
plotter = GroundingValidationPlotter(game_df, fix_xlim=True, title=display_title)
476492
plotter.create_plot()
477493
plotter.save(game_output)
478494

0 commit comments

Comments
 (0)