Getting Started with glyph

library(glyph)

This vignette walks through glyph’s grammar with live, interactive output. Every plot below is a real glyph_spec built with the package and rendered to an actual D3-backed htmlwidget — not a screenshot. Hover, click, brush, and zoom them right here in the page.

One thing worth knowing up front: printing a glyph_spec at the console auto-renders it (like a ggplot2 plot), but that auto-render only fires in an interactive R session. Inside a vignette or pkgdown article the code runs non-interactively, so each example below ends the pipeline with an explicit render() call to produce the widget.

All examples use mtcars so you can copy-paste and run them yourself.

1. Tooltips and hover, declared in the pipeline

Interactivity is grammar, not glue. interact() turns on tooltips and a hover effect right where the plot is built, and titles() adds a title in the same pipe — no ggplotly() conversion step, no lost formatting.

glyph(mtcars, x = wt, y = mpg) |>
  mark_point(color = cyl) |>
  interact(tooltip = TRUE, hover = "enlarge") |>
  titles(title = "Motor Trend Cars") |>
  render()

Hover over a point to see it enlarge; pause on it to see the tooltip.

2. Animated bar chart

animate() declares a transition as part of the spec. stagger offsets each bar’s entrance animation so they draw in sequence rather than all at once.

glyph(mtcars, x = cyl, y = mpg) |>
  mark_bar() |>
  animate(transition = "slide", stagger = 50) |>
  render()

Reload this page (or re-run the chunk in an R session) to see the bars slide in.

3. Token-based dark theme

Instead of ggplot2’s dozens of individual theme() arguments, theme_tokens() takes a small preset (or individual tokens like bg, font, accent) and cascades foreground, grid, and title colors automatically for contrast.

glyph(mtcars, x = wt, y = mpg) |>
  mark_point(color = cyl) |>
  interact(tooltip = TRUE) |>
  theme_tokens(preset = "dark") |>
  titles(title = "Dark Theme Example") |>
  render()

4. Point labels with automatic collision avoidance

mark_text() draws a label per point, and smart_repel = TRUE nudges overlapping labels apart so they stay readable — a first-class feature instead of a separate ggrepel dependency. mtcars stores car names as row names, so we promote them to a real column first.

mtcars_named <- data.frame(model = rownames(mtcars), mtcars, row.names = NULL)

glyph(mtcars_named, x = wt, y = mpg) |>
  mark_point(color = cyl) |>
  mark_text(label = model, smart_repel = TRUE) |>
  render()

5. Linked panels with crossfilter brushing

compose() arranges multiple glyph_spec objects into a single layout — here, two scatterplots side by side — without reaching for patchwork or cowplot. With interact(brush = TRUE) on each panel and linked_selections = TRUE on the composed layout, brushing points in one panel highlights the same rows in the other.

p1 <- glyph(mtcars, x = wt, y = mpg) |>
  mark_point(color = cyl) |>
  interact(brush = TRUE)

p2 <- glyph(mtcars, x = hp, y = mpg) |>
  mark_point(color = cyl) |>
  interact(brush = TRUE)

compose(p1, p2, type = "hstack", linked_selections = TRUE) |>
  render()

Drag a rectangle over a few points in either panel — the corresponding cars highlight in both.

6. Faceting

facet() splits a plot into small multiples by one or two variables, each with its own panel — like ggplot2’s facet_wrap(), built into the same pipeline instead of a separate layer.

glyph(mtcars, x = wt, y = mpg) |>
  mark_point(color = cyl) |>
  facet(cols = cyl) |>
  render()

7. Marginal distributions

marginals() adds histograms, density curves, or boxplots along the axes — a common pattern that normally needs ggExtra or manual grid manipulation in ggplot2.

glyph(mtcars, x = wt, y = mpg) |>
  mark_point(color = cyl) |>
  marginals(x = "histogram", y = "density") |>
  render()

8. Inset plots

inset() places a second, smaller glyph_spec inside a corner of the main plot — useful for a detail view or a different breakdown of the same data, without any manual viewport math.

main_plot <- glyph(mtcars, x = wt, y = mpg) |> mark_point(color = cyl)
detail_plot <- glyph(mtcars, x = cyl, y = mpg) |> mark_bar()

inset(main_plot, detail_plot, position = "top-right") |>
  render()

9. Keyframe (“morph”) animation

animate(by = ..., transition = "morph") cycles the plot through subsets of the data grouped by a field, transitioning marks smoothly between states — similar in spirit to gganimate::transition_states(), but with a built-in play/pause control and no rendering-to-GIF step.

glyph(mtcars, x = wt, y = mpg) |>
  mark_point(size = hp, color = cyl) |>
  animate(by = gear, transition = "morph", duration = 800) |>
  render()

Use the play/pause button to step through each gear group.

Where to next