Black Lives Matter. Please consider donating to Black Girls Code today.

Choroplethmapbox & 2 custom Geojsons - US works but Ireland does not. Why?

Completely puzzled by this so more than grateful for any help.

The R code below uses the same logic to generate from custom geojson’s a choroplethmapbox
for Ireland (p3) & the US (p4) respectively.

p4 works nicely & produces the coloured map below, p3 does not & produces a map without
colours although it does render a colour legend on the right.

I’ve checked the geojsons & they both appear to have their id’s in the right place in the schema.
Otherwise, the only real difference between p3 & p4 is that p3 uses & manipulates a downloaded
dataset “primary_schools_2013_2014.csv” & p4 uses the state.x77 R dataset.

Here’s the code:


fileName <- "./primary_schools_2013_2014.csv"
fileUrl = "http://airo.maynoothuniversity.ie/files/dDATASTORE/education/csv/primary_schools_2013_2014.csv"
if(!file.exists(fileName)) {
  download.file(fileUrl, "./primary_schools_2013_2014.csv", method = "curl")
}

schools <- read.csv("./primary_schools_2013_2014.csv", header = TRUE, sep = ",", quote = "\"")
colourCount = length(unique(mtcars$hp))
getPalette = colorRampPalette(brewer.pal(9, "Set1"))

schools_grp <- schools %>% 
    select(County, M_13_14, F_13_14, T_13_14) %>% group_by(County) %>% 
    summarize(nrows = n(), 
              total_male = sum(M_13_14), 
              mean_male = mean(M_13_14, na.rm = TRUE), 
              total_female = sum(F_13_14), 
              mean_female = mean(F_13_14, na.rm = TRUE), 
              total_both = sum(T_13_14), 
              mean_both = mean(T_13_14, na.rm = TRUE)) %>%
    mutate(char_county = as.character(County)) %>%
    select(-County) 

# %>% filter(char_county == "Donegal")

#
# Have to re-work the schools_grp data frame to a matrix
# whose values will match with the geojson id's
#

schools_mtrx <- data.matrix(schools_grp[, 1:7])
schools_counties <- unname(as.matrix(schools_grp[, 8]))
row.names(schools_mtrx) <- schools_counties

p3 <- plot_ly() %>%
    add_trace(data = as.data.frame(schools_mtrx),
              type = "choroplethmapbox",
              geojson = paste(c(
              "https://gist.githubusercontent.com/pnewall/",
              "9a122c05ba2865c3a58f15008548fbbd/raw/",
              "f7e1731bab695bd76fad9c23c22106eb12cb3ddf/",
              "ireland-counties.geojson"),
              collapse = ""),
              locations = row.names(schools_mtrx),
              z = as.vector(schools_mtrx[, "mean_both"]),
              text = row.names(schools_mtrx),
              span = I(0)) %>%
  
    layout(mapbox = list(
            style = "light",
            zoom = 6,
            center = list(lon = -8.0, lat = 53.4))) %>%
  
    config(
        mapboxAccessToken = Sys.getenv("MAPBOX_TOKEN"),
        
# Workaround to make sure image download uses full container
# size https://github.com/plotly/plotly.js/pull/3746

        toImageButtonOptions = list(
            format = "svg", 
            width = NULL, 
            height = NULL))

p3

p4 <- plot_ly() %>%
  add_trace(
    type = "choroplethmapbox",
    geojson = paste(c(
    "https://gist.githubusercontent.com/pnewall/",
    "d25c7c7a79a8a8a552834d26b8ecea99/raw/",
    "85eb5495b0b8eb01b8bdd7091f5ed1d726180ad0/",
    "us_counties.geojson"), 
    collapse = ""),
    locations = row.names(state.x77),
    z = state.x77[, "Population"] / state.x77[, "Area"],
    span = I(0)
  ) %>%
  layout(
    mapbox = list(
      style = "light",
      zoom = 4,
      center = list(lon = -98.58, lat = 39.82)
    )
  ) %>%
  config(
    mapboxAccessToken = Sys.getenv("MAPBOX_TOKEN"),
    # Workaround to make sure image download uses full container
    # size https://github.com/plotly/plotly.js/pull/3746
    toImageButtonOptions = list(
      format = "svg", 
      width = NULL, 
      height = NULL
    )
  )

p4

& here is the output from p4

cmb_us

& this from p3

cmb_ireland

Have fixed/worked around this. Looks like I should have RTFM’ed more closely. Para 4.2.1 of https://plotly-r.com/maps.html#maps-custom says *

“By simply providing a z attribute, plotly_geo() objects will try to create a choropleth, but you’ll also need to provide locations and a locationmode. It’s worth noting that the locationmode is currently limited to countries and US states, so if you need to a different geo-unit (e.g., counties, municipalities, etc), you should use the choroplethmapbox trace type and/or use a “custom” mapping approach as discussed in Section 4.2.”*

This explains why the US map works but the Ireland one does not. In the end, I found it easier & more effective to use the sf simple feature package & mapview as below:

schools_grp <- schools %>%
select(County, M_13_14, F_13_14, T_13_14) %>% group_by(County) %>%
summarize(nrows = n(),
total_male = sum(M_13_14),
mean_male = mean(M_13_14, na.rm = TRUE),
total_female = sum(F_13_14),
mean_female = mean(F_13_14, na.rm = TRUE),
total_both = sum(T_13_14),
mean_both = mean(T_13_14, na.rm = TRUE)) %>%
mutate(char_county = as.character(County)) %>%
select(-County)

url_gj <- paste(c(
https://gist.githubusercontent.com/pnewall/”,
“9a122c05ba2865c3a58f15008548fbbd/raw/”,
“572888440cec7059e2fd55802756e59aca83f51e/”,
“ireland-counties.geojson”),
collapse = “”)

Make the geojson simple feature from the file at the url above
then merge with the schools data on the county name

sf <- geojson_sf(url_gj)
schools_grp_sf <- merge(sf, schools_grp, by.x = “name”, by.y = “char_county”)

Set the column names so the chart output looks better

colnames(schools_grp_sf) <- c(“County”, “Nr of Schools”, “Total Male Pupils”, “Mean Nr of Males per School”, “Total Female Pupils”, “Mean Nr Females per School”, “Total Pupils”, “Mean Nr of Pupils per School”, “Geometry”)

st_geometry(schools_grp_sf) <- “Geometry”

p3 <- mapview(schools_grp_sf,
zcol = c(“Nr of Schools”, “Total Pupils”, “Mean Nr of Pupils per School”),
col.regions = sf.colors(5), lwd = 1,
popup = popupTable(schools_grp_sf, row.numbers = FALSE, feature.id = FALSE))

1 Like