0

I'm trying to create a choropleth of world countries that also shows microstates - but the issue I have is that they're too small to be seen at the scale.

Wikimedia projects sometimes use this illustration for this purpose - microstates are displayed with a dot, which is not to scale but at least is visible.

I realise this is not really a geographically accurate map, but I was wondering if something like this was available in code form, so that I could use it to make maps programmatically (in my case, with R, sf and ggplot2):

dat |>
    left_join(ne_countries(scale = "small", returnclass = "sf")) |>
    ggplot() +
    geom_sf(aes(fill = yes_no, geometry = geometry))
5
  • I'm assuming you need a fixed size map and can't use something like SVG or Leaflet or just a really large map? Aug 22, 2022 at 12:04
  • Yes, fixed size map (illustration for a scientific article). I could edit the Wikipedia SVG I linked manually, but it would be very tedious, so I'd prefer to do it programmatically: merge a GIS dataset with my dataset and then create the plot that way. I'm not familiar with Leaflet.
    – Andrea M
    Aug 22, 2022 at 13:41
  • Leaflet lets you create zooming maps, so won't help. You could go the insane route of magnifying the map near microstates and then doing a continuous dropoff so the map remains smooth. If you have a high-resolution image, you can use an image manipulation tool to do this and then reduce back down to the size you need. Aug 22, 2022 at 13:45
  • Or you could use different "side maps" for microstates, like many US maps do for Alaska and Hawaii Aug 22, 2022 at 13:46
  • 1
    I'm not familiar with r mapping so not sure if doable in your case but an easy way would be to use a symbology with both a fill and a dot the same colour as the fill at the center of each country, for "small" country the dot will entirely cover the country making them visible
    – J.R
    Aug 22, 2022 at 13:56

1 Answer 1

4

see if this may help.

The idea is:

  1. To identify microstates by area. So you may need to compute the area of each country and add that as an additional variable. Based on a thresold (in my example, it is set to 1900000000 (m^2)
  2. Split your dataset based on micro vs non-micro states.
  3. For those countries identified as micro states, replace the shape for a polygon that is the centroid of the country buffered by a given distance (in my case 200 kms). This would determine the final size of the circle for each microstate
  4. Recreate the initial dataset with the non-micro states plus the modified microstates.

See how this can be done. You may want to play with the thresold for identifying microstates and the distance of the buffer.

library(giscoR)
library(ggplot2)
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(sf)
#> Linking to GEOS 3.9.1, GDAL 3.4.3, PROJ 7.2.1; sf_use_s2() is TRUE

cnt <- gisco_get_countries() %>%
  st_transform("+proj=robin")

mapborder <- st_bbox(gisco_get_countries(epsg = 4326)) %>%
  st_as_sfc() %>%
  st_segmentize(1000000) %>%
  st_transform(st_crs(cnt)) %>%
  st_cast("LINESTRING")


# Mock variable for plotting choropleth

cnt$mock <- sample(letters[1:4], size = nrow(cnt), replace = TRUE)

# Area of countries
cnt$area <- as.double(st_area(cnt))

cnt <- cnt %>% arrange(desc(area))

# Thresold for determining which countries are tiny (in terms of area)
thr <- 1900000000

notiny <- cnt %>% filter(area >= thr)
# Make tiny circles
tiny <- cnt %>%
  filter(area < thr) %>%
  mutate(tiny = TRUE) %>%
  # Create a circle with a buffer of 200 kms
  st_centroid(of_largest_polygon = TRUE) %>%
  st_buffer(200000)
#> Warning in st_centroid.sf(., of_largest_polygon = TRUE): st_centroid assumes
#> attributes are constant over geometries of x

all <- notiny %>% bind_rows(tiny)


ggplot(all) +
  geom_sf(data = mapborder, size = 0.1) +
  geom_sf(aes(fill = mock), color = NA) +
  theme_void()

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.