Thanks for your nice reproducible example.
As far as I know, ggplot2
doesn't support clipping polygons directly. There are some workarounds: drawing a big polygon on top of them to obscure the parts you don't want to see, or clipping the polygons before you draw them using some other package, or working "down a level" with the grid
package to modify the final plot. This question has answers that explore a couple of those methods. Here, I'm just going to concentrate on drawing the Voronoi cells and not attempt the clipping.
The main issue is extracting the cells and their color from the tiles
object. It's a list, with one entry per cell. If you look at str(tiles[[1]])
you'll see something like this:
List of 6
$ ptNum: int 1
$ pt : Named num [1:2] 0.266 0.478
..- attr(*, "names")= chr [1:2] "x" "y"
$ x : num [1:8] 0.386 0.365 0.317 0.128 0.141 ...
$ y : num [1:8] 0.638 0.656 0.67 0.642 0.509 ...
$ bp : logi [1:8] FALSE FALSE FALSE FALSE FALSE FALSE ...
$ area : num 0.0402
- attr(*, "ncomp")= num 1
The boundary of the cell is in the polygon defined by the x
and y
components.
So here's one way to do what you want (except for the clipping):
library(ggplot2)
library(deldir)
set.seed(1)
x <- runif(50)
y <- runif(50)
tesselation <- deldir(x, y)
tiles <- tile.list(tesselation)
s <- seq(0, 2 * pi, length.out = 3000)
circle <- list(x = 0.5 * (1 + cos(s)),
y = 0.5 * (1 + sin(s)))
points <- data.frame(x=x, y=y)
colors <- hcl.colors(50, "viridis")
g <- ggplot(points, aes(x = x, y = y))
for (i in 1:50)
g <- g + geom_polygon(data = data.frame(x = tiles[[i]]$x,
y = tiles[[i]]$y,
density = 1/tiles[[i]]$area),
aes(fill = density))
g <- g + geom_point(col = "white")
g

Created on 2022-08-22 with reprex v2.0.2