The "graphicsutils" package includes a set of functions built on the top of the
graphics
package. This vignette is basically a guided tour of the package,
a cook book that exemplifies the functions implemented.
knitr::opts_chunk$set( fig.align = "center", comment = "#> ", fig.height = 6, fig.width = 6 ) library(graphicsutils)
An important aspect of graphicsutils
is that functions have been written in a layer-oriented perspective meaning that the default behavior of the functions provides functions that are rather minimalist and the user should call other functions (such as axis
, box2
, etc.) or change the default parameters values in order to customize his plot. Even though that this takes more command lines, we think that this approach makes it easier to get very personalized figures and we hope the functions we provide will help users
making beautiful figures.
In the layer-oriented approach we are using, it is very convenient to start with an empty plot of a given dimension, just like a canevas. To help creating such canevas, we wrote plot0()
. Note that by default x and y ranges are c(-1, 1)
. Moreover the argument fill
color the plot region (it is equivalent to calling the plotAreaColor()
).
par(mar = c(1, 1, 1, 1), mfrow = c(2, 2)) # plot0() text(0, 0, "plot0") # plot0(fill = "#8eb5e3") # plot0() plotAreaColor(col = "#8eb5e3") # plot0() plotAreaColor(col = "#8eb5e3", border = "grey20", lty = 2, lwd = 4)
The fill
and grid.col
make the customization of the background fairly
easy:
plot0(c(-10, 10), fill = "grey90", grid.col = 'white')
Another parameter text
that adds a text in the middle of the plot area
which makes plot0()
a helpful function to add piece of legend :
plot0(c(-10, 10), asp = 1, fill = 8, text = 'cool', srt = 45, cex = 4, col = 2)
The box2()
function allows the user to add any axes around the plot. A
limitation of the box()
function is does not allowed all the combination of
axes. box2()
proposes a simple way to select the sides to be added on the plot:
1 = bottom; 2 = left; 3 = top; 4 = right.
par(mar = rep(2, 4)) plot0() box2(which = "figure", lwd = 2, fill = "grey30") box2(side = 12, lwd = 2, fill = "grey80") axis(1) axis(2)
plot(1, type = "n", ann = FALSE, las = 1) coords <- textBox(x = 1, y = 1, labels = "AqA") str(coords) rect(coords$box[1], coords$box[2], coords$box[3], coords$box[4], border = 3) text(x = coords$x, y = coords$y, labels = coords$labels, col = "red")
plot(1, type = "n", ann = FALSE, las = 1) # all borders textBox(x = 1, y = 1.2, labels = "Hello World (1)", padding = 0.05) # bottom/top and left/right textBox(x = 1, y = 1.0, labels = "Hello World (2)", padding = c(0.05, 0.20)) # bottom, left, top, right textBox(x = 1, y = 0.8, labels = "Hello World (3)", padding = c(0.05, 0.05, 0.05, 0.35))
plot(1, type = "n", ann = FALSE, las = 1) textBox(x = 1, y = 1.2, labels = "Hello World (1)", padding = 0.05, col = "yellow", border = "green", fill = "red") textBox(x = 1, y = 1.0, labels = "Hello World (2)", padding = 0.05, lwd = 3, lty = 3) textBox(x = 1, y = 0.8, labels = "Hello World (3)", padding = 0.05, density = 30, angle = 45, fill = "gray")
plot(1, type = "n", ann = FALSE, las = 1) textBox(x = 1, y = 1.2, labels = "Hello World (1)", padding = 0.05, family = "mono") textBox(x = 1, y = 1.0, labels = "Hello World (2)", padding = 0.05, family = "serif") textBox(x = 1, y = 0.8, labels = "Hello World (3)", padding = 0.05, family = "serif", font = 3, cex = 3)
text <- "Hello World!\nHow beautiful you are!" plot(1, type = "n", ann = FALSE, las = 1) textBox(x = 1, y = 1.2, labels = text, padding = 0.05, align = "l") textBox(x = 1, y = 1.0, labels = text, padding = 0.05, align = "c") textBox(x = 1, y = 0.8, labels = text, padding = 0.05, align = "r") plot(1, type = "n", ann = FALSE, las = 1) textBox(x = 1, y = 1.2, labels = text, padding = 0.05, align = "l", lheight = 0) textBox(x = 1, y = 1.0, labels = text, padding = 0.05, align = "l", lheight = 1) textBox(x = 1, y = 0.8, labels = text, padding = 0.05, align = "l", lheight = 2) plot(1, type = "n", ann = FALSE, las = 1) textBox(x = 1, y = 1.2, labels = text, align = "l", padding = c(0.05, 0.05, 0.05, 0.35)) textBox(x = 1, y = 1.0, labels = text, align = "c", padding = c(0.05, 0.05, 0.05, 0.35)) textBox(x = 1, y = 0.8, labels = text, align = "r", padding = c(0.05, 0.05, 0.05, 0.35))
plot(1, type = "n", ann = FALSE, las = 1) textBox(x = 1, y = 1.2, labels = text, col = "transparent") textBox(x = 1, y = 1.0, labels = text, lwd = 0) textBox(x = 1, y = 0.8, labels = text, lwd = 0, col = "transparent")
plot(1, type = "n", ann = FALSE, las = 1) shadowText(x = 0.7, y = 1.3, labels = "This is a\nshadow text") shadowText(x = 1.0, y = 1.3, labels = "This is a\nshadow text", family = "serif") shadowText(x = 1.3, y = 1.3, labels = "This is a\nshadow text", family = "mono") shadowText(x = 1.0, y = 1.0, labels = "This is a shadow text", family = "serif", cex = 3, col = "yellow", bg = "red") shadowText(x = 0.7, y = 0.7, labels = "This is a\nshadow text", family = "serif", srt = 45) shadowText(x = 1.0, y = 0.7, labels = "This is a\nshadow text", family = "serif", srt = 180) shadowText(x = 1.3, y = 0.7, labels = "This is a\nshadow text", family = "serif", srt = -45)
A function that creates circles.
par(mar = c(1, 1, 1, 1), mfrow = c(2, 2)) plot0() circles(0, 0, 1) plot0() circles(0, 0, seq(0, 1, 0.2)) plot0() circles(0, 0, seq(0, 1, 0.2), lty = 2, lwd = 1.4) plot0() circles(0, 0 ,seq(0, 1, 0.2), from = pi, col = "#BBBBFF88", lty = 2, lwd = 1.4)
plot0(c(-2, 2), c(-2, 2), asp = 1) ellipse(c(-1, 1), c(1, 1, -1, -1), from = pi*seq(0.25, 1, by = 0.25), to = 1.25*pi, col = 2, border = 4, lwd = 3)
The pchImage()
function eases the uses of rasterImage()
to add images
(including .png
and .jpeg
files) on a graphic. It allows to change the color of the whole image.
pathLogo <- system.file("img", "Rlogo.png", package = "png") par(mar = c(4, 1, 4, 1), mfrow = c(1, 2)) plot0() pchImage(0, 0, file = pathLogo, cex.x = 4.5, cex.y = 4) plot0() pchImage(0, 0, file = pathLogo, cex.x = 4.5, cex.y = 4, col = "grey25", angle = 25)
Default frame.
plot0() frameIt()
A custom one.
plot0() frameIt(cex.x = 1.5, col = c(2, 3), border = 1)
addFrame() addFrame(grid = TRUE) addFrame(grid = TRUE, lwd = 0.25, lty = 3) addFrame(at_x = seq(-1, 1, by = 0.1)) ## Frame width addFrame(width = 0.25) addFrame(at_x = seq(-1, 1, by = 0.01), width = 1.00) ## Colors addFrame(col = 1:6) addFrame(col = "lightgray", border = "darkgray") ## Adding to a plot maps::map() addFrame(grid = TRUE, add = TRUE, width = 5) maps::map.axes() ## Other graphical parameters addFrame(bg = "darkgray", xaxs = "i", yaxs = "i")
plot0(c(0, 10), c(0, 10)) sz <- 100 seqx <- seq(0, 10, length.out = sz) seqy1 <- 0.2 * seqx * runif(sz, 0, 1) seqy2 <- 4 + 0.25 * seqx * runif(sz, 0, 1) seqy3 <- 8 + 0.25 * seqx * runif(sz, 0, 1) envelop(seqx, seqy1, seqy2, col = 'grey85', border = NA) envelop(seqx, seqy2, seqy3, col = 'grey25', border = NA)
coords <- cbind(runif(10), runif(10)) plot0(coords) points(coords, bg = "grey25", pch = 21) encircle(coords, border = "#7b11a1", lwd = 2)
par(mar = rep(2, 4)) dfa <- data.frame(name = rep(LETTERS[1:4], 25), val = runif(100)) plot0(c(0, 5), c(0, 1)) boxplot2(val ~ name, data = dfa, add = TRUE, vc_cex = c(4, 40, 2))
dataset <- data.frame(dat = c(rnorm(50, 10, 2), rnorm(50, 20, 2)) , grp = rep(c('A', 'D'), each = 50)) graphics::par(mfrow = c(1, 3)) plotMeans(dat ~ grp, data = dataset, pch = 19) ## plotMeans(dat ~ grp, data = dataset, FUN_err= function(x) sd(x)*2, pch = 15, ylim = c(-5, 30), yaxs = 'i', connect = TRUE, args_con = list(lwd = 2, lty = 2, col = 'grey35')) ## ser <- function(x) sd(x)/sqrt(length(x)) plot0(c(0, 4), c(0, 30)) plotMeans(dat~grp, data = dataset, FUN_err = ser, pch = 15, draw_axis = FALSE, add = TRUE, seqx = c(.5, 3.5), mar = c(6, 6, 1, 1), cex = 1.4) graphics::axis(2)
polarPlot(1:40, stats::runif(40), to = 1.9 * pi, col = 'grey30', border = 'grey80')
img <- png::readPNG(system.file('img', 'Rlogo.png', package = 'png'), native = TRUE) op <- graphics::par(no.readonly = TRUE) graphics::par(mfrow = c(2, 2), mar = rep(1, 4)) for (i in 1:4) plotImage(img) graphics::par(op)
Another example:
img<-png::readPNG(system.file('img', 'Rlogo.png', package = 'png'), native = TRUE) n<-15 plot0(c(0, 1),c(0, 1)) pchImage(0.1 + 0.8*stats::runif(n), 0.1 + 0.8 * stats::runif(n), cex.x = 0.2 + 1.6 * stats::runif(n), obj = img, angle = 360*runif(n), col = 2)
This function is designed for small matrices so the matrix is translated into a colored image without any rotation of the axes.
image2(matrix(1:9, 3)) image2(matrix(1:27, 3), from = 2, border = 2, lwd = 2)
The darken()
and lighten()
functions ease the creation of shades of a given
color. For any color palette, use the showPalette()
to display them!
someblue <- darken("blue", 10 * 1:9) showPalette(someblue)
somered <- lighten("red", 10 * 1:9) showPalette(somered)
showPalette(ramp("blue", "red", 10 * 3:7)) showPalette(blendColors(c("blue", "purple"))) showPalette(rainbow(81))
darken()
and lighten()
functions are convenient way to produce consistent
set of shaded colors with minimal effort; also use
showPalette()
to display your palette.
someblue <- darken("blue", 10*1:9) showPalette(someblue)
somered <- lighten("red", 10*1:9) showPalette(somered, add_codecolor = TRUE)
Since version 1.1-2 a set of color palettes has been added, see gpuPalette()
.
By default, gpuPalette()
displays the color palettes available:
gpuPalette()
In order to use one of the palette, use its names:
showPalette(gpuPalette("insileco"), add_codecolor = TRUE) showPalette(gpuPalette("insileco", 25), add_codecolor = TRUE)
par(mar = c(0, 0, 0, 0)) plot0(c(0, 10), c(0, 10)) colorScale(1, 8, gpuPalette("cisl", 10)) colorScale(1, 1, gpuPalette("cisl", 10), horiz = FALSE, labels.cex = 0.7) colorScale(7, 8, gpuPalette("cisl", 10), at = 1:5*2, labels = LETTERS[1:5]) lab <- LETTERS[1:10] lab[c(1, 3, 5, 7, 9)] <- "" colorScale(7, 1, gpuPalette("cisl", 10), horiz = FALSE, labels = lab, title = "color scale", labels.cex = 1.1, title.cex = 1.6)
par(mar = c(0, 0, 0, 0)) plot0(c(0, 10), c(0, 10)) colorScale(2, 7, gpuPalette("cisl", 100), percx = 0.6, at = c(5, 25, 50, 75, 95), title = "adj = 0") colorScale(2, 3, gpuPalette("cisl", 100), percx = 0.6, at = c(5, 25, 50, 75, 95), adj = 1, title = "adj = 1")
plot0(c(0, 10), c(0, 10)) sz <- 100 seqx <- seq(0, 10, length.out = sz) seqy1 <- 0.2 * seqx * runif(sz, 0, 1) seqy2 <- 4 + 0.25 * seqx * runif(sz, 0, 1) seqy3 <- 8 + 0.25 * seqx * runif(sz, 0, 1) envelop(seqx, seqy1, seqy2, col = "grey85", border = NA)
x <- data.frame(matrix(runif(200, 2, 10), 8, 25)) stackedAreas(x)
Some functions are interactive and fairly understandable, give them a try.
# NB: not run pickColors()
# NB: not run layout2()
dfGantt par(lwd = 2) palette(gpuPalette(6)[c(2, 4)]) ganttChart(dfGantt, mstone_lwd = 4, mstone_spacing = 0.6, lighten_done = 80) palette(gpuPalette(6)[c(3, 6)]) ganttChart(dfGantt, task_order = FALSE, mstone_add = TRUE, lighten_done = -40) # restore default palette palette("default")
mat <- matrix(10 * runif(100), 50) res <- pointsInPolygon(mat, cbind(c(4, 8, 8, 4), c(4, 4, 8, 8))) # Visual assessment plot0(c(0, 10), c(0, 10)) graphics::polygon(c(4, 8, 8, 4),c(4, 4, 8, 8)) graphics::points(mat[,1], mat[,2], col = res+1)
par(mfrow = c(2, 2), mar = rep(1, 4)) ## plot0(c(-1, 1), asp = 1) compassRose(0, 0) ## plot0(c(-1, 1), asp = 1) compassRose(0.5, 0.5) ## plot0(c(-1, 1), asp = 1) compassRose(0, 0, cex.cr = 2) ## plot0(c(-1, 1), asp = 1) compassRose(0, 0, rot = 0.75*pi, cex.cr = 2, cex.let = 1.5, offset = -1.25)
also,
```{R compassRose2} compassRose(0, rot = 25, cex.cr = 2, col.let =2, add = FALSE)
# Vector fields ```r systLin <- function(X, beta){ Y <- matrix(0,ncol = 2) Y[1L] <- beta[1, 1] * X[1L] + beta[1, 2] * X[2L] Y[2L] <- beta[2, 1] * X[1L] + beta[2, 2] * X[2L] return(Y) } seqx <- seq(-2, 2, 0.31) seqy <- seq(-2, 2, 0.31) beta1 <- matrix(c(0, -1, 1, 0), 2) # Plot 1: vecfield2d(coords = expand.grid(seqx, seqy), FUN = systLin, args = list(beta = beta1)) # Plot 2: graphics::par(mar = c(2, 2, 2, 2)) vecfield2d(coords = expand.grid(seqx, seqy), FUN = systLin, args = list(beta = beta1), cex.x = 0.35, cex.arr = 0.25, border = NA, cex.hh = 1, cex.shr = 0.6, col = 8) graphics::abline(v = 0, h = 0)
vec <- stats::runif(20) range(vec) prettyRange(vec) prettyRange(c(3.849, 3.88245))
This helper function returns suggested numbers of row and column for a given number of panels passed as an argument.
howManyRC(10) howManyRC(16)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.