Adjsuting and cleaning
This commit is contained in:
@@ -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):")
|
||||
|
||||
Reference in New Issue
Block a user