Adjsuting and cleaning

This commit is contained in:
2026-02-08 01:59:38 +01:00
parent f4bf37f71c
commit 2f507bcf20
4 changed files with 148 additions and 209 deletions

View File

@@ -1828,6 +1828,97 @@ plt.tight_layout()
plt.show()
##
# %% name
import pandas as pd
import matplotlib.pyplot as plt
import os
import numpy as np
# --- Configuration & Theme ---
plt.rcParams['font.family'] = 'Arial'
figure_save_path = 'project/visuals/functional_systems_magnitude_focus.svg'
# --- 1. Process Error Data with Magnitude Breakdown ---
system_names = [name.split('.')[1] for name, _ in functional_systems_to_plot]
plot_list = []
for gt_col, res_col in functional_systems_to_plot:
sys_name = gt_col.split('.')[1]
# Robust parsing
gt = df[gt_col].apply(safe_parse)
res = df[res_col].apply(safe_parse)
error = res - gt
# Granular Counts
matches = (error == 0).sum()
u_1 = (error == -1).sum()
u_2plus = (error <= -2).sum()
o_1 = (error == 1).sum()
o_2plus = (error >= 2).sum()
total = error.dropna().count()
divisor = max(total, 1)
plot_list.append({
'System': sys_name.replace('_', ' ').title(),
'Matches': matches, 'MatchPct': (matches / divisor) * 100,
'U1': u_1, 'U2': u_2plus, 'UnderTotal': u_1 + u_2plus,
'UnderPct': ((u_1 + u_2plus) / divisor) * 100,
'O1': o_1, 'O2': o_2plus, 'OverTotal': o_1 + o_2plus,
'OverPct': ((o_1 + o_2plus) / divisor) * 100
})
stats_df = pd.DataFrame(plot_list)
# --- 2. Plotting ---
fig, ax = plt.subplots(figsize=(13, 8))
# Define Magnitude Colors
c_under_dark, c_under_light = '#C0392B', '#E74C3C' # Dark Red (-2+), Soft Red (-1)
c_over_dark, c_over_light = '#2980B9', '#3498DB' # Dark Blue (+2+), Soft Blue (+1)
bar_height = 0.6
y_pos = np.arange(len(stats_df))
# Plot Under-scored (Stacked: -2+ then -1)
ax.barh(y_pos, -stats_df['U2'], bar_height, color=c_under_dark, label='Under -2+', edgecolor='white')
ax.barh(y_pos, -stats_df['U1'], bar_height, left=-stats_df['U2'], color=c_under_light, label='Under -1', edgecolor='white')
# Plot Over-scored (Stacked: +1 then +2+)
ax.barh(y_pos, stats_df['O1'], bar_height, color=c_over_light, label='Over +1', edgecolor='white')
ax.barh(y_pos, stats_df['O2'], bar_height, left=stats_df['O1'], color=c_over_dark, label='Over +2+', edgecolor='white')
# --- 3. Aesthetics & Table Labels ---
for i, row in stats_df.iterrows():
label_text = (
f"$\\mathbf{{{row['System']}}}$\n"
f"Match: {int(row['Matches'])} ({row['MatchPct']:.1f}%)\n"
f"Under: {int(row['UnderTotal'])} ({row['UnderPct']:.1f}%) | Over: {int(row['OverTotal'])} ({row['OverPct']:.1f}%)"
)
# Position table text to the left
ax.text(ax.get_xlim()[0] - 0.5, i, label_text, va='center', ha='right', fontsize=9, color='#333333', linespacing=1.4)
# Formatting
ax.axvline(0, color='black', linewidth=1.2)
ax.set_yticks([])
ax.set_xlabel('Number of Patients with Error', fontsize=11, fontweight='bold')
#ax.set_title('Directional Error Magnitude (Under vs. Over Scoring)', fontsize=14, pad=35)
# Absolute X-axis labels
ax.set_xticklabels([int(abs(tick)) for tick in ax.get_xticks()])
# Remove spines and add grid
for spine in ['top', 'right', 'left']: ax.spines[spine].set_visible(False)
ax.xaxis.grid(True, linestyle='--', alpha=0.3)
# Legend with magnitude info
ax.legend(loc='upper right', frameon=False, bbox_to_anchor=(1, 1.1), ncol=2)
plt.tight_layout()
plt.show()
##
# %% test
# Diagnose: what are the actual differences?
print("\n🔍 Raw differences (first 5 rows per system):")