{"spec_id":"lightcurve-transit","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' lightcurve-transit: Astronomical Light Curve\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 90/100 | Created: 2026-06-20\n\nlibrary(ggplot2)\nlibrary(ragg)\n\nset.seed(42)\n\n# Theme tokens (Imprint palette — see prompts/default-style-guide.md)\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\"\n\nIMPRINT_PALETTE <- c(\n  \"#009E73\",  # 1 — brand green (observed data — always first series)\n  \"#C475FD\",  # 2 — lavender\n  \"#4467A3\",  # 3 — blue (transit model)\n  \"#BD8233\",  # 4 — ochre\n  \"#AE3030\",  # 5 — matte red\n  \"#2ABCCD\",  # 6 — cyan\n  \"#954477\",  # 7 — rose\n  \"#99B314\"   # 8 — lime\n)\n\n# Transit parameters (shared between data generation and plot annotations)\nTRANSIT_CENTER     <- 0.5\nTRANSIT_HALF_FLAT  <- 0.035  # half-duration of flat bottom (phase units)\nTRANSIT_HALF_TOTAL <- 0.050  # half-duration including ingress/egress\nTRANSIT_DEPTH      <- 0.01   # 1% transit depth\n\n# Data: simulated phase-folded exoplanet transit (600 observations)\n# Scenario: Hot Jupiter analog with ~1% transit depth, period ~3.5 days\nn_obs     <- 600\nphase_obs <- runif(n_obs, 0, 1)\n\n# Transit model: flat-bottom shape with smooth quadratic ingress/egress\ntransit_flux <- function(ph) {\n  dp <- ph - TRANSIT_CENTER\n  t  <- abs(dp)\n  ifelse(\n    t <= TRANSIT_HALF_FLAT,\n    1.0 - TRANSIT_DEPTH,\n    ifelse(\n      t <= TRANSIT_HALF_TOTAL,\n      1.0 - TRANSIT_DEPTH * (1 - ((t - TRANSIT_HALF_FLAT) / (TRANSIT_HALF_TOTAL - TRANSIT_HALF_FLAT))^2),\n      1.0\n    )\n  )\n}\n\nmodel_vals <- transit_flux(phase_obs)\nflux_err   <- abs(rnorm(n_obs, mean = 0.00035, sd = 0.00004))\nflux_obs   <- model_vals + rnorm(n_obs, 0, 0.00035)\n\nobs_df <- data.frame(\n  phase    = phase_obs,\n  flux     = flux_obs,\n  flux_err = flux_err\n)\n\n# Dense smooth model curve for overlay\nphase_grid <- seq(0, 1, length.out = 2000)\nmodel_df   <- data.frame(phase = phase_grid, flux = transit_flux(phase_grid))\n\n# Plot\nplot_title <- \"lightcurve-transit · r · ggplot2 · anyplot.ai\"\n\np <- ggplot() +\n  # Ingress/egress shading via annotate() — transit contact points T1-T4\n  annotate(\n    \"rect\",\n    xmin  = c(TRANSIT_CENTER - TRANSIT_HALF_TOTAL, TRANSIT_CENTER + TRANSIT_HALF_FLAT),\n    xmax  = c(TRANSIT_CENTER - TRANSIT_HALF_FLAT,  TRANSIT_CENTER + TRANSIT_HALF_TOTAL),\n    ymin  = -Inf, ymax = Inf,\n    fill  = INK_SOFT, alpha = 0.08\n  ) +\n  # Out-of-transit baseline reference\n  geom_hline(\n    yintercept = 1.0,\n    color      = INK_SOFT,\n    linetype   = \"dashed\",\n    linewidth  = 0.35,\n    alpha      = 0.7\n  ) +\n  geom_errorbar(\n    data = obs_df,\n    aes(x = phase, ymin = flux - flux_err, ymax = flux + flux_err),\n    color     = IMPRINT_PALETTE[1],\n    width     = 0,\n    alpha     = 0.45,\n    linewidth = 0.3\n  ) +\n  geom_point(\n    data = obs_df,\n    aes(x = phase, y = flux, color = \"Observed\"),\n    size  = 1.4,\n    alpha = 0.55\n  ) +\n  geom_line(\n    data = model_df,\n    aes(x = phase, y = flux, color = \"Transit model\"),\n    linewidth = 1.0\n  ) +\n  scale_color_manual(\n    name   = NULL,\n    values = c(\"Observed\" = IMPRINT_PALETTE[1], \"Transit model\" = IMPRINT_PALETTE[3])\n  ) +\n  guides(\n    color = guide_legend(\n      override.aes = list(\n        shape    = c(16, NA),\n        linetype = c(\"blank\", \"solid\")\n      )\n    )\n  ) +\n  scale_x_continuous(\n    name   = \"Orbital Phase\",\n    breaks = seq(0, 1, by = 0.1),\n    expand = c(0.01, 0.01)\n  ) +\n  scale_y_continuous(\n    name   = \"Relative Flux\",\n    labels = function(x) sprintf(\"%.3f\", x)\n  ) +\n  labs(title = plot_title) +\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 = INK,        linewidth = 0.15),\n    panel.grid.minor       = element_blank(),\n    panel.border           = element_blank(),\n    axis.line              = element_line(color = INK_SOFT,   linewidth = 0.4),\n    axis.ticks             = element_line(color = INK_SOFT,   linewidth = 0.3),\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, hjust = 0),\n    legend.background      = element_rect(fill = ELEVATED_BG, color = INK_SOFT, linewidth = 0.3),\n    legend.text            = element_text(color = INK_SOFT,   size = 8),\n    legend.position.inside = c(0.99, 0.04),\n    legend.justification   = c(\"right\", \"bottom\"),\n    plot.margin            = margin(12, 16, 10, 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"}