gridpattern
provides grid.pattern() and patternGrob() functions to use with R’s grid graphics system. They fill in a user-specified boundary path with a user-specified pattern. These pattern grobs include enhanced versions of the patterns originally contained within Mike FC’s awesome ggpattern package as well as original “pch”, “polygon_tiling”, “regular_polygon”, “rose”, “text”, “wave”, and “weave” patterns.
{gridpattern}
currently provides {grid}
grob support for the following patterns:
grid::null()
)To install the development version use the following command in R:
library("grid")
library("gridpattern")
x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6))
y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6))
grid.pattern_circle(x_hex, y_hex, density = 0.5, grid = "hex_circle",
fill = c("blue", "yellow", "red"))
grid.pattern_regular_polygon(x_hex, y_hex, shape = c("convex4", "star8", "circle"),
colour = "black", fill = c("blue", "yellow", "red"),
density = c(0.45, 0.42, 0.4), spacing = 0.08, angle = 0)
grid.pattern_regular_polygon(x_hex, y_hex, shape = "convex6", grid = "hex",
color = "transparent", fill = c("white", "grey", "black"),
density = 1.0, spacing = 0.1)
gp <- gpar(fill = c("yellow", "blue", "red"))
grid.pattern_polygon_tiling(x_hex, y_hex, type = "truncated_hexagonal",
spacing = 0.15, gp = gp)
blue <- grDevices::rgb(0.35, 0.70, 0.90)
yellow <- grDevices::rgb(0.95, 0.90, 0.25)
red <- grDevices::rgb(0.80, 0.40, 0.00)
green <- grDevices::rgb(0.00, 0.60, 0.50)
grid.rect(gp = gpar(fill = yellow, col = NA))
gp <- gpar(fill = red, col = "black")
grid.pattern_stripe(grid = "hex_circle", density = 0.25, spacing = 0.3,
angle = 0, gp = gp)
grid.pattern_stripe(grid = "hex_circle", density = 0.25, spacing = 0.3,
angle = -60, gp = gp)
grid.pattern_stripe(grid = "hex_circle", density = 0.25, spacing = 0.3,
angle = 60, gp = gp)
gp <- gpar(fill = blue, col = "black")
grid.pattern_regular_polygon(shape = "convex12", grid = "hex_circle", rot = 15,
density = 0.82, spacing = 0.3, angle = 0, gp = gp)
gp <- gpar(fill = green, col = "black")
scale <- star_scale(12, 30)
grid.pattern_regular_polygon(shape = "star12", grid = "hex_circle", rot = 15,
density = 0.82, spacing = 0.3, angle = 0, gp = gp,
scale = scale)
gp <- gpar(fill = c("blue", "red", "yellow", "green"), col = "black")
grid.newpage()
grid.pattern_rose(x_hex, y_hex,
spacing = 0.18, density = 0.5, angle = 0,
frequency = c(2, 6/4, 5/4, 3/7), gp = gp)
playing_card_symbols <- c("\u2660", "\u2665", "\u2666", "\u2663")
grid.pattern_text(x_hex, y_hex,
shape = playing_card_symbols,
colour = c("black", "red", "red", "black"),
size = 24, spacing = 0.12, angle = 0)
grid.pattern_wave(x_hex, y_hex, colour = "black", type = "sine",
fill = c("red", "blue"), density = 0.4,
spacing = 0.15, angle = 0,
amplitude = 0.05, frequency = 1 / 0.20)
grid.pattern_weave(x_hex, y_hex, type = "satin",
colour = "black", fill = "lightblue", fill2 = "yellow",
density = 0.3)
The patterns provided by gridpattern
can be used to create custom ggpattern geometry-based patterns.
Here is an example of creating a new “multicolor_stripe” pattern that supports comma-separated pattern_fill
and/or pattern_colour
aesthetics:
library("ggpattern") # remotes::install_github("coolbutuseless/ggpattern")
library("ggplot2", warn.conflicts = FALSE)
library("gridpattern")
multicolor_stripe_pattern <- function(params, boundary_df, aspect_ratio,
legend = FALSE) {
args <- as.list(params)
args <- args[grep("^pattern_", names(args))]
args$pattern_colour <- strsplit(args$pattern_colour, ",")[[1]]
args$pattern_fill <- strsplit(args$pattern_fill, ",")[[1]]
args$pattern <- "stripe"
args$x <- boundary_df$x
args$y <- boundary_df$y
args$id <- boundary_df$id
args$prefix <- ""
do.call(gridpattern::patternGrob, args)
}
options(ggpattern_geometry_funcs = list(multicolor_stripe = multicolor_stripe_pattern))
df <- data.frame(trt = c("a", "b", "c"), outcome = c(2.3, 1.9, 3.2))
ggplot(df, aes(trt, outcome)) +
geom_col_pattern(aes(fill = trt), colour = 'black',
pattern = 'multicolor_stripe',
pattern_fill = "grey30,grey70,white,grey70")
And here is an example of creating a “tiling3” pattern that creates three-color polygon tilings using the fill
colour, the pattern_fill
colour, and their “average” color.
tiling3_pattern <- function(params, boundary_df, aspect_ratio, legend = FALSE) {
args <- as.list(params)
args <- args[grep("^pattern_", names(args))]
# hexagonal tiling using "regular_polygon" pattern
args$pattern <- "polygon_tiling"
# three-color tiling using `fill`, `pattern_fill` and their "average"
avg_col <- gridpattern::mean_col(params$fill, params$pattern_fill)
args$pattern_fill <- c(params$fill, avg_col, args$pattern_fill)
args$x <- boundary_df$x
args$y <- boundary_df$y
args$id <- boundary_df$id
args$prefix <- ""
do.call(gridpattern::patternGrob, args)
}
options(ggpattern_geometry_funcs = list(tiling3 = tiling3_pattern))
df <- data.frame(trt = c("a", "b", "c"), outcome = c(2.3, 1.9, 3.2))
ggplot(df, aes(trt, outcome)) +
geom_col_pattern(aes(fill = trt, pattern_type = trt),
pattern = 'tiling3', pattern_angle = 45) +
scale_pattern_type_manual(values = c("hexagonal", "tetrakis_square", "rhombille")) +
theme(legend.key.size = unit(1.5, 'cm'))
piecepackr allows the use of custom grob functions to completely customize the appearance of one’s game pieces. {piecepackr}
comes with a variety of convenience functions such as pp_shape()
to facilitate creating custom game pieces using custom grob functions. Here is an example of creating “patterned” checkers filled with uniform polygon tilings by using pp_shape()
objects’ pattern()
method powered by {gridpattern}
:
library("grid")
library("gridpattern")
library("piecepackr")
tilings <- c("hexagonal", "snub_square", "pythagorean",
"truncated_square", "triangular", "trihexagonal")
patternedCheckerGrobFn <- function(piece_side, suit, rank, cfg) {
opt <- cfg$get_piece_opt(piece_side, suit, rank)
shape <- pp_shape(opt$shape, opt$shape_t, opt$shape_r, opt$back)
gp_pattern <- gpar(col=opt$suit_color, fill=c(opt$background_color, "white"))
pattern_grob <- shape$pattern("polygon_tiling", type = tilings[suit],
spacing = 0.3, name = "pattern",
gp = gp_pattern, angle = 0)
gp_border <- gpar(col=opt$border_color, fill=NA, lex=opt$border_lex)
border_grob <- shape$shape(gp=gp_border, name = "border")
grobTree(pattern_grob, border_grob)
}
checkers1 <- as.list(game_systems()$checkers1)
checkers1$grob_fn.bit <- patternedCheckerGrobFn
checkers1 <- pp_cfg(checkers1)
x1 <- c(1:3, 1:2, 1)
x2 <- c(6:8, 7:8, 8)
df <- tibble::tibble(piece_side = c("board_face", rep_len("bit_back", 24L)),
suit = c(6L, rep(c(1L, 3L, 4L, 5L), each = 6L)),
rank = 8L,
x = c(4.5, x1, rev(x1), x2, rev(x2)),
y = c(4.5, rep(c(1,1,1, 2,2, 3, 6, 7,7, 8,8,8), 2)))
pmap_piece(df, cfg=checkers1, default.units="in")