What’s New in TidierPlots.jl (2025)

Randall Boyes

About Me

  • Epidemiologist (Former?)
  • Currently: Analytics at Presage Group

Thanks to contributors

  • Karandeep Singh - Tidier
  • Alex Knudson - Documentation
  • Connor Robertson - Patchwork, Labels
  • Daniel Rizk - Documentation, geom_jitter
  • Pavel Dimens - Logo Design
  • Jeffrey Chandler - geom_density_2d + friends
  • Robert Gregg - Project.toml tweaks
  • You?

The “tidyverse”

  • The best reason to still use R
  • Comprehensive, connected set of packages for reading, wrangling, and visualizing data

Tidier.jl

  • 100% Julia reimplementation of R’s tidyverse
    • TidierData.jl - dplyr/tidyr
    • TidierDB.jl - dbplyr (Tomorrow 1:40 Main Stage)
    • TidierPlots.jl - ggplot2
  • See more tomorrow at the “State of Tidier.jl” talk (Tomorrow 2:30 Main Stage)!

Brief Introduction to ggplot

  • “Part of” the tidyverse
  • Data visualization
  • Based on grammar of graphics

library(ggplot2)

ggplot(mpg, aes(x = displ, y = hwy, colour = class)) + 
  geom_point()

library(ggplot2)

ggplot(mpg, aes(x = displ, y = hwy, colour = class)) + 
  geom_point() + geom_line()

library(ggplot2)

ggplot(mpg, aes(x = displ, y = hwy, colour = class)) + 
  geom_point() + theme_classic()

How does it work?

TidierPlots.jl provides:

  • A set of structs corresponding to ggplot concepts (GGPlot, Geom, Aes, etc.)
  • Functions that look like ggplot functions that generate those structs
  • Definitions for operators using those structs (+)
  • A way to translate all of this to Makie.SpecApi

What can it do?

ggplot(df) + 
    geom_point(
        aes(x = :x, y = :y, size = :size, color = :x), 
        alpha = 0.8) +
    scale_x_log10() + scale_y_log10() + 
    labs(x = "x", y = "y") + lims(y = c(.1, 100)) +
    scale_color_continuous(palette = "Hiroshige", name = "") + theme

What can it do?

grid = ggplot(df) + theme .+ 
[geom_histogram(aes(x = :x),
    color = (:orangered, 0.5), 
    strokewidth = 0.5) +
    lims(x = c(-4, 4)),
blank,
geom_histogram(aes(:y), 
    color = (:dodgerblue, 0.5), 
    direction = :x, 
    strokewidth = 0.5) + 
    lims(y = c(-3, 3)),
geom_point(aes(:x, :y), size = 10) +
lims(x = c(-4, 4), y = c(-3, 3)) + 
    labs(x = "x", y = "y")]
+(grid...)

Goals from last year

[ ] Fix aes operations

[ ] scale_fill and scale_alpha

[ ] facet_grid

[ ] More comprehensive documentation and tutorials

Flying too close to the sun

  • ggplot allows calculated columns to be created within an aes call
  • Implemented the closest syntax to this:
ggplot(data) + geom_point(aes(x = :x/10))
  • By defining:
Base.:/(s1::Symbol, s2::Real) = [s1] => AesTransform(make_div_const_fn(s2))

You wouldn’t pirate a type

New syntax options:

“DataFrames-style”

aes(x = :x => x -> x/10)

“TidierData-style”

@aes(x = x/10)

In the background, these both resolve to the same Aes struct.

Goals from last year

[x] Fix aes operations

[ ] scale_fill and scale_alpha

[ ] facet_grid

New Scales

plot +
@aes(fill = bill_depth_mm)) + 
scale_fill_continuous()

plot +
@aes(alpha = bill_depth_mm)) + 
scale_alpha_continuous()

Goals from last year

[x] Fix aes operations

[x] scale_fill and scale_alpha

[ ] facet_grid

Facet Grids

plot + facet_grid(rows = :sex, cols = :species)

Goals from last year

[x] Fix aes operations

[x] scale_fill and scale_alpha

[x] facet_grid

Benefits over ggplot

  • Access to Makie’s theming/options
  • Pluto notebook interactivity
  • No more dealing with R’s handling of fonts and plot scaling

Towards v1.0

  • More complete documentation
  • Bug fixes
  • More geoms!

Towards v1.0

geom_raincloud = geom_template(
    "geom_raincloud", 
    ["x", "y"], 
    :RainClouds)

ggplot(penguins) + 
    geom_raincloud(
        aes(x = :species,
            y = :bill_depth_mm,
            color = :species), 
        size = 4) +
    scale_y_continuous(
        labels = "{:.1f} cm") + 
    labs(title = "Bill Depth by Species",
         x = "Species",
         y = "Bill Depth") +
    theme_minimal()

Thanks!

  • Questions?
  • github.com/TidierOrg/TidierPlots.jl
  • bluesky: @randy.pub