{"spec_id":"scatter-regression-lowess","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' scatter-regression-lowess: Scatter Plot with LOWESS Regression\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 90/100 | Created: 2026-09-09\n\nlibrary(ggplot2)\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_PALETTE <- c(\n  \"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\",\n  \"#AE3030\", \"#2ABCCD\", \"#954477\", \"#99B314\"\n)\nBRAND <- IMPRINT_PALETTE[1]\n\n# ggplot2 doesn't expose an alpha channel for grid-line color directly, so\n# fade the grid by blending INK toward PAGE_BG instead of using full-opacity\n# ink (keeps gridlines subtle behind the scatter/LOWESS curve).\nblend_toward_bg <- function(fg, bg, amount) {\n  mixed <- col2rgb(fg) * amount + col2rgb(bg) * (1 - amount)\n  rgb(mixed[1, ], mixed[2, ], mixed[3, ], maxColorValue = 255)\n}\nGRID_COLOR <- blend_toward_bg(INK, PAGE_BG, 0.2)\n\n# --- Data ----------------------------------------------------------------\n# Enzyme activity across a temperature range: activity rises as the enzyme\n# warms toward its optimum, then collapses once heat denatures the protein.\n# This non-monotonic dose-response curve is exactly the case LOWESS is built\n# for, since a single polynomial or linear fit cannot follow the rise-then-\n# fall shape.\nn <- 220\ntemperature_c <- runif(n, 10, 70)\noptimum <- 42\ntrue_activity <- 100 * exp(-((temperature_c - optimum)^2) / (2 * 11^2))\nenzyme_activity <- pmax(0, true_activity + rnorm(n, mean = 0, sd = 9))\n\ndf <- tibble::tibble(\n  temperature_c   = temperature_c,\n  enzyme_activity = enzyme_activity\n)\n\n# --- Plot ------------------------------------------------------------------\np <- ggplot(df, aes(x = temperature_c, y = enzyme_activity)) +\n  geom_point(color = BRAND, size = 2.5, alpha = 0.55) +\n  geom_smooth(\n    method = \"loess\", span = 0.4, se = TRUE,\n    color = IMPRINT_PALETTE[2], fill = IMPRINT_PALETTE[2],\n    linewidth = 1.1, alpha = 0.18\n  ) +\n  labs(\n    title = \"scatter-regression-lowess · r · ggplot2 · anyplot.ai\",\n    x = \"Incubation Temperature (°C)\",\n    y = \"Enzyme Activity (% of maximum)\"\n  ) +\n  theme_minimal(base_size = 8) +\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 = GRID_COLOR, linewidth = 0.3),\n    panel.grid.minor   = element_line(color = GRID_COLOR, linewidth = 0.2),\n    axis.line.x.bottom = element_line(color = INK_SOFT),\n    axis.line.x.top    = element_blank(),\n    axis.line.y.left   = element_line(color = INK_SOFT),\n    axis.line.y.right  = element_blank(),\n    axis.title         = element_text(color = INK, size = 10),\n    axis.text          = element_text(color = INK_SOFT, size = 8),\n    plot.title         = element_text(color = INK, size = 12)\n  )\n\n# --- Save --------------------------------------------------------------\nggsave(\n  filename = sprintf(\"plot-%s.png\", THEME),\n  plot     = p,\n  device   = ragg::agg_png,\n  width    = 8,\n  height   = 4.5,\n  units    = \"in\",\n  dpi      = 400\n)\n"}