Plot a specific image in a delimited polygon as repeated pattern

Plot a specific image in a delimited polygon as repeated pattern on a map

Plot an image pattern in a delimited polygon

A question on stackoverflow got my attention. This question asked how to draw trees in a polygon to represent a forest area on a map. I first thought about plotting “emoji” on a regular point pattern sampled in the polygon. Library sp allows for sampling points in a delimited SpatialPolygon which was exactly what I was looking for. I also thought about the possibility to plot y own image, which is possible using function rasterImage. Although this answered to the question, I was not completely satisfied with my answer. Thus, I decided to create a function a little more advanced than rasterImage.
The complete script is here.

Let us define a SpatialPolygonsDataFrame to work on. Let’s also define the specific polygon in which to draw the forest.

Draw a point grid with emoji in a specific polygon

We can sample points in the polygon area using sp::spsample function. We can then plot at the coordinates locations, any emoji using library emojifont for instance.

Realise a point grid in a specific polygon

Realize a grid point assuring icons not crossing lines

A problem with the previous code is that, depending on the locations sampled and on the size of emoji, icons may be out of the polygon. This arise because icons are centered on the position defined. To avoid this, we should sample locations in a polygon slightly smaller than the original. Function rgeos::gBuffer allows to calculate a buffer area around a spatial feature. Using a negative width on a SpatialPolygon creates a polygon with a smaller size (red area on the figure below). The appropriate width helps avoid plotting icons out of the polygon.

Realize a grid point assuring icons not crossing lines

Add your own image as a repeated pattern

Using emoji is an easy task, but you may want to use your own image. I used an other answer on stackoverflow to realize this with function graphics::rasterImage, coupled with the buffer polygon. Here I use an example with the R-logo so that you can reproduce the example, but any PNG image would work.

Add your own image as a repeated patternFunction to crop image within the limits of a polygon

Plotting with the buffer polygon requires to first calculate the size of your images in the spatial scale to be sure that images will not be plot out of the polygon area. You may want to avoid this calculation or you may want to avoid the white buffer area in your map. If your polygon is so small that the image do not fit entirely in, this may also be a problem. I thus created a function that give a transparent color to pixels of each images that are out of the polygon boudaries. To do so, I combined rasterImage and function mask of library raster, which work on Raster objects. I also made this function to work with ggplot.

Add your own image as repeated pattern within a polygon, cropped when needed

With my function, it is possible to plot our repeated image pattern without the use of the buffer. Images along borders get transparent pixels if they are out of the area.

Add your own image as repeated pattern in a polygon, cropped when needed

Create a wallpaper image with repeated pattern

I must admit that function raster::mask used in my function makes it a little long to calculate, in particular because the image needs to be repeated for each point of the pattern. If you have a big polygon with image repeated many times, the image may be long to appear with the for-loop…

You may want to do it only once. For that, you can first create your own PNG image wallpaper with the repeated pattern (or any combination of images wanted). Here I create my wallpaper directly in R, but you can use any PNG image.

Create a wallpaper image with repeated pattern

Add your own wallpaper with repeated images in a polygon

Once your PNG image pattern wallpaper is created, you can use my function once to plot inside your polygon. While using parameter offset or, like here offset.pc, you make sure that your wallpaper covers 100% of your polygone.

Add your own wallpaper with repeated images in a polygon

Add your own wallpaper with repeated images in a polygon with ggplot

Directly in the ggplot pipe

As I said earlier, my function may also be used in ggplot using type = ggplot. You can insert it directly in your piped ggplot syntax.

Add your own wallpaper with repeated images in a polygon with ggplot - direct

Indirectly by creating the dataset to be plot with tiles

You can also run my function previous to the ggplot and retrieve the data.tbl necessary to add in your ggplot, using parameter add=FALSE. You can then plot it using geom_tiles as in my function. If you want to reduce the weight of the cropped image, you can also filter the transparent tiles before plotting. Here I also modified the offset.pc parameter to increase the size of r-logo images.

Add your own wallpaper with repeated images in a polygon with ggplot - indirect

The complete R-code to plot a specific image in a delimited polygon as repeated pattern is here