Slogan: Focus on the Why, forget the How.
yplot is an R package that implements a universal grammar of graphics, decoupled from the rendering backend. It allows you to define what you want to see (the Why) and lets the backend handle how to draw it.
Most plotting libraries are tightly coupled to their rendering engine. ggplot2 is tied to grid. Base plot is tied to graphics. yplot separates the specification of the plot (the Intermediate Representation) from the rendering.
This architecture allows:
- Portability: The same plot code can render to a static image (Base/Grid) or an interactive web visualization (D3/Vega).
- Extensibility: New backends can be added without changing the user API.
- Clarity: Users focus on data mapping, not drawing commands.
- Modern Syntax: Uses the native pipe
|>for composing layers, distinct fromggplot2's+.
# Not yet on CRAN
# install.packages("yplot")The API is inspired by the Grammar of Graphics but designed for the pipe era.
library(yplot)
# Define the plot (The Why)
# Note: Functions are prefixed with y_ to avoid conflicts with ggplot2
# Note: Uses |> pipe instead of +
p <- yplot(mtcars, y_aes(x = wt, y = mpg)) |>
y_point(color = "red") |>
y_line(color = "blue")
# Mapped aesthetics + scale
p2 <- yplot(mtcars, y_aes(x = wt, y = mpg, colour = factor(cyl))) |>
y_point() |>
y_scale_color_discrete()
# Render using Base Graphics (The How)
print(p, backend = "base")
# Render using Grid Graphics
print(p, backend = "grid")
# Render to D3 (JSON Spec)
print(p, backend = "d3")
# Export to files
y_save(p, "plot.pdf", backend = "base")
y_save(p, "plot.html", backend = "d3", open = FALSE)
yplot_register_backend("txt", list(
render = function(plot, file = NULL, open = FALSE, ...) {
if (is.null(file)) stop("file is required")
n_layers <- if (is.null(plot$layers)) 0 else length(plot$layers)
writeLines(paste0("layers: ", n_layers), file)
file
}
))
y_save(p, "plot.txt", backend = "txt", open = FALSE)
# Optional: build once, render many
built <- y_build(p)
render_base(built)
render_grid(built)
render_d3(built, file = "plot.html", open = FALSE)- Frontend:
yplot(),y_aes(),y_point()create ayplotobject (a structured list). - IR: The
yplotobject acts as an Intermediate Representation. - Backends:
render_base(): Usesgraphics::plot,graphics::points.render_grid(): Usesgrid::grid.points,grid::grid.lines.render_d3(): Outputs JSON for D3.js (Prototype).
- Core Architecture & IR
- Base Graphics Backend
- Grid Graphics Backend
- Pipe-based API (
|>) - Stats & position (histogram, smooth, jitter)
- Facets & coords (facet_wrap, coord_cartesian)
- Backend plugin system (register custom renderers)
- Complete D3/Web Backend
- Minimal scales & guides (colour/size/alpha)
- Minimal theme (axis sizes, panel background/border)
- Themes support
- Statistical Transformations (
stat_*)