--- title: "Volcano levelplot in Excalidraw" author: "Baptiste AuguiƩ" date: '`r Sys.Date()`' vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{Volcano levelplot in Excalidraw} %\VignetteEncoding{UTF-8} output: rmarkdown::html_vignette: toc: true toc_depth: 3 self_contained: false --- ```{r setup, echo=FALSE, message=FALSE,warning=FALSE,out.width='100%'} library(minixcali) library(purrr) library(knitr) opts_chunk$set(message = FALSE, warning=FALSE, fig.width = 7, fig.height = 4, out.width='50%') ``` Let's import a volcano in Excalidraw; since there's no support for raster graphics, we'll use the `{isobands}` package to create polygonal contour lines. ## The R object The `{isobands}` package takes a matrix of elevations and returns a number of contour lines at different heights. Adapting the documentation's example with the R volcano dataset, ```{r, fig.width = 3, fig.height = 5} library(minixcali) library(isoband) m <- volcano b <- isobands((1:ncol(m))/(ncol(m)+1), (nrow(m):1)/(nrow(m)+1), m, 10*(9:19), 10*(10:20)) str(b, list.len = 3) ``` We have a number of polygons with (x,y) coordinates to pass to `xkd_draw()` elements, but note that some of these polygons are not simply connected: this will be a problem as Excalidraw will join the pieces that should be disjoint. We'll therefore break down each path into separate groups using the `id` attribute returned by `isobands()`. ```{r data} p <- split(data.frame(b[[2]]), b[[2]]$id) str(p) ``` We now proceed to build the Excalidraw scene one subpath at a time, colouring the levels with both fill and colour. ```{r fun} d <- Excali_doc() library(scales) fills <- scales::viridis_pal(alpha = 0.2)(length(b)) cols <- scales::viridis_pal(alpha = 1)(length(b)) scale <- 500 for(ii in seq_along(b)) { fill <- fills[ii] col <- cols[ii] l <- b[[ii]] spl <- split(data.frame(x = l$x, y = -l$y), l$id) for (s in spl) { r_x <- range(s$x) r_y <- range(s$y) m <- scale * cbind(s$x - r_x[1], s$y - r_y[1]) shape <- xkd_draw( x = scale * r_x[1], y = scale * r_y[1], width = scale * diff(r_x), height = scale * diff(r_y), strokeWidth = 0.8, roughness = 2L, strokeSharpness = "sharp", groupIds = list("levelplot", paste0('level-', ii)), fillStyle = "solid", strokeColor = col, backgroundColor = fill, points = m ) d$add(shape) } } d$export('volcano.json') ``` You can see this drawing at: https://excalidraw.com/#json=6037869848166400,542JGip6v1DtWfHgYEvG5w ```{r drawing, out.width="50%", fig.align='center', echo=FALSE} knitr::include_graphics('volcano.png') ```