Search code examples
rdictionarytmap

{tm_shape}: specify icons via image filenames


I can't assign a separate icon for each point in the CSV file to be displayed as a point

And it looks like this and each point should have a different icon

enter image description here

points <- read.csv("dane_ikony.csv", header = TRUE)
points
points.sf <- st_as_sf(points, coords = c("x", "y"), crs = 4326)


for(i in 1:nrow(points)) {
  icon <- tmap_icons(points$Icon[i])
  points.sf$icon[i] <- icon
}


tm_shape(pl.map.sf) + 
  tm_polygons(col = "lightyellow1") +
  tm_shape(points.sf) +
  tm_symbols(shape = icon, size = 1.2, border.lwd = NA) +
  tm_grid(col = "gray",
          labels.size = 0.8) +
  tm_text("Nazwa", size = 0.8, root = F, just = 'top', auto.placement = T) + 
  tm_layout(title = "mapa Polski", 
            legend.text.size = 0.8, 
            legend.title.size = 0.8, 
            frame = TRUE) +
  tm_scale_bar(position = c("left", "bottom"))

tmap_mode("view") 
tm_shape(pl.map.sf) + 
  tm_polygons(col = "lightyellow1") +
  tm_shape(points.sf) +
  tm_text("Nazwa", size = 0.8, root = F, just = 'top', auto.placement = T) + 
  tm_symbols(shape = icon, size = 1.2, border.lwd = NA) +
  tm_view(alpha = 0.5)

CSV :

x,y,Nazwa,Icon
16.91855,52.40692,Poznan,krakow.png
19.94498,50.06465,Krakow,wroclaw.png

Solution

    1. To reproduce first download and unzip to POL_adm directory the shapefile from https://geodata.ucdavis.edu/gadm/gadm4.1/json/gadm41_POL_1.json.zip. Then load the two required packages.
    library(tmap)
    library(sf)
    
    1. Load the Poland's map.
    pl.map.sf <- st_read(dsn = 'POL_adm/gadm41_POL_1.shp')
    
    1. Create cities.csv file with content as below (or download the file from https://www.dropbox.com/s/4yvdyemr8l3avbu/cities.csv?dl=0).
    x,y,Name,Icon
    19.94498,50.06465,Krakow,Krakow.png
    16.91855,52.40692,Poznan,Poznan.png
    21.00762,52.23222,Warszawa,Warszawa.png
    17.03044,51.11083,Wroclaw,Wroclaw.png
    15.50498,51.93835,ZielonaGora,ZielonaGora.png
    
    1. Read the CSV file and convert geographical coordinates to an sf object.
    points <- read.csv("cities.csv", header = TRUE)
    points.sf <- st_as_sf(points, coords = c("x", "y"), crs = 4326)
    
    1. Download 5 coats of arms from here https://www.dropbox.com/s/b3lwew0wcx3y70g/coats_of_arms.zip?dl=0 and save the 5 png files in the current directory.
    list.files(pattern = "png")
    [1] "Krakow.png"      "Poznan.png"      "Warszawa.png"   
    [4] "Wroclaw.png"     "ZielonaGora.png"
    
    1. Create a list of icons with city coats of arms
    coats_of_arms = tmap_icons(points.sf$Icon)
    
    1. Create the map.
    tmap_mode("plot") 
    tm_shape(pl.map.sf) +
      ## Pierwsza warstwa
      tm_polygons(col = "lightyellow1") +
      tm_grid(col = "gray", labels.size = 0.8) +
      tm_layout(title = "Map of Poland", 
                legend.text.size = 0.8, 
                legend.title.size = 0.8, 
                frame = TRUE) +
      tm_scale_bar(position = c("left", "bottom")) +
      ## Druga warstwa z nazwami miast i ich herbami
      tm_shape(points.sf) +
      tm_text("Name", col = "blue", size = 1, auto.placement = FALSE) +
      tm_symbols(shape = "Icon", 
                 shapes = coats_of_arms, 
                 size = 1, 
                 border.lwd = NA, 
                 ymod = 1) +
      tm_layout(legend.show = FALSE)
    
    1. And here is the end result. map of Poland

    !!! IMPORTANT NOTE !!!

    Is this a bug or is it an intended behaviour?

    It seams that the names of the cities in the cities.csv file MUST be listed alphabetically. Otherwise the icons do appear on the map, but in the wrong order (incorrect icons appear next to cities).

    Now the order of the names is "from A to Z":

    points$Name
    [1] "Krakow"      "Poznan"      "Warszawa"    "Wroclaw"     "ZielonaGora"
    

    However, after shuffling the data

    points <- points[sample(1:nrow(points)), ]
    

    the points variable may by as below and now the city names are certainly not sorted alphabetically.

             x        y        Name            Icon
    5 15.50498 51.93835 ZielonaGora ZielonaGora.png
    4 17.03044 51.11083     Wroclaw     Wroclaw.png
    1 19.94498 50.06465      Krakow      Krakow.png
    3 21.00762 52.23222    Warszawa    Warszawa.png
    2 16.91855 52.40692      Poznan      Poznan.png
    

    After executing the codes again the map is bad as icons are placed in wrong places Take a close look at the map below and compare it with the previous one. Any suggestions?

    map of Poland - BAD