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:
::install_github("trevorld/gridpattern") remotes
library("grid")
library("gridpattern")
<- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6))
x_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) y_hex
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)
<- gpar(fill = c("yellow", "blue", "red"))
gp grid.pattern_polygon_tiling(x_hex, y_hex, type = "truncated_hexagonal",
spacing = 0.15, gp = gp)
<- grDevices::rgb(0.35, 0.70, 0.90)
blue <- grDevices::rgb(0.95, 0.90, 0.25)
yellow <- grDevices::rgb(0.80, 0.40, 0.00)
red <- grDevices::rgb(0.00, 0.60, 0.50)
green grid.rect(gp = gpar(fill = yellow, col = NA))
<- gpar(fill = red, col = "black")
gp 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)
<- gpar(fill = blue, col = "black")
gp grid.pattern_regular_polygon(shape = "convex12", grid = "hex_circle", rot = 15,
density = 0.82, spacing = 0.3, angle = 0, gp = gp)
<- gpar(fill = green, col = "black")
gp <- star_scale(12, 30)
scale grid.pattern_regular_polygon(shape = "star12", grid = "hex_circle", rot = 15,
density = 0.82, spacing = 0.3, angle = 0, gp = gp,
scale = scale)
<- gpar(fill = c("blue", "red", "yellow", "green"), col = "black")
gp 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)
<- c("\u2660", "\u2665", "\u2666", "\u2663")
playing_card_symbols 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")
<- function(params, boundary_df, aspect_ratio,
multicolor_stripe_pattern legend = FALSE) {
<- 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 <- ""
args
do.call(gridpattern::patternGrob, args)
}
options(ggpattern_geometry_funcs = list(multicolor_stripe = multicolor_stripe_pattern))
<- data.frame(trt = c("a", "b", "c"), outcome = c(2.3, 1.9, 3.2))
df 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.
<- function(params, boundary_df, aspect_ratio, legend = FALSE) {
tiling3_pattern <- as.list(params)
args <- args[grep("^pattern_", names(args))]
args
# hexagonal tiling using "regular_polygon" pattern
$pattern <- "polygon_tiling"
args
# three-color tiling using `fill`, `pattern_fill` and their "average"
<- gridpattern::mean_col(params$fill, params$pattern_fill)
avg_col $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 <- ""
args
do.call(gridpattern::patternGrob, args)
}
options(ggpattern_geometry_funcs = list(tiling3 = tiling3_pattern))
<- data.frame(trt = c("a", "b", "c"), outcome = c(2.3, 1.9, 3.2))
df 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")
<- c("hexagonal", "snub_square", "pythagorean",
tilings "truncated_square", "triangular", "trihexagonal")
<- function(piece_side, suit, rank, cfg) {
patternedCheckerGrobFn <- cfg$get_piece_opt(piece_side, suit, rank)
opt <- pp_shape(opt$shape, opt$shape_t, opt$shape_r, opt$back)
shape <- gpar(col=opt$suit_color, fill=c(opt$background_color, "white"))
gp_pattern <- shape$pattern("polygon_tiling", type = tilings[suit],
pattern_grob spacing = 0.3, name = "pattern",
gp = gp_pattern, angle = 0)
<- gpar(col=opt$border_color, fill=NA, lex=opt$border_lex)
gp_border <- shape$shape(gp=gp_border, name = "border")
border_grob grobTree(pattern_grob, border_grob)
}<- as.list(game_systems()$checkers1)
checkers1 $grob_fn.bit <- patternedCheckerGrobFn
checkers1<- pp_cfg(checkers1)
checkers1
<- c(1:3, 1:2, 1)
x1 <- c(6:8, 7:8, 8)
x2 <- tibble::tibble(piece_side = c("board_face", rep_len("bit_back", 24L)),
df 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")