Interactive Maps with tmap and Shiny

Session 6: Interactive features (tooltips and popups)

Martijn Tennekes

Overview

What are interactive features?

In view mode, map objects can respond to user interaction:

  • Tooltips — text shown when hovering over a feature
  • Popups — panel shown when clicking on a feature
  • Feature IDs — identify which feature was clicked (used with Shiny — covered in Session 11)

These are set via arguments in the layer functions (tm_polygons, tm_symbols, etc.).

Tooltips

Hover tooltips with hover

By default, hover is disabled — unless id is set in the layer, in which case the id value is shown automatically:

tmap_mode("view")

# hover is on by default when id is set — shows country name on hover
tm_shape(World) +
  tm_polygons(fill = "HPI", id = "name")

To disable hover even when id is set:

tm_shape(World) +
  tm_polygons(fill = "HPI", id = "name", hover = FALSE)

To show a different column than id on hover, pass a column name explicitly:

tm_shape(World) +
  tm_polygons(fill = "HPI", id = "iso_a3", hover = "name")

Feature IDs with id

The id argument in a layer function sets the column used to identify features:

  • Shown as the hover tooltip by default
  • Returned to Shiny when the user clicks a feature (see Session 11)
tmap_mode("view")

tm_shape(World) +
  tm_polygons(fill = "HPI", id = "name")

Popups

Click popups with popup

tmap_mode("view")

tm_shape(World) +
  tm_polygons(
    fill = "HPI",
    popup = tm_popup(vars = c("name", "HPI", "life_exp", "gdp_cap_est"))
  )
  • Character vector of column names to show
  • popup = TRUE → default popup, show all variables
  • popup = FALSE → disable popups

Named popup variables

Use a named character vector to display friendly labels:

tm_shape(World) +
  tm_polygons(
    fill = "HPI",
    popup = tm_popup(
      vars = c(
        "Happy Planet Index" = "HPI",
        "Life expectancy"    = "life_exp",
        "GDP per capita"     = "gdp_cap_est"
      ),
      title = "name")
  )

Formatting labels

tm_label_format()

tm_label_format() controls how numeric values are formatted — in legend labels and in popups.

It is passed to:

  • label.format argument of scale functions (tm_scale_intervals(), tm_scale_continuous(), …)
  • format argument of tm_popup()
# Reference:
# https://r-tmap.github.io/tmap/reference/tm_label_format.html

Key arguments

Argument Default Effect
digits NA (auto) Number of decimal places
scientific FALSE Use scientific notation
big.num.abbr c(mln=6, bln=9) Abbreviate millions/billions
prefix "" Text before number
suffix "" Text after number
text.separator "to" Between interval bounds
text.less.than "Less than" For lowest open interval
text.or.more "or more" For highest open interval
interval.disjoint TRUE Show disjoint intervals (0–999, 1000–1999)
html.escape TRUE Escape HTML in popups; set FALSE to allow HTML

label.format — prefix and separator

tm_shape(World) +
  tm_polygons(
    fill = "gdp_cap_est",
    fill.scale = tm_scale_intervals(
      style = "kmeans", n = 5,
      label.format = tm_label_format(
        prefix         = "$",
        text.separator = "to",
        digits         = 0
      )
    )
  )

label.format — abbreviating large numbers

tm_shape(World) +
  tm_polygons() +
tm_shape(metro) +
  tm_bubbles(
    size = "pop2020",
    size.scale = tm_scale_continuous(
      label.format = tm_label_format(big.num.abbr = c(million = 6))
    )
  )

popup.format — per-column formatting in view mode

tmap_mode("view")

tm_shape(World) +
  tm_polygons(
    fill = "HPI",
    popup.vars = c("name", "HPI", "gdp_cap_est", "pop_est"),
    popup.format = list(
      HPI         = tm_label_format(digits = 1),
      gdp_cap_est = tm_label_format(prefix = "$", big.num.abbr = c(k = 3)),
      pop_est     = tm_label_format(
        fun = function(x) paste("About", round(x/1e6), "million"))
    )
  )

HTML in popups

Setting html.escape = FALSE allows raw HTML in popup values — for example, rendering numbers in italics:

World$HPI_fmt <- paste0("<strong>", round(World$HPI, 1), "</strong>")

tmap_mode("view")

tm_shape(World) +
  tm_polygons(
    fill = "HPI",
    id = "name",
    popup = tm_popup(
      vars = c("Country" = "name", "HPI" = "HPI_fmt"),
      format = list(
        HPI_fmt = tm_label_format(html.escape = FALSE)
    ))
  )

Recap

  • id = "column" → identifies features; hover is enabled automatically when id is set; use hover = FALSE to disable it, or hover = "column" to show a different column
  • popup = tm_popup(...) → popup on click
  • tm_label_format() controls number formatting in both legend labels and popups
  • Key args: digits, prefix, suffix, big.num.abbr, text.separator, interval.disjoint, html.escape
  • label.format → used inside tm_scale_*() for legend labels
  • format → used inside tm_popup() for popup values
  • Reference: tm_label_format
  • Shiny integration with id is covered in Session 11