Search code examples
rimagemagicktmap

Make silhouette icons in tmap


I would like to include the silhouette of animals as the icons in tmap, however when I save the svg as a png as required by tmap_icons I either get a white background, or an error. This works but includes the background:

library(tmap)
library(sf)
library(magick)
library(tidyverse)


nc <-st_read(system.file("shape/nc.shp", package="sf"))%>% 
  mutate(ICON="SQUIRREL") 



    SQUIRREL <- image_read_svg("https://images.phylopic.org/images/2916f8fe-290a-423b-b6f7-fb975c30d518/vector.svg")

image_write(SQUIRREL,"SQUIRREL.png", flatten = T, density = 90 )



SQUIRREL_ICON<- tmap_icons("SQUIRREL.png")


tm_shape(nc)+
  tm_polygons()+
  tm_symbols(shapes = SQUIRREL_ICON, shape="ICON")

Any of my attempts to remove or make the background transparent using the magick package for image manipulation where the background is made transparent or removed results in "Error in array(if (d[3L] == 3L) rgb(t(x[, , 1L]), t(x[, , 2L]), t(x[, : a raster array must have exactly 3 or 4 planes" or still draws the background

Examples:

SQUIRREL_OUTLINE1 <- SQUIRREL %>%
  image_background(color=rgb(0, 0, 0, 0), flatten = T)


image_write(SQUIRREL_OUTLINE1,"SQUIRREL_OUTLINE1.png", flatten = T, density = 90)

SQUIRREL_ICON_OUTLINE1<- tmap_icons("SQUIRREL_OUTLINE1.png")


tm_shape(nc)+
  tm_polygons()+
  tm_symbols(shapes = SQUIRREL_ICON_OUTLINE1, shape="ICON")




SQUIRREL_OUTLINE2 <- SQUIRREL %>%
  image_trim()


image_write(SQUIRREL_OUTLINE2,"SQUIRREL_OUTLINE2.png", flatten = T, density = 90)

SQUIRREL_ICON_OUTLINE2<- tmap_icons("SQUIRREL_OUTLINE2.png")


tm_shape(nc)+
  tm_polygons()+
  tm_symbols(shapes = SQUIRREL_ICON_OUTLINE2, shape="ICON")

I can test that the image manipulation can work, but is seems just not with alpha values of 0,

SQUIRREL_OUTLINE_RED <- SQUIRREL %>%
  
  image_background(color="red", flatten = T)

image_write(SQUIRREL_OUTLINE_RED,"SQUIRREL_OUTLINE_RED.png", flatten = T, density = 90)

SQUIRREL_ICON_OUTLINE_RED<- tmap_icons("SQUIRREL_OUTLINE_RED.png")



tm_shape(nc)+
  tm_polygons()+
  tm_symbols(shapes = SQUIRREL_ICON_OUTLINE_RED, shape="ICON")



SQUIRREL_OUTLINE_RED_RGB05 <- SQUIRREL %>%
  
  image_background(color=rgb(1, 0, 0, 0.5), flatten = T)

image_write(SQUIRREL_OUTLINE_RED_RGB05,"SQUIRREL_OUTLINE_RED_RGB05.png", flatten = T, density = 90)

SQUIRREL_ICON_OUTLINE_RED_RGB05<- tmap_icons("SQUIRREL_OUTLINE_RED_RGB05.png")



tm_shape(nc)+
  tm_polygons()+
  tm_symbols(shapes = SQUIRREL_ICON_OUTLINE_RED_RGB05, shape="ICON")


SQUIRREL_OUTLINE_RED_RGB00 <- SQUIRREL %>%
  
  image_background(color=rgb(1, 0, 0, 0), flatten = T)

image_write(SQUIRREL_OUTLINE_RED_RGB00,"SQUIRREL_OUTLINE_RED_RGB00.png", flatten = T, density = 90)

SQUIRREL_ICON_OUTLINE_RED_RGB00<- tmap_icons("SQUIRREL_OUTLINE_RED_RGB00.png")



tm_shape(nc)+
  tm_polygons()+
  tm_symbols(shapes = SQUIRREL_ICON_OUTLINE_RED_RGB00, shape="ICON")

Solution

  • You can force your png file to have an alpha channel like this...

    image_write(SQUIRREL, "SQUIRREL.png", 
                format = "png32",             #32-bit (4-channel) png
                flatten = FALSE,              #do not flatten 
                density = 90 )
    
    SQUIRREL_ICON <- tmap_icons("SQUIRREL.png")
    

    You also need to suppress the square borders round the icons in your tmap. This works for me...

    tm_shape(nc) +
      tm_polygons() +
      tm_symbols(shapes = SQUIRREL_ICON, shape="ICON", border.lwd = 0)
    

    enter image description here