A parametric curve plot visualizes x(t) and y(t) as functions of a parameter t, tracing smooth curves in 2D space. Unlike standard function plots where y = f(x), parametric curves can loop, self-intersect, and form closed shapes such as Lissajous figures, spirals, and cardioids. This makes them essential for representing trajectories, oscillations, and classical mathematical curves that cannot be expressed as single-valued functions.

#' anyplot.ai
#' line-parametric: Parametric Curve Plot
#' Library: ggplot2 3.5.1 | R 4.4.1
#' Quality: 90/100 | Created: 2026-06-20
library(ggplot2)
library(dplyr)
library(ragg)
set.seed(42)
# Theme tokens
THEME <- Sys.getenv("ANYPLOT_THEME", "light")
PAGE_BG <- if (THEME == "light") "#FAF8F1" else "#1A1A17"
ELEVATED_BG <- if (THEME == "light") "#FFFDF6" else "#242420"
INK <- if (THEME == "light") "#1A1A17" else "#F0EFE8"
INK_SOFT <- if (THEME == "light") "#4A4A44" else "#B8B7B0"
IMPRINT_PALETTE <- c(
"#009E73", # 1 — brand green (first series)
"#C475FD", # 2 — lavender
"#4467A3", # 3 — blue
"#BD8233", # 4 — ochre
"#AE3030", # 5 — matte red
"#2ABCCD", # 6 — cyan
"#954477", # 7 — rose
"#99B314" # 8 — lime
)
# Data
n <- 1200
# Lissajous figure: x = sin(3t), y = sin(2t) for t in [0, 2pi]
t_liss <- seq(0, 2 * pi, length.out = n)
df_liss <- data.frame(
t_norm = (t_liss - min(t_liss)) / diff(range(t_liss)),
x = sin(3 * t_liss),
y = sin(2 * t_liss),
curve = "Lissajous (3:2)"
)
# Archimedean spiral: x = t*cos(t), y = t*sin(t) for t in [0, 4pi]
t_sprl <- seq(0, 4 * pi, length.out = n)
df_sprl <- data.frame(
t_norm = (t_sprl - min(t_sprl)) / diff(range(t_sprl)),
x = t_sprl * cos(t_sprl),
y = t_sprl * sin(t_sprl),
curve = "Archimedean Spiral"
)
df <- rbind(df_liss, df_sprl)
df$curve <- factor(df$curve, levels = c("Lissajous (3:2)", "Archimedean Spiral"))
# Start and end markers per curve
start_pts <- df %>% group_by(curve) %>% slice(1) %>% ungroup()
end_pts <- df %>% group_by(curve) %>% slice(n()) %>% ungroup()
# Plot
p <- ggplot(df, aes(x = x, y = y, color = t_norm)) +
geom_path(linewidth = 0.9) +
geom_point(
data = start_pts,
aes(x = x, y = y),
inherit.aes = FALSE,
color = IMPRINT_PALETTE[1],
size = 3.5,
shape = 19
) +
geom_point(
data = end_pts,
aes(x = x, y = y),
inherit.aes = FALSE,
color = IMPRINT_PALETTE[3],
size = 3.5,
shape = 15
) +
scale_color_gradient(
low = "#009E73",
high = "#4467A3",
name = "t (0 to 1)"
) +
facet_wrap(~curve, scales = "free") +
labs(
title = "line-parametric · r · ggplot2 · anyplot.ai",
x = "x(t)",
y = "y(t)",
caption = "● start (t = 0) ■ end (t = max)"
) +
theme_minimal(base_size = 8) +
theme(
plot.background = element_rect(fill = PAGE_BG, color = PAGE_BG),
panel.background = element_rect(fill = PAGE_BG, color = NA),
panel.grid.major = element_line(
color = adjustcolor(INK, alpha.f = 0.12),
linewidth = 0.3
),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
axis.title = element_text(color = INK, size = 10),
axis.text = element_text(color = INK_SOFT, size = 8),
axis.line = element_line(color = INK_SOFT, linewidth = 0.4),
plot.title = element_text(color = INK, size = 12,
margin = margin(b = 10)),
plot.caption = element_text(color = INK_SOFT, size = 8,
hjust = 0, margin = margin(t = 8)),
legend.background = element_rect(fill = ELEVATED_BG, color = INK_SOFT,
linewidth = 0.3),
legend.text = element_text(color = INK_SOFT, size = 8),
legend.title = element_text(color = INK, size = 10),
legend.key.width = unit(1.2, "cm"),
strip.text = element_text(color = INK, size = 10, face = "bold",
margin = margin(b = 6)),
strip.background = element_blank(),
aspect.ratio = 1
)
# Save
ggsave(
filename = sprintf("plot-%s.png", THEME),
plot = p,
device = ragg::agg_png,
width = 8,
height = 4.5,
units = "in",
dpi = 400
)
Part of Parametric Curve Plot on anyplot.ai.