| 59 | |
| 60 | |
| 61 | def plot_instability(df: pd.DataFrame, output: Path) -> None: |
| 62 | agents = sorted(df["agent"].unique()) |
| 63 | fig, axes = plt.subplots( |
| 64 | nrows=2, |
| 65 | ncols=len(agents), |
| 66 | figsize=(6 * len(agents), 9), |
| 67 | gridspec_kw={"height_ratios": [1, 2]}, |
| 68 | ) |
| 69 | |
| 70 | if len(agents) == 1: |
| 71 | axes = axes.reshape(2, 1) |
| 72 | |
| 73 | for col, agent in enumerate(agents): |
| 74 | agent_df = df[df["agent"] == agent] |
| 75 | |
| 76 | final_scores = ( |
| 77 | agent_df[["file", "finalScore"]].drop_duplicates().sort_values("file") |
| 78 | ) |
| 79 | ax_top = axes[0][col] |
| 80 | sns.barplot( |
| 81 | data=final_scores, |
| 82 | x="file", |
| 83 | y="finalScore", |
| 84 | palette="Blues_d", |
| 85 | ax=ax_top, |
| 86 | ) |
| 87 | ax_top.set_title(f"{agent} – Final Score by Run") |
| 88 | ax_top.set_ylim(0, 1) |
| 89 | ax_top.set_ylabel("finalScore") |
| 90 | ax_top.set_xlabel("") |
| 91 | ax_top.bar_label(ax_top.containers[0], fmt="%.3f", padding=3) |
| 92 | |
| 93 | pivot = ( |
| 94 | agent_df.pivot_table( |
| 95 | index="assignment", |
| 96 | columns="file", |
| 97 | values="averageScore", |
| 98 | aggfunc="mean", |
| 99 | ) |
| 100 | .reindex(sorted(agent_df["assignment"].unique())) |
| 101 | .sort_index(axis=1) |
| 102 | ) |
| 103 | |
| 104 | ax_bottom = axes[1][col] |
| 105 | sns.heatmap( |
| 106 | pivot, |
| 107 | annot=True, |
| 108 | fmt=".2f", |
| 109 | cmap="coolwarm", |
| 110 | vmin=0, |
| 111 | vmax=1, |
| 112 | cbar_kws={"label": "averageScore"}, |
| 113 | ax=ax_bottom, |
| 114 | ) |
| 115 | ax_bottom.set_title(f"{agent} – Assignment Scores") |
| 116 | ax_bottom.set_ylabel("assignment") |
| 117 | ax_bottom.set_xlabel("file/run") |
| 118 | |