ingrid
provides some tools that I find useful for creating/manipulating grid
/grob
.
The key benefits I get from ingrid
:
row
and col
- similar to shiny UI definitiongrobs
, gTrees
and polyclipgrobs
print
methods for grobsdefault.units
ig_*()
grob creation functions with inline gpar
specification
ig_circle(r = .mm(10), fill = 'blue')
igc_*()
grob combination operators
igl_*()
layout for multiple grobs
igt_*()
transform operations on grobs
igt_translate()
, igt_rotate()
igt_update()
to update any parameter in the grob or viewportig_circle()
etc. Analoges for the the grob creation functions in the grid
package, but with a slight change in the argument defaults:
gp
and vp
objects are both created as fully realised structures, and no longer left as NULL
if no values are given. This makes manipulation of grob objects a bit easier after they’ve been created.gridGeometry::polyclipgrob()
which extends the operations to recurse into gTree and polyclipgrob structures to affect all child objects:
igc_stack()
for simple combination of shapesigc_intersect()
for shape intersectionigc_union()
for shape unionigc_minus()
for shape subtractionigc_xor()
for shape combination thruogh use of ‘exclusive or’.mm(x)
instead of units(x, 'mm')
vp_translate()
vp_rotate()
gp()
is a wrapper around grid::gpar()
which is more friendly for IDEs which support auto-complete.print
methods with more structured output than grid
’s defaultig_pattern()
is a wrapper around grid::pattern()
where:
extend = 'repeat'
is the default (instead of ‘pad’)default.units
are in ‘mm’ (instead of ‘npc’)centred = FALSE
to disable this behaviour.You can install from GitHub with:
# install.package('remotes')
remotes::install_github('coolbutuseless/ingrid')
ingrid reframes the grid layout functions into nested hierarchical layout functions, somewhat similar to how shiny does it’s UI layout.
igl_row()
will arrange its sub-elements in a horizontal row.igl_col()
will arrange its sub-elements in a vertical column.igl_vp()
will create an arbitrary viewport containing its sub-elements.
check <- igl_row(
igl_col(
ig_rect(fill = 'black'),
nullGrob()
),
igl_col(
nullGrob(),
ig_rect(fill = 'black')
)
)
grid.newpage(); grid.draw(check)
check45 <- igl_vp(check, angle = 45)
grid.newpage(); grid.draw(check45)
demo <- igl_row(
ig_rect (fill = ig_pattern(check , width = .cm(1.5), height = .cm(1.5))),
ig_circle(fill = ig_pattern(check , width = .cm(2.5), height = .cm(2.5))),
ig_rect (fill = ig_pattern(check45, width = .cm(3 ), height = .cm(3 )))
)
grid::grid.newpage(); grid::grid.draw(demo)
Grobs may be combined with igc_*()
functions.
igc_stack()
combines multiple grobs (as a grobTree()
igc_intersetion()
, igc_union()
, igc_xor()
and igc_minus()
are general set operations on grobs using gridGeometry::polyclipGrob()
igc_combine()
is the core function used by the above set operatorsigc_mask()
and igc_clip()
use the new arbitrary clip and mask functionality introduced in R4.1
library(grid)
library(ingrid)
wug <- igc_intersect(
igc_stack(
ig_circle(r = .mm(20), fill = 'red', alpha = 0.3),
ig_circle(r = .mm(33), x = .mid + .mm(25), fill = 'blue', alpha = 0.3),
ig_circle(r = .mm( 2), x = .mid - .mm(13), y = .mid + .mm(4), fill='black', col='white')
),
ig_circle(r = .mm(28), x = .mid - .mm(19), y = .mid - .mm(20), fill = 'lightblue', col = 'transparent', alpha = 0.3)
)
grid.newpage(); grid.draw(wug)
igc_mask()
and igc_clip()
use the new arbitrary clip and mask functionality introduced in R4.1
library(grid)
library(ingrid)
# Hex
r <- .mm(20)
theta <- seq(30, 360, 60) * pi/180
x <- .mid + .mm(r * cos(theta))
y <- .mid + .mm(r * sin(theta))
hex <- ig_polygon(x, y, fill = 'blue')
# Random raster
ras <- ig_raster(
image = matrix(runif(100), 10, 10)
)
# Draw individually
grid.newpage()
grid.draw(ras)
grid.draw(hex)
# Mask the raster with the hex
masked <- igc_mask(ras, hex)
grid.newpage(); grid.draw(masked)
# Template object that will be adapted
rect <- ig_rect(width = .cm(2), height = .cm(2), col = 'grey20')
# create grobs
N <- 160
color <- rainbow(N)
grobs <- lapply(seq(N), function(i) {
igt_translate(
x = -.mid + .mm(3 * i),
y = .inch(sin(i/4)),
igt_rotate(
angle = i * 2,
igt_update(rect, fill = color[i])
)
)
})
# draw
grobs <- do.call(grid::grobTree, grobs)
grid.newpage(); grid.draw(grobs)
# Template object that will be adapted
rect <- ig_rect(width = .cm(1), height = .cm(1), col = 'white')
N <- 160
color <- rainbow(N)
# Coords
r <- .mm(40)
theta <- (seq(0, 360, length.out = N + 1) * pi/180 )[-1]
x <- .mm(r * cos(theta + 0.2) + r * sin(3 * theta))
y <- .mm(r * 0.8 * cos(2 * theta) + r * sin(theta))
# create grobs
grobs <- lapply(seq(N), function(i) {
igt_translate(
x = x[i],
y = y[i],
igt_rotate(
angle = i * 5,
igt_update(rect, fill = color[i])
)
)
})
# draw
grobs <- do.call(grid::grobTree, grobs)
grid.newpage(); grid.draw(grobs)
ellipseGrob
, ngonGrob
from gridExtra