## ----setup, include = FALSE--------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ## ----------------------------------------------------------------------------- library(ggspec) library(ggplot2) library(dplyr) ## ----------------------------------------------------------------------------- # Global aes — canonical form p_global <- ggplot(airquality, aes(x = Day, y = Wind)) + geom_line() + geom_point() # All aesthetics local to each layer p_local <- ggplot(airquality) + geom_line(aes(x = Day, y = Wind)) + geom_point(aes(x = Day, y = Wind)) # Mixed: global x, local y per layer p_mixed <- ggplot(airquality, aes(x = Day)) + geom_line(aes(y = Wind)) + geom_point(aes(y = Wind)) ## ----------------------------------------------------------------------------- equiv_plot(p_global, p_local, check = c("layers", "aes")) equiv_plot(p_global, p_mixed, check = c("layers", "aes")) ## ----------------------------------------------------------------------------- # Global data p_data_global <- ggplot(airquality, aes(x = Day, y = Wind)) + geom_line() + geom_point() # Per-layer data p_data_local <- ggplot() + geom_line(aes(x = Day, y = Wind), data = airquality) + geom_point(aes(x = Day, y = Wind), data = airquality) ## ----------------------------------------------------------------------------- equiv_plot(p_data_global, p_data_local, check = c("layers", "aes")) ## ----------------------------------------------------------------------------- p_point_line <- ggplot(airquality, aes(Day, Wind)) + geom_point() + geom_line() p_line_point <- ggplot(airquality, aes(Day, Wind)) + geom_line() + geom_point() # Subset check: passes regardless of order equiv_layers(p_point_line, p_line_point) # Exact check: fails without canonicalisation equiv_layers(p_point_line, p_line_point, exact = TRUE) # Structural mode sorts layers, so exact check passes compare_plots(p_point_line, p_line_point, mode = "structural", check = "layers") ## ----------------------------------------------------------------------------- p_ref <- ggplot(mpg, aes(x = class)) + geom_bar() p_loc <- ggplot(mpg) + geom_bar(aes(x = class)) equiv_plot(p_ref, p_loc, check = c("layers", "aes")) ## ----------------------------------------------------------------------------- counts <- count(mpg, class) p_identity <- ggplot(counts, aes(x = class, y = n)) + geom_bar(stat = "identity") + labs(y = "n") equiv_plot(p_ref, p_identity, check = c("layers", "aes")) ## ----------------------------------------------------------------------------- p_col <- ggplot(counts, aes(x = class, y = n)) + geom_col() + labs(y = "n") # Direct comparison fails on the layer check: equiv_plot(p_ref, p_col, check = "layers") # Structural mode applies .rule_geom_col_to_bar, normalising "col" → "bar": compare_plots(p_ref, p_col, mode = "structural", check = "layers") ## ----------------------------------------------------------------------------- p_flip <- ggplot(mpg, aes(y = class)) + geom_bar() + coord_flip() # Direct aes check fails: equiv_plot(p_ref, p_flip, check = "aes") # Visual mode applies .rule_coord_flip, swapping x <-> y and replacing # coord_flip with coord_cartesian before comparison: compare_plots(p_ref, p_flip, mode = "visual", check = c("layers", "aes", "coord")) ## ----------------------------------------------------------------------------- p_scale_name <- ggplot(counts, aes(x = class, y = n)) + geom_bar(stat = "identity") + scale_y_continuous(name = "count") p_labs <- ggplot(counts, aes(x = class, y = n)) + geom_bar(stat = "identity") + labs(y = "count") # Visual mode applies .rule_scale_name_to_labels, promoting the scale name # into the labels table: compare_plots(p_labs, p_scale_name, mode = "visual", check = "labels") ## ----------------------------------------------------------------------------- p_count_global <- ggplot(mpg, aes(x = drv, y = class)) + geom_count() p_count_local <- ggplot(mpg) + geom_count(aes(x = drv, y = class)) p_count_split <- ggplot(mpg, aes(x = drv)) + geom_count(aes(y = class)) equiv_plot(p_count_global, p_count_local, check = c("layers", "aes")) equiv_plot(p_count_global, p_count_split, check = c("layers", "aes")) ## ----------------------------------------------------------------------------- mpg_counts <- count(mpg, drv, class) p_point_sized <- ggplot(mpg_counts, aes(x = drv, y = class, size = n)) + geom_point() # Fails: reference has geom "count", observation has geom "point" equiv_plot(p_count_global, p_point_sized, check = "layers") ## ----------------------------------------------------------------------------- p_hist_default <- ggplot(mpg, aes(x = hwy)) + geom_histogram() p_hist_bins30 <- ggplot(mpg, aes(x = hwy)) + geom_histogram(bins = 30) p_hist_binwidth <- ggplot(mpg, aes(x = hwy)) + geom_histogram(binwidth = 3) equiv_plot(p_hist_default, p_hist_bins30, check = c("layers", "aes")) equiv_plot(p_hist_default, p_hist_binwidth, check = c("layers", "aes")) ## ----------------------------------------------------------------------------- # Reference has no explicit bins; observation has bins = 30 — params differ equiv_params(p_hist_default, p_hist_bins30, layer = 1L, params = "bins")