plast1cd0nk3y
plast1cd0nk3y

Reputation: 418

Is there a function to set a minimum size for symbols in tmap?

when tm_bubbles or tm_symbols is used to create bubbles or dots representing my data, categorized using size="data column of my choice", I am encountering a problem, where very small numbers in my dataset (let's say n=2 and my range is 10,2000), my bubble that represents x1=2000 is very visible on the screen, but x2=10 is so small that I can hardly see it on the screen. what I need is a function that sets a size.minimum for the bubbles. has anyone found a workaround for this problem? or can we create something like a size.minimum function for symbols?

Upvotes: 1

Views: 549

Answers (1)

mgrund
mgrund

Reputation: 1625

That's how it currently looks like:

library(tidyverse)
library(tmap)
library(sf)
data("World")

df_dummy <- tibble(size = c(10, 200, 2000), 
                   points = c(st_sfc(st_point(c(-30,20))), 
                              st_sfc(st_point(c(7,52))),
                              st_sfc(st_point(c(30,5))))) %>% 
  st_as_sf()

tm_shape(World) +
  tm_fill(col = "gray") +
tm_shape(df_dummy) +
  tm_bubbles(col = "red",
             size = "size")

enter image description here

Option 1

If you now add a df_dummy`<- df_dummy %>% mutate(size = log10(size)) your data is scaled differenty since we use the log10 function. Of course you loose the information about the "original" values in the legend but all symbols are visible:

enter image description here

Option 2

Alternatively, you could simply generate a new column in which all values below a defined limit receive a specific size value (e.g. all values below 100 receive a size of 100). By this all values below this limit would be clipped to a single one which then can be used as your size parameter. In the following example the points with original sizes of 10, 50 and 80 are uniformly plotted with a clip size of 100. In the custom legend they are covered by the label <= 100.

df_dummy <- tibble(size = c(10, 50, 80, 500, 2000), 
                   points = c(st_sfc(st_point(c(-30,20))), 
                              st_sfc(st_point(c(7,52))),
                              st_sfc(st_point(c(10,45))),
                              st_sfc(st_point(c(15,35))),
                              st_sfc(st_point(c(30,5))))) %>% 
  mutate(size = ifelse(size <= 100, 100, size)) %>% 
  st_as_sf()

# see the tm_bubbles docs regarding the applied scaling
bubble_sizes <- ((c(100, 500, 1000, 1500, 2000)) / 2000) ^ 0.5 * 2 

tm_shape(World) +
  tm_fill(col = "gray") +
tm_shape(df_dummy) +
  tm_bubbles(col = "red",
             size = "size",
             scale = 2,
             border.col = "black",
             legend.size.show = F,  
                 legend.col.show = F) +
  tm_add_legend("symbol",
                size = bubble_sizes,
                col = "red",
                labels = c("<= 100","500","1000","1500", "2000"),
                title = "custom legend")

enter image description here

Upvotes: 1

Related Questions