{"spec_id":"line-markers","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' line-markers: Line Plot with Markers\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 84/100 | Created: 2026-09-05\n\nlibrary(ggplot2)\nlibrary(tibble)\nlibrary(ragg)\n\nset.seed(42)\n\n# --- Theme tokens -----------------------------------------------------------\nTHEME       <- Sys.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG     <- if (THEME == \"light\") \"#FAF8F1\" else \"#1A1A17\"\nINK         <- if (THEME == \"light\") \"#1A1A17\" else \"#F0EFE8\"\nINK_SOFT    <- if (THEME == \"light\") \"#4A4A44\" else \"#B8B7B0\"\n\n# Imprint palette (see prompts/default-style-guide.md \"Categorical Palette\")\nIMPRINT_PALETTE <- c(\n  \"#009E73\",  # 1 — brand green, always first series\n  \"#4467A3\"   # 3 — blue, second series\n)\n\n# --- Data ---------------------------------------------------------------\n# Quality-control inspection: diameter readings (mm) of a machined part,\n# sampled once per shift across two production lines.\nshift <- 1:16\n\nline_a <- 24.98 + cumsum(rnorm(16, mean = 0, sd = 0.015)) +\n  rnorm(16, mean = 0, sd = 0.01)\nline_b <- 25.02 + cumsum(rnorm(16, mean = 0, sd = 0.015)) +\n  rnorm(16, mean = 0, sd = 0.01)\n\nn_shifts <- length(shift)\ndf <- tibble(\n  shift = rep(shift, 2),\n  diameter = c(line_a, line_b),\n  production_line = factor(rep(c(\"Line A\", \"Line B\"), each = n_shifts))\n)\n\n# Lines converge around shift 6 (diameters within 0.004mm) before diverging —\n# call out the crossover as the chart's focal point.\ncross_shift <- 6\ncross_y <- mean(c(line_a[cross_shift], line_b[cross_shift]))\n\n# --- Plot -----------------------------------------------------------------\ntitle_text <- \"line-markers · r · ggplot2 · anyplot.ai\"\n\np <- ggplot(df, aes(x = shift, y = diameter, color = production_line, shape = production_line, fill = production_line)) +\n  geom_line(linewidth = 1.0) +\n  geom_point(size = 3.2, stroke = 1.1) +\n  annotate(\n    \"point\", x = cross_shift, y = cross_y,\n    shape = 1, size = 7, stroke = 0.8, color = INK_SOFT\n  ) +\n  annotate(\n    \"text\", x = cross_shift, y = cross_y - 0.05,\n    label = \"Lines converge\", color = INK_SOFT, size = 2.6, vjust = 1\n  ) +\n  scale_color_manual(values = IMPRINT_PALETTE) +\n  scale_fill_manual(values = c(IMPRINT_PALETTE[1], PAGE_BG)) +\n  scale_shape_manual(values = c(21, 24)) +\n  scale_x_continuous(breaks = shift) +\n  labs(\n    title = title_text,\n    x = \"Inspection Shift\",\n    y = \"Part Diameter (mm)\",\n    color = \"Production Line\",\n    shape = \"Production Line\",\n    fill = \"Production Line\"\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.y = element_line(color = INK, linewidth = 0.25),\n    panel.grid.major.x = element_blank(),\n    panel.grid.minor  = element_blank(),\n    axis.title        = element_text(color = INK, size = 10),\n    axis.text         = element_text(color = INK_SOFT, size = 8),\n    axis.ticks        = element_blank(),\n    plot.title        = element_text(color = INK, size = 12, face = \"plain\", margin = margin(b = 4)),\n    plot.margin       = margin(t = 6, r = 10, b = 6, l = 6),\n    legend.position   = \"top\",\n    legend.margin     = margin(t = 0, b = 0),\n    legend.box.spacing = unit(2, \"pt\"),\n    legend.title      = element_blank(),\n    legend.text       = element_text(color = INK_SOFT, size = 8),\n    legend.background = element_rect(fill = PAGE_BG, color = NA),\n    legend.key        = element_rect(fill = PAGE_BG, color = NA)\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"}