{"spec_id":"logistic-regression","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' logistic-regression: Logistic Regression Curve Plot\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 89/100 | Created: 2026-05-18\n\nlibrary(ggplot2)\nlibrary(dplyr)\nlibrary(ragg)\n\nset.seed(42)\n\n# --- Theme tokens -----------------------------------------------------------\nTHEME       <- Sys.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG     <- if (THEME == \"light\") \"#FAF8F1\" else \"#1A1A17\"\nELEVATED_BG <- if (THEME == \"light\") \"#FFFDF6\" else \"#242420\"\nINK         <- if (THEME == \"light\") \"#1A1A17\" else \"#F0EFE8\"\nINK_SOFT    <- if (THEME == \"light\") \"#4A4A44\" else \"#B8B7B0\"\nIMPRINT   <- c(\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\",\n                 \"#AE3030\", \"#2ABCCD\", \"#954477\")\n\n# --- Data -------------------------------------------------------------------\n# Medical diagnostic context: biomarker level predicts disease probability\nn <- 150\nbiomarker <- rnorm(n, mean = 5, sd = 2)\n# Logistic function: P(disease) = 1 / (1 + exp(-(intercept + slope*biomarker)))\ntrue_prob <- 1 / (1 + exp(-(0.8 * biomarker - 2)))\ndisease <- rbinom(n, size = 1, prob = true_prob)\n\n# Fit logistic regression\nmodel <- glm(disease ~ biomarker, family = binomial(link = \"logit\"))\n\n# Generate prediction data for smooth curve\nbiomarker_range <- seq(min(biomarker) - 0.5, max(biomarker) + 0.5, length.out = 300)\npred_data <- data.frame(biomarker = biomarker_range)\npred <- predict(model, newdata = pred_data, type = \"response\", se.fit = TRUE)\n\npred_data$probability <- pred$fit\npred_data$se <- pred$se.fit\npred_data$upper <- pmin(pred$fit + 1.96 * pred$se.fit, 1)\npred_data$lower <- pmax(pred$fit - 1.96 * pred$se.fit, 0)\n\n# Prepare data for plotting with jitter on y-axis\nplot_data <- data.frame(\n  biomarker = biomarker,\n  disease = factor(disease, labels = c(\"No Disease\", \"Disease\")),\n  y_jittered = disease + rnorm(n, mean = 0, sd = 0.03)\n)\n\n# --- Plot -------------------------------------------------------------------\np <- ggplot() +\n  # Confidence interval band\n  geom_ribbon(data = pred_data, aes(x = biomarker, ymin = lower, ymax = upper),\n              fill = IMPRINT[1], alpha = 0.15) +\n  # Fitted curve\n  geom_line(data = pred_data, aes(x = biomarker, y = probability),\n            color = IMPRINT[1], linewidth = 1.2) +\n  # Data points colored by class\n  geom_point(data = plot_data, aes(x = biomarker, y = y_jittered, color = disease),\n             size = 3, alpha = 0.65) +\n  # Decision threshold line\n  geom_hline(yintercept = 0.5, linetype = \"dashed\", color = INK_SOFT,\n             linewidth = 0.7) +\n  # Scales\n  scale_color_manual(values = c(IMPRINT[1], IMPRINT[2])) +\n  scale_y_continuous(limits = c(-0.15, 1.15), breaks = seq(0, 1, 0.25)) +\n  # Labels\n  labs(\n    title = \"logistic-regression · r · ggplot2 · anyplot.ai\",\n    x = \"Biomarker Level\",\n    y = \"Probability\",\n    color = \"Status\"\n  ) +\n  # Theme\n  theme_minimal(base_size = 14) +\n  theme(\n    plot.background   = element_rect(fill = PAGE_BG, color = PAGE_BG),\n    panel.background  = element_rect(fill = PAGE_BG, color = NA),\n    panel.grid.major  = element_line(color = INK_SOFT, linewidth = 0.3),\n    panel.grid.minor  = element_blank(),\n    panel.border      = element_rect(color = INK_SOFT, fill = NA, linewidth = 0.5),\n    axis.title        = element_text(color = INK, size = 20),\n    axis.text         = element_text(color = INK_SOFT, size = 16),\n    plot.title        = element_text(color = INK, size = 24, face = \"plain\"),\n    legend.background = element_rect(fill = ELEVATED_BG, color = INK_SOFT, linewidth = 0.5),\n    legend.text       = element_text(color = INK_SOFT, size = 16),\n    legend.title      = element_text(color = INK, size = 18),\n    legend.position   = \"topleft\"\n  )\n\n# --- Save -------------------------------------------------------------------\noutput_file <- sprintf(\"plot-%s.png\", THEME)\nggsave(\n  filename = output_file,\n  plot     = p,\n  device   = ragg::agg_png,\n  width    = 16,\n  height   = 9,\n  units    = \"in\",\n  dpi      = 300\n)\n"}