Generate and plot **Voronoi treemaps** or
**Sunburst treemaps** from hierarchical data.

Treemaps are a visually appealing graphical representation of
numerical data using a space-filling approach. A plane or ‘map’ is
subdivided into smaller areas called cells. The cells in the map are
scaled according to an underlying metric which allows to grasp the
hierarchical organization and relative importance of many objects at
once. This package contains two different implementations of treemaps,
**Voronoi treemaps** and **Sunburst treemaps**

There are different implementations available for **Voronoi
tesselations** in R, the simplest being the `deldir()`

function (from package `deldir`

). However,
`deldir`

and others do not handle nested Voronoi
tesselations, nor do they perform additively weighted Voronoi
tesselation. This is an important demand for systems biology and other
applications where it is useful to scale the cell size (or area) to a
set of predefined weights. The `voronoiTreemap()`

function
provided in this packages allows both the additively weighted Voronoi
tesselation and the nesting of different hierarchical levels in one
plot.

Some of the underlying functions for the tesselation were developed
by Paul Murrell, University of Auckland, and serve as the basis for this
package. They are called by a recursive wrapper function,
`voronoiTreemap()`

, which subdivides the plot area in
polygonal cells according to the highest hierarchical level. It then
continues with the tesselation on the next lower level using the child
cell of the previous level as the new parental cell, and so on.

The **Sunburst treemap** is a computationally less
demanding treemap that does not require iterative refinement, but simply
generates circle sectors that are sized according to predefined weights.
The main function to draw Sunburst treemaps is
`sunburstTreemap()`

. It uses the same underlying recursive
algorithm under the hood and can be used to draw sectors of different
hierarchical levels with increasing granularity.

The C++ code computing the actual Voronoi tesselation requires the CGAL library headers.
Thanks to Ahmadou Dicko,
installing the complete CGAL library locally is no longer necessary.
Instead, the package depends on the CGAL headers that are available as R
packages on CRAN. The package was using CGAL 4 (package
`cgal4h`

), but now moved to the latest CGAL 5.5+ version
available as package `RcppCGAL`

. The dependencies are usually
installed automatically and manual installation of CGAL (headers) should
not be necessary.

**NOTE**: The `RcppCGAL`

package is currently
(September 2023) not available on CRAN! Please install it manually from
Github.

To install the package directly from github, use the following
function from the `devtools`

package in your R session:

The functions to create Voronoi (or Sunburst) treemaps take a
`data.frame`

as main input. The `data.frame`

should contain column(s) with numerical or categorical data (i.e. a
character vector). Let’s create a simple example data frame.

```
library(WeightedTreemaps)
# load example data
data(mtcars)
mtcars$car_name = gsub(" ", "\n", row.names(mtcars))
```

Generate the treemap. It will return a list of polygons and metadata. The columns of the data frame that are used as levels of the treemap need to be specified. Different parameters like the initial shape, or the maximum number of iterations are optional.

```
# generate treemap; set seed to obtain same pattern every time
tm <- voronoiTreemap(
data = mtcars,
levels = c("gear", "car_name"),
cell_size = "wt",
shape = "rounded_rect",
seed = 123
)
```

Draw the treemap.

The `voronoiTreemap()`

and `drawTreemap()`

functions are separated in order to allow drawing of the same treemap
object in different ways. Computation of treemaps with thousands of
cells can be very time and resource consuming (around 5-10 minutes for a
2000-cell treemap on a regular desktop computer). With the
`drawTreemap()`

function, we can not only plot the same
treemap in different ways but also combine several treemaps on one page
using the `layout`

and `position`

arguments. The
most important style element is color. Coloring can be based on cell
category, cell size, or both, using the `color_type`

argument. By default, the highest hierarchical level is used for
coloring but that can be customized using the `color_level`

argument.

```
drawTreemap(tm, title = "treemap 1", label_size = 2,
color_type = "categorical", color_level = 1,
layout = c(2, 2), position = c(1, 1), legend = TRUE)
drawTreemap(tm, title = "treemap 2", label_size = 2,
color_type = "categorical", color_level = 2, border_size = 3,
add = TRUE, layout = c(2, 2), position = c(1, 2), legend = TRUE)
drawTreemap(tm, title = "treemap 3", label_size = 2,
color_type = "both", color_level = 1,
add = TRUE, layout = c(2, 2), position = c(2, 1), legend = TRUE)
drawTreemap(tm, title = "treemap 4", label_size = 2,
color_type = "cell_size", color_level = 2,
color_palette = heat.colors(10),
border_color = grey(0.4), label_color = grey(0.4),
add = TRUE, layout = c(2, 2), position = c(2, 2),
title_color = "black", legend = TRUE)
```

The expansion of cells towards a certain target size is a
non-deterministic process. During each iteration, cell size is adjusted
using weights, but the final result can only be measured after a cell
(polygon) was created. Is it too small compared to the target area, it
will get a higher weight for the next iteration, and *vice
versa*. The adjustment of weights can be controlled by the
`convergence`

parameter (“slow”, “intermediate”, “fast”).
Faster convergence will adjust weights more strongly and attempts to
reach the target size with fewer iterations. However this procedure
increases the probability of obtaining problematic polygons with for
example self-intersections or holes. Compare the following treemaps
generated with identical input except for the
`convergence`

.

```
convergence <- c("slow", "intermediate", "fast")
for (i in 1:3) {
tm <- voronoiTreemap(
data = mtcars,
levels = c("gear", "car_name"),
cell_size = "wt",
shape = "rounded_rect",
seed = 123,
convergence = convergence[i],
verbose = TRUE
)
drawTreemap(
tm,
title = paste0("convergence = ", convergence[i]),
label_size = 2.5,
label_color = "white",
layout = c(1, 3),
position = c(1, i),
add = ifelse(i == 1, FALSE, TRUE)
)
}
```

Generating a Voronoi treemap is an iterative and somewhat random
process. Since the cells ‘move’ during the iteration process, it can be
difficult to control the exact final position of cells. However, there
are two ways to influence cell positioning. The first is to use
different algorithms for sampling initial coordinates for each cell. The
second is simply setting a seed, which will sample the same set of
starting coordinates for the same input data. Regarding the
`positioning`

argument, compare the following three examples
where initial positions are 1) random, 2) ordered from top to bottom, or
3) ordered from center to edges.

```
# set seed to obtain same df every time
set.seed(123)
df <- data.frame(A = sample(10:100, 45))
tm1 <- voronoiTreemap(
data = df, levels = "A",
cell_size = "A",
shape = "rounded_rect",
positioning = "random"
)
tm2 <- voronoiTreemap(
data = df, levels = "A",
cell_size = "A",
shape = "rounded_rect",
positioning = "regular"
)
tm3 <- voronoiTreemap(
data = df, levels = "A",
cell_size = "A",
shape = "rounded_rect",
positioning = "clustered"
)
```

```
drawTreemap(tm1, title = "positioning = 'random'", border_size = 3,
layout = c(1,3), position = c(1, 1))
drawTreemap(tm2, title = "positioning = 'regular'", border_size = 3,
add = TRUE, layout = c(1,3), position = c(1, 2))
drawTreemap(tm3, title = "positioning = 'clustered'", border_size = 3,
add = TRUE, layout = c(1,3), position = c(1, 3))
```