2025-10-22 15:25:58 +08:00
# Plot AUC comparisons (1-year gap) between models and Delphi using ggplot2
# Usage:
# Rscript plot_model_comparison_1year.R [path_to_csv] [output_dir]
# Defaults:
# path_to_csv = "model_comparison_auc_1year.csv"
# output_dir = current working directory (".")
suppressPackageStartupMessages ( {
library ( ggplot2 )
2025-10-22 15:43:16 +08:00
library ( cowplot )
2025-10-22 15:25:58 +08:00
} )
args <- commandArgs ( trailingOnly = TRUE )
csv_path <- if ( length ( args ) >= 1 ) args [1 ] else " model_comparison_auc_1year.csv"
out_dir <- if ( length ( args ) >= 2 ) args [2 ] else " ."
if ( ! dir.exists ( out_dir ) ) {
dir.create ( out_dir , recursive = TRUE , showWarnings = FALSE )
}
# Read data
# Expect columns including: auc_delphi, auc_256, auc_120, Colour (hex color), name, etc.
df <- tryCatch ( {
read.csv ( csv_path , check.names = FALSE )
} , error = function ( e ) {
stop ( sprintf ( " Failed to read CSV at '%s': %s" , csv_path , e $ message ) )
} )
2025-10-22 15:43:16 +08:00
# Helper to compare any two AUC columns (x vs y)
make_xy_plot <- function ( data , x_col , y_col , title_text , x_label , y_label ) {
ggplot ( data , aes ( x = .data [ [x_col ] ] , y = .data [ [y_col ] ] ) ) +
2025-10-22 15:25:58 +08:00
geom_abline ( slope = 1 , intercept = 0 , color = " black" , linetype = " dashed" , linewidth = 0.5 ) +
geom_vline ( xintercept = 0.5 , color = " gray50" , linetype = " dashed" , linewidth = 0.4 ) +
geom_hline ( yintercept = 0.5 , color = " gray50" , linetype = " dashed" , linewidth = 0.4 ) +
geom_point ( aes ( fill = Colour ) , shape = 21 , color = " white" , stroke = 0.65 , size = 2.2 , alpha = 0.95 , show.legend = FALSE ) +
scale_fill_identity ( ) +
coord_cartesian ( xlim = c ( 0.3 , 1.05 ) , ylim = c ( 0.3 , 1.05 ) ) +
coord_fixed ( ratio = 1 ) +
2025-10-22 15:43:16 +08:00
labs ( title = title_text , x = x_label , y = y_label ) +
2025-10-22 15:25:58 +08:00
theme_minimal ( base_size = 10 ) +
theme (
plot.title = element_text ( hjust = 0.5 ) ,
panel.grid.minor = element_blank ( )
)
}
2025-10-22 15:43:16 +08:00
# Helper to compare model AUC vs Delphi AUC (x = auc_delphi)
make_delphi_plot <- function ( data , y_col , title_text , y_label ) {
ggplot ( data , aes ( x = auc_delphi , y = .data [ [y_col ] ] ) ) +
2025-10-22 15:32:02 +08:00
geom_abline ( slope = 1 , intercept = 0 , color = " black" , linetype = " dashed" , linewidth = 0.5 ) +
geom_vline ( xintercept = 0.5 , color = " gray50" , linetype = " dashed" , linewidth = 0.4 ) +
geom_hline ( yintercept = 0.5 , color = " gray50" , linetype = " dashed" , linewidth = 0.4 ) +
geom_point ( aes ( fill = Colour ) , shape = 21 , color = " white" , stroke = 0.65 , size = 2.2 , alpha = 0.95 , show.legend = FALSE ) +
scale_fill_identity ( ) +
coord_cartesian ( xlim = c ( 0.3 , 1.05 ) , ylim = c ( 0.3 , 1.05 ) ) +
coord_fixed ( ratio = 1 ) +
2025-10-22 15:43:16 +08:00
labs ( title = title_text , x = " AUC_Delphi" , y = y_label ) +
2025-10-22 15:32:02 +08:00
theme_minimal ( base_size = 10 ) +
theme (
plot.title = element_text ( hjust = 0.5 ) ,
panel.grid.minor = element_blank ( )
)
}
2025-10-22 15:43:16 +08:00
# Placeholder empty plot if a required column is missing
empty_plot <- function ( msg ) {
ggplot ( ) + theme_void ( ) + ggtitle ( msg ) + theme ( plot.title = element_text ( hjust = 0.5 ) )
2025-10-22 15:25:58 +08:00
}
2025-10-22 15:32:02 +08:00
# Plot: AUC_120 vs AUC_120_L (1 year gap)
if ( ! all ( c ( " auc_120" , " auc_120_l" ) %in% names ( df ) ) ) {
warning ( " Columns 'auc_120' and/or 'auc_120_l' not found in CSV; skipping AUC_120 vs AUC_120_L plot." )
} else {
p120_vs_120l <- make_xy_plot (
data = df ,
x_col = " auc_120" ,
y_col = " auc_120_l" ,
title_text = " AUC_120 vs AUC_120_L 1 year gap" ,
x_label = " AUC_120" ,
y_label = " AUC_120_L"
)
out_120_vs_120l <- file.path ( out_dir , " model_comparison_auc_120_vs_120_l_1year.png" )
ggsave ( filename = out_120_vs_120l , plot = p120_vs_120l , width = 7 , height = 4 , dpi = 600 , bg = " white" )
cat ( sprintf ( " Saved: %s\n" , out_120_vs_120l ) )
}
# Plot: AUC_256 vs AUC_256_L (1 year gap)
if ( ! all ( c ( " auc_256" , " auc_256_l" ) %in% names ( df ) ) ) {
warning ( " Columns 'auc_256' and/or 'auc_256_l' not found in CSV; skipping AUC_256 vs AUC_256_L plot." )
} else {
p256_vs_256l <- make_xy_plot (
data = df ,
x_col = " auc_256" ,
y_col = " auc_256_l" ,
title_text = " AUC_256 vs AUC_256_L 1 year gap" ,
x_label = " AUC_256" ,
y_label = " AUC_256_L"
)
out_256_vs_256l <- file.path ( out_dir , " model_comparison_auc_256_vs_256_l_1year.png" )
ggsave ( filename = out_256_vs_256l , plot = p256_vs_256l , width = 7 , height = 4 , dpi = 600 , bg = " white" )
cat ( sprintf ( " Saved: %s\n" , out_256_vs_256l ) )
}
2025-10-22 15:43:16 +08:00
# ---- Combined 2x2 grid: (auc_120 vs delphi), (auc_256 vs delphi), (auc_120_l vs delphi), (auc_256_l vs delphi) ----
has_cols <- function ( cols ) all ( cols %in% names ( df ) )
p_120_vs_delphi <- if ( has_cols ( c ( " auc_delphi" , " auc_120" ) ) ) make_delphi_plot ( df , " auc_120" , " AUC_120 vs Delphi (1 year)" , " AUC_120" ) else empty_plot ( " Missing auc_120 or auc_delphi" )
p_256_vs_delphi <- if ( has_cols ( c ( " auc_delphi" , " auc_256" ) ) ) make_delphi_plot ( df , " auc_256" , " AUC_256 vs Delphi (1 year)" , " AUC_256" ) else empty_plot ( " Missing auc_256 or auc_delphi" )
p_120l_vs_delphi <- if ( has_cols ( c ( " auc_delphi" , " auc_120_l" ) ) ) make_delphi_plot ( df , " auc_120_l" , " AUC_120_L vs Delphi (1 year)" , " AUC_120_L" ) else empty_plot ( " Missing auc_120_l or auc_delphi" )
p_256l_vs_delphi <- if ( has_cols ( c ( " auc_delphi" , " auc_256_l" ) ) ) make_delphi_plot ( df , " auc_256_l" , " AUC_256_L vs Delphi (1 year)" , " AUC_256_L" ) else empty_plot ( " Missing auc_256_l or auc_delphi" )
grid_plot <- plot_grid (
p_120_vs_delphi , p_256_vs_delphi ,
p_120l_vs_delphi , p_256l_vs_delphi ,
labels = c ( " A" , " B" , " C" , " D" ) ,
ncol = 2 , align = " hv"
)
out_grid <- file.path ( out_dir , " model_comparison_auc_vs_delphi_1year_grid.png" )
ggsave ( filename = out_grid , plot = grid_plot , width = 12 , height = 8 , dpi = 300 , bg = " white" )
cat ( sprintf ( " Saved grid: %s\n" , out_grid ) )