tmap icon indicating copy to clipboard operation
tmap copied to clipboard

`bg` and `outer.bg` default values

Open ar-puuk opened this issue 7 months ago • 12 comments

Hi @mtennekes, I was trying to plot a map without the area outside layout frame using outer.bg = FLASE (let me know if this is not right approach. That didnt quite work, I instead ended up using tmap::tm_layout(outer.margins = c(0,0,0,0))

library(tmap)

tmap_options(scale = 0.75)

packageVersion("tmap")
#> [1] '4.1'
packageDate("tmap")
#> [1] "2025-05-18"

tmap_devel_mode()
#> devel.mode: ON

test <- tmap::tm_shape(NLD_prov) +
  tmap::tm_polygons(lwd = 1) +
  tmap::tm_layout(bg.color = "#caeefb", frame = FALSE)

test

#>                 s1                 s2                      s3
#>             <char>             <char>                  <char>
#>  1:                                                          
#>  2:                                   get_shape_meta1 (0.021)
#>  3:                                        subset_shp (0.006)
#>  4:                                   get_shape_meta2 (0.001)
#>  5:                facet meta (0.055)                        
#>  6:                prep shape (0.003)                        
#>  7: step 1 (0.058)                                           
#>  8:                                                          
#>  9:                                                          
#> 10:                                                          
#> 11:                                                          
#> 12:                                                          
#> 13:                                                          
#> 14:                                                          
#> 15:                                    layer polygons (0.034)
#> 16:                     group (0.035)                        
#> 17: step 2 (0.035)                                           
#> 18: step 3 (0.003)                                           
#> 19: step 4 (0.114)                                           
#>                         s4 total
#>                     <char> <num>
#>  1:                        0.000
#>  2:                        0.021
#>  3:                        0.027
#>  4:                        0.028
#>  5:                        0.055
#>  6:                        0.058
#>  7:                        0.058
#>  8:       aes fill (0.008) 0.066
#>  9:        aes col (0.004) 0.070
#> 10:        aes lwd (0.004) 0.074
#> 11:        aes lty (0.004) 0.078
#> 12: aes fill_alpha (0.004) 0.082
#> 13:  aes col_alpha (0.003) 0.085
#> 14:        combine (0.006) 0.091
#> 15:                        0.092
#> 16:                        0.093
#> 17:                        0.093
#> 18:                        0.096
#> 19:                        0.210

test +
  tmap::tm_layout(outer.bg = FALSE) # Draw map background (outside the frame)?

#>                 s1                 s2                      s3
#>             <char>             <char>                  <char>
#>  1:                                                          
#>  2:                                   get_shape_meta1 (0.004)
#>  3:                                        subset_shp (0.002)
#>  4:                                                          
#>  5:                facet meta (0.011)                        
#>  6:                prep shape (0.002)                        
#>  7: step 1 (0.013)                                           
#>  8:                                                          
#>  9:                                                          
#> 10:                                                          
#> 11:                                                          
#> 12:                                                          
#> 13:                                                          
#> 14:                                                          
#> 15:                                    layer polygons (0.035)
#> 16:                     group (0.037)                        
#> 17: step 2 (0.037)                                           
#> 18: step 3 (0.002)                                           
#> 19: step 4 (0.131)                                           
#>                         s4 total
#>                     <char> <num>
#>  1:                        0.000
#>  2:                        0.004
#>  3:                        0.006
#>  4:                        0.006
#>  5:                        0.011
#>  6:                        0.013
#>  7:                        0.013
#>  8:       aes fill (0.007) 0.020
#>  9:        aes col (0.005) 0.025
#> 10:        aes lwd (0.004) 0.029
#> 11:        aes lty (0.005) 0.034
#> 12: aes fill_alpha (0.005) 0.039
#> 13:  aes col_alpha (0.004) 0.043
#> 14:        combine (0.005) 0.048
#> 15:                        0.048
#> 16:                        0.050
#> 17:                        0.050
#> 18:                        0.052
#> 19:                        0.183

test +
  tmap::tm_layout(outer.margins = c(0,0,0,0)) # expected output

#>                 s1                 s2                      s3
#>             <char>             <char>                  <char>
#>  1:                                                          
#>  2:                                   get_shape_meta1 (0.003)
#>  3:                                        subset_shp (0.002)
#>  4:                                                          
#>  5:                facet meta (0.012)                        
#>  6:                prep shape (0.001)                        
#>  7: step 1 (0.014)                                           
#>  8:                                                          
#>  9:                                                          
#> 10:                                                          
#> 11:                                                          
#> 12:                                                          
#> 13:                                                          
#> 14:                                                          
#> 15:                                    layer polygons (0.029)
#> 16:                     group (0.031)                        
#> 17: step 2 (0.031)                                           
#> 18: step 3 (0.002)                                           
#> 19: step 4 (0.106)                                           
#>                         s4 total
#>                     <char> <num>
#>  1:                        0.000
#>  2:                        0.003
#>  3:                        0.005
#>  4:                        0.005
#>  5:                        0.012
#>  6:                        0.013
#>  7:                        0.014
#>  8:       aes fill (0.004) 0.018
#>  9:        aes col (0.005) 0.023
#> 10:        aes lwd (0.005) 0.028
#> 11:        aes lty (0.003) 0.031
#> 12: aes fill_alpha (0.004) 0.035
#> 13:  aes col_alpha (0.003) 0.038
#> 14:        combine (0.005) 0.043
#> 15:                        0.043
#> 16:                        0.045
#> 17:                        0.045
#> 18:                        0.047
#> 19:                        0.153

Created on 2025-05-18 with reprex v2.1.1

Session info

sessioninfo::session_info()
#> Warning in system2("quarto", "-V", stdout = TRUE, env = paste0("TMPDIR=", :
#> running command '"quarto"
#> TMPDIR=C:/Users/pukar/AppData/Local/Temp/RtmpW6gMhu/file13c148af7a13 -V' had
#> status 1
#> ─ Session info ───────────────────────────────────────────────────────────────
#>  setting  value
#>  version  R version 4.5.0 (2025-04-11 ucrt)
#>  os       Windows 11 x64 (build 26100)
#>  system   x86_64, mingw32
#>  ui       RTerm
#>  language (EN)
#>  collate  English_United States.utf8
#>  ctype    English_United States.utf8
#>  tz       America/New_York
#>  date     2025-05-18
#>  pandoc   3.6.4 @ C:/PROGRA~1/Pandoc/ (via rmarkdown)
#>  quarto   NA @ C:\\PROGRA~1\\Quarto\\bin\\quarto.exe
#> 
#> ─ Packages ───────────────────────────────────────────────────────────────────
#>  package           * version    date (UTC) lib source
#>  abind               1.4-8      2024-09-12 [1] CRAN (R 4.5.0)
#>  base64enc           0.1-3      2015-07-28 [1] CRAN (R 4.5.0)
#>  class               7.3-23     2025-01-01 [2] CRAN (R 4.5.0)
#>  classInt            0.4-11     2025-01-08 [1] CRAN (R 4.5.0)
#>  cli                 3.6.5      2025-04-23 [1] CRAN (R 4.5.0)
#>  codetools           0.2-20     2024-03-31 [1] CRAN (R 4.5.0)
#>  colorspace          2.1-1      2024-07-26 [1] CRAN (R 4.5.0)
#>  cols4all            0.8        2024-10-16 [1] CRAN (R 4.5.0)
#>  crosstalk           1.2.1      2023-11-23 [1] CRAN (R 4.5.0)
#>  curl                6.2.3      2025-04-01 [1] https://ar-puuk.r-universe.dev (R 4.5.0)
#>  data.table          1.17.99    2025-04-09 [1] https://ar-puuk.r-universe.dev (R 4.5.0)
#>  DBI                 1.2.3.9027 2025-03-18 [1] https://ar-puuk.r-universe.dev (R 4.5.0)
#>  dichromat           2.0-0.1    2022-05-02 [1] CRAN (R 4.5.0)
#>  digest              0.6.37     2024-08-19 [1] CRAN (R 4.5.0)
#>  e1071               1.7-16     2024-09-16 [1] CRAN (R 4.5.0)
#>  evaluate            1.0.3      2025-01-10 [1] CRAN (R 4.5.0)
#>  fastmap             1.2.0      2024-05-15 [1] CRAN (R 4.5.0)
#>  fs                  1.6.6      2025-04-12 [1] CRAN (R 4.5.0)
#>  glue                1.8.0      2024-09-30 [1] CRAN (R 4.4.1)
#>  htmltools           0.5.8.1    2024-04-04 [1] CRAN (R 4.5.0)
#>  htmlwidgets         1.6.4      2023-12-06 [1] CRAN (R 4.5.0)
#>  KernSmooth          2.23-26    2025-01-01 [1] CRAN (R 4.5.0)
#>  knitr               1.50       2025-03-16 [1] CRAN (R 4.5.0)
#>  lattice             0.22-7     2025-04-02 [1] CRAN (R 4.5.0)
#>  leafem              0.2.4      2025-05-01 [1] Github (r-spatial/leafem@41cbf71)
#>  leaflegend          1.2.1      2024-05-09 [1] CRAN (R 4.5.0)
#>  leaflet             2.2.2      2024-03-26 [1] CRAN (R 4.5.0)
#>  leaflet.providers   2.0.0      2023-10-17 [1] CRAN (R 4.5.0)
#>  leafsync            0.1.0      2019-03-05 [1] CRAN (R 4.5.0)
#>  lifecycle           1.0.4      2023-11-07 [1] CRAN (R 4.5.0)
#>  logger              0.4.0      2024-10-22 [1] CRAN (R 4.5.0)
#>  lwgeom              0.2-14     2024-02-21 [1] CRAN (R 4.5.0)
#>  magrittr            2.0.3      2022-03-30 [1] CRAN (R 4.3.1)
#>  maptiles            0.10.0     2025-05-11 [1] Github (riatelab/maptiles@8c35b5d)
#>  microbenchmark      1.5.0      2024-09-04 [1] CRAN (R 4.5.0)
#>  png                 0.1-8      2022-11-29 [1] CRAN (R 4.5.0)
#>  proxy               0.4-27     2022-06-09 [1] CRAN (R 4.5.0)
#>  R6                  2.6.1      2025-02-15 [1] CRAN (R 4.5.0)
#>  raster              3.6-32     2025-03-28 [1] CRAN (R 4.5.0)
#>  RColorBrewer        1.1-3      2022-04-03 [1] CRAN (R 4.5.0)
#>  Rcpp                1.0.14     2025-01-12 [1] CRAN (R 4.5.0)
#>  reprex              2.1.1      2024-07-06 [1] CRAN (R 4.5.0)
#>  rlang               1.1.6      2025-04-11 [1] CRAN (R 4.5.0)
#>  rmarkdown           2.29       2024-11-04 [1] CRAN (R 4.5.0)
#>  rstudioapi          0.17.1     2024-10-22 [1] CRAN (R 4.5.0)
#>  s2                  1.1.8      2025-05-12 [1] CRAN (R 4.5.0)
#>  sessioninfo         1.2.3      2025-02-05 [1] CRAN (R 4.5.0)
#>  sf                  1.0-21     2025-05-15 [1] Github (r-spatial/sf@a9ceef1)
#>  sp                  2.2-0      2025-02-01 [1] CRAN (R 4.5.0)
#>  spacesXYZ           1.5-1      2025-02-10 [1] CRAN (R 4.5.0)
#>  stars               0.6-8      2025-02-01 [1] CRAN (R 4.5.0)
#>  terra               1.8-50     2025-05-09 [1] CRAN (R 4.5.0)
#>  tmap              * 4.1        2025-05-18 [1] Github (r-tmap/tmap@e24262a)
#>  tmaptools           3.2        2025-04-13 [1] https://r-tmap.r-universe.dev (R 4.5.0)
#>  units               0.8-7      2025-03-11 [1] CRAN (R 4.5.0)
#>  viridisLite         0.4.2      2023-05-02 [1] CRAN (R 4.5.0)
#>  withr               3.0.2      2024-10-28 [1] CRAN (R 4.5.0)
#>  wk                  0.9.4      2024-10-11 [1] CRAN (R 4.5.0)
#>  xfun                0.52       2025-04-02 [1] CRAN (R 4.5.0)
#>  XML                 3.99-0.18  2025-01-01 [1] CRAN (R 4.5.0)
#>  xml2                1.3.8      2025-03-14 [1] CRAN (R 4.5.0)
#>  yaml                2.3.10     2024-07-26 [1] CRAN (R 4.5.0)
#> 
#>  [1] C:/Users/pukar/AppData/Local/R/win-library/4.5
#>  [2] C:/Program Files/R/R-4.5.0/library
#>  * ── Packages attached to the search path.
#> 
#> ──────────────────────────────────────────────────────────────────────────────

Thats when I realized the outer.bg.color didnt work as well. Please see the reprex below:

library(tmap)

tmap_options(scale = 0.75)

packageVersion("tmap")
#> [1] '4.1'
packageDate("tmap")
#> [1] "2025-05-18"

tmap_devel_mode()
#> devel.mode: ON

tm_shape(World) + 
  tm_polygons("HPI") + 
  tm_layout(frame = TRUE, bg.color = "pink", outer.bg.color = "red", earth_boundary = TRUE, space.color = "yellow", frame.r = 20, scale = 2) + 
  tm_crs("auto")
#> [plot mode] fit legend/component: Some legend items or map compoments do not
#> fit well, and are therefore rescaled.
#> ℹ Set the tmap option `component.autoscale = FALSE` to disable rescaling.

#>                 s1                 s2                      s3
#>             <char>             <char>                  <char>
#>  1:                                                          
#>  2:                                   get_shape_meta1 (0.006)
#>  3:                                        subset_shp (0.006)
#>  4:                                   get_shape_meta2 (0.001)
#>  5:                facet meta (0.040)                        
#>  6:                prep shape (0.003)                        
#>  7: step 1 (0.043)                                           
#>  8:                                                          
#>  9:                                                          
#> 10:                                                          
#> 11:                                                          
#> 12:                                                          
#> 13:                                                          
#> 14:                                                          
#> 15:                                    layer polygons (0.047)
#> 16:                     group (0.049)                        
#> 17: step 2 (0.050)                                           
#> 18: step 3 (0.019)                                           
#> 19: step 4 (0.281)                                           
#>                         s4 total
#>                     <char> <num>
#>  1:                        0.000
#>  2:                        0.006
#>  3:                        0.012
#>  4:                        0.013
#>  5:                        0.040
#>  6:                        0.043
#>  7:                        0.043
#>  8:       aes fill (0.019) 0.062
#>  9:        aes col (0.005) 0.067
#> 10:        aes lwd (0.004) 0.071
#> 11:        aes lty (0.005) 0.076
#> 12: aes fill_alpha (0.004) 0.080
#> 13:  aes col_alpha (0.003) 0.083
#> 14:        combine (0.006) 0.089
#> 15:                        0.090
#> 16:                        0.092
#> 17:                        0.093
#> 18:                        0.112
#> 19:                        0.393

Created on 2025-05-18 with reprex v2.1.1

Session info

sessioninfo::session_info()
#> Warning in system2("quarto", "-V", stdout = TRUE, env = paste0("TMPDIR=", :
#> running command '"quarto"
#> TMPDIR=C:/Users/pukar/AppData/Local/Temp/RtmpgtIhGA/file157b06e8f3522 -V' had
#> status 1
#> ─ Session info ───────────────────────────────────────────────────────────────
#>  setting  value
#>  version  R version 4.5.0 (2025-04-11 ucrt)
#>  os       Windows 11 x64 (build 26100)
#>  system   x86_64, mingw32
#>  ui       RTerm
#>  language (EN)
#>  collate  English_United States.utf8
#>  ctype    English_United States.utf8
#>  tz       America/New_York
#>  date     2025-05-18
#>  pandoc   3.6.4 @ C:/PROGRA~1/Pandoc/ (via rmarkdown)
#>  quarto   NA @ C:\\PROGRA~1\\Quarto\\bin\\quarto.exe
#> 
#> ─ Packages ───────────────────────────────────────────────────────────────────
#>  package           * version    date (UTC) lib source
#>  abind               1.4-8      2024-09-12 [1] CRAN (R 4.5.0)
#>  base64enc           0.1-3      2015-07-28 [1] CRAN (R 4.5.0)
#>  class               7.3-23     2025-01-01 [2] CRAN (R 4.5.0)
#>  classInt            0.4-11     2025-01-08 [1] CRAN (R 4.5.0)
#>  cli                 3.6.5      2025-04-23 [1] CRAN (R 4.5.0)
#>  codetools           0.2-20     2024-03-31 [1] CRAN (R 4.5.0)
#>  colorspace          2.1-1      2024-07-26 [1] CRAN (R 4.5.0)
#>  cols4all            0.8        2024-10-16 [1] CRAN (R 4.5.0)
#>  crosstalk           1.2.1      2023-11-23 [1] CRAN (R 4.5.0)
#>  curl                6.2.3      2025-04-01 [1] https://ar-puuk.r-universe.dev (R 4.5.0)
#>  data.table          1.17.99    2025-04-09 [1] https://ar-puuk.r-universe.dev (R 4.5.0)
#>  DBI                 1.2.3.9027 2025-03-18 [1] https://ar-puuk.r-universe.dev (R 4.5.0)
#>  dichromat           2.0-0.1    2022-05-02 [1] CRAN (R 4.5.0)
#>  digest              0.6.37     2024-08-19 [1] CRAN (R 4.5.0)
#>  e1071               1.7-16     2024-09-16 [1] CRAN (R 4.5.0)
#>  evaluate            1.0.3      2025-01-10 [1] CRAN (R 4.5.0)
#>  fastmap             1.2.0      2024-05-15 [1] CRAN (R 4.5.0)
#>  fs                  1.6.6      2025-04-12 [1] CRAN (R 4.5.0)
#>  glue                1.8.0      2024-09-30 [1] CRAN (R 4.4.1)
#>  htmltools           0.5.8.1    2024-04-04 [1] CRAN (R 4.5.0)
#>  htmlwidgets         1.6.4      2023-12-06 [1] CRAN (R 4.5.0)
#>  KernSmooth          2.23-26    2025-01-01 [1] CRAN (R 4.5.0)
#>  knitr               1.50       2025-03-16 [1] CRAN (R 4.5.0)
#>  lattice             0.22-7     2025-04-02 [1] CRAN (R 4.5.0)
#>  leafem              0.2.4      2025-05-01 [1] Github (r-spatial/leafem@41cbf71)
#>  leaflegend          1.2.1      2024-05-09 [1] CRAN (R 4.5.0)
#>  leaflet             2.2.2      2024-03-26 [1] CRAN (R 4.5.0)
#>  leaflet.providers   2.0.0      2023-10-17 [1] CRAN (R 4.5.0)
#>  leafsync            0.1.0      2019-03-05 [1] CRAN (R 4.5.0)
#>  lifecycle           1.0.4      2023-11-07 [1] CRAN (R 4.5.0)
#>  logger              0.4.0      2024-10-22 [1] CRAN (R 4.5.0)
#>  lwgeom              0.2-14     2024-02-21 [1] CRAN (R 4.5.0)
#>  magrittr            2.0.3      2022-03-30 [1] CRAN (R 4.3.1)
#>  maptiles            0.10.0     2025-05-11 [1] Github (riatelab/maptiles@8c35b5d)
#>  microbenchmark      1.5.0      2024-09-04 [1] CRAN (R 4.5.0)
#>  png                 0.1-8      2022-11-29 [1] CRAN (R 4.5.0)
#>  proxy               0.4-27     2022-06-09 [1] CRAN (R 4.5.0)
#>  R6                  2.6.1      2025-02-15 [1] CRAN (R 4.5.0)
#>  raster              3.6-32     2025-03-28 [1] CRAN (R 4.5.0)
#>  RColorBrewer        1.1-3      2022-04-03 [1] CRAN (R 4.5.0)
#>  Rcpp                1.0.14     2025-01-12 [1] CRAN (R 4.5.0)
#>  reprex              2.1.1      2024-07-06 [1] CRAN (R 4.5.0)
#>  rlang               1.1.6      2025-04-11 [1] CRAN (R 4.5.0)
#>  rmarkdown           2.29       2024-11-04 [1] CRAN (R 4.5.0)
#>  rstudioapi          0.17.1     2024-10-22 [1] CRAN (R 4.5.0)
#>  s2                  1.1.8      2025-05-12 [1] CRAN (R 4.5.0)
#>  sessioninfo         1.2.3      2025-02-05 [1] CRAN (R 4.5.0)
#>  sf                  1.0-21     2025-05-15 [1] Github (r-spatial/sf@a9ceef1)
#>  sp                  2.2-0      2025-02-01 [1] CRAN (R 4.5.0)
#>  spacesXYZ           1.5-1      2025-02-10 [1] CRAN (R 4.5.0)
#>  stars               0.6-8      2025-02-01 [1] CRAN (R 4.5.0)
#>  terra               1.8-50     2025-05-09 [1] CRAN (R 4.5.0)
#>  tmap              * 4.1        2025-05-18 [1] Github (r-tmap/tmap@e24262a)
#>  tmaptools           3.2        2025-04-13 [1] https://r-tmap.r-universe.dev (R 4.5.0)
#>  units               0.8-7      2025-03-11 [1] CRAN (R 4.5.0)
#>  viridisLite         0.4.2      2023-05-02 [1] CRAN (R 4.5.0)
#>  withr               3.0.2      2024-10-28 [1] CRAN (R 4.5.0)
#>  wk                  0.9.4      2024-10-11 [1] CRAN (R 4.5.0)
#>  xfun                0.52       2025-04-02 [1] CRAN (R 4.5.0)
#>  XML                 3.99-0.18  2025-01-01 [1] CRAN (R 4.5.0)
#>  xml2                1.3.8      2025-03-14 [1] CRAN (R 4.5.0)
#>  yaml                2.3.10     2024-07-26 [1] CRAN (R 4.5.0)
#> 
#>  [1] C:/Users/pukar/AppData/Local/R/win-library/4.5
#>  [2] C:/Program Files/R/R-4.5.0/library
#>  * ── Packages attached to the search path.
#> 
#> ──────────────────────────────────────────────────────────────────────────────

Another example is in the example provided in package vignettes: Background colors. The plot doesn't have any element with "gold" color.

ar-puuk avatar May 18 '25 16:05 ar-puuk

Thanks for reporting this @ar-puuk This is probably an unresolved issue from https://github.com/r-tmap/tmap/issues/1078

Apparently, you'll have to set outer.bg = TRUE explicitly:

tmap::tm_shape(NLD_prov) +
	tmap::tm_polygons(lwd = 1) +
	tmap::tm_layout(bg.color = "#caeefb", 
					frame = FALSE, 
					outer.bg.color = "#caeefb", 
					outer.bg = TRUE)

Currently, bg is TRUE by default and outer.bg is FALSE (see https://github.com/r-tmap/tmap/blob/master/R/tmap_options_defaults.R#L227-L239)

Any reason to change these defaults? @Nowosad @aonojeghuo @Rapsodia86 @nickbearman ?

mtennekes avatar May 28 '25 06:05 mtennekes

If one sets, e.g., outer.bg.color = "red", couldn't then outer.bg switch to TRUE automatically?

Rapsodia86 avatar May 28 '25 13:05 Rapsodia86

Agree that this is most sensible default.

How about bg? Keep it TRUE by default? Or alternatively, set to FALSE unless bg.color is called?

mtennekes avatar May 28 '25 13:05 mtennekes

@mtennekes what's the current bg default?

Nowosad avatar May 28 '25 14:05 Nowosad

Thanks for reporting this @ar-puuk This is probably an unresolved issue from #1078

Apparently, you'll have to set outer.bg = TRUE explicitly:

tmap::tm_shape(NLD_prov) + tmap::tm_polygons(lwd = 1) + tmap::tm_layout(bg.color = "#caeefb", frame = FALSE, outer.bg.color = "#caeefb", outer.bg = TRUE) Currently, bg is TRUE by default and outer.bg is FALSE (see https://github.com/r-tmap/tmap/blob/master/R/tmap_options_defaults.R#L227-L239)

Any reason to change these defaults? @Nowosad @aonojeghuo @Rapsodia86 @nickbearman ?

I think the default could remain FALSE for outer bg and become TRUE once you set a color as suggested by @Rapsodia86 .

aonojeghuo avatar May 28 '25 14:05 aonojeghuo

@Nowosad Currently, bg is TRUE by default and outer.bg is FALSE (see https://github.com/r-tmap/tmap/blob/master/R/tmap_options_defaults.R#L227-L239)

On the contrary, I think a TRUE default would make sense with the default "white" color background. Since, for general and most common mapping purposes, that is the behaviour most users expect.

Also, @mtennekes. I do not know how big of an issue this is, but:

library(tmap)

tmap_options(scale = 0.75)

packageVersion("tmap")
#> [1] '4.1'
packageDate("tmap")
#> [1] "2025-05-18"

tmap_devel_mode()
#> devel.mode: ON

test <- tmap::tm_shape(NLD_prov) +
  tmap::tm_polygons(lwd = 1) +
  tmap::tm_layout(bg.color = "#caeefb", frame = FALSE)

test
test +
  tmap::tm_layout(outer.bg = FALSE)

I was expecting the above to be treated like:

test +
  tmap::tm_layout(outer.margins = c(0,0,0,0))

instead of the current:

test +
  tmap::tm_layout(outer.bg.color = "white")

I am interested in what you think about this behaviour.

ar-puuk avatar May 28 '25 14:05 ar-puuk

On the contrary, I think a TRUE default would make sense with the default "white" color background. Since, for general and most common mapping purposes, that is the behaviour most users expect.

Yes indeed. In some cases a transparent background is useful, e.g. in an infographic, but in general, especially with a frame, you would expect a background. I think (but not 100% sure yet) that this was also the default in v3).

I get your point @ar-puuk with outer.bg = FALSE, but by design this is only whether the outer.bg is coloured or transparent and does not influence the layout/margins. I don't want to change this, because then it would cause inconsistencies in other use cases: e.g. a map without frame where bg is set to FALSE. To be consistent the inner margins should then be set to 0 but I don't think this is a good idea. Agree?

mtennekes avatar May 28 '25 15:05 mtennekes

Both of those sound reasonable. Thanks!

ar-puuk avatar May 28 '25 16:05 ar-puuk

In any case, I think bg, uter.bg, and similar parameters should be somewhat consistent across the tm_layout.

For instance, both of the following are equivalent. i.e, if bg.color has been supplied, the color overrides the bg = FALSE argument. (Which is what I prefer as well).

library(tmap)

tmap_options(scale = 0.75)

packageVersion("tmap")
#> [1] '4.1'

packageDate("tmap")
#> [1] "2025-05-18"

# tmap_devel_mode()

tm_shape(World) + 
  tm_polygons("HPI") + 
  tm_layout(frame = TRUE,
            bg.color = "pink", # background is printed
            earth_boundary = TRUE,space.color = "yellow", frame.r = 20, scale = 2) + 
  tm_crs("auto")
#> [plot mode] fit legend/component: Some legend items or map compoments do not
#> fit well, and are therefore rescaled.
#> ℹ Set the tmap option `component.autoscale = FALSE` to disable rescaling.


tm_shape(World) + 
  tm_polygons("HPI") + 
  tm_layout(frame = TRUE,
            bg = TRUE, bg.color = "pink", # the same as above
            earth_boundary = TRUE, space.color = "yellow", frame.r = 20, scale = 2) + 
  tm_crs("auto")
#> [plot mode] fit legend/component: Some legend items or map compoments do not
#> fit well, and are therefore rescaled.
#> ℹ Set the tmap option `component.autoscale = FALSE` to disable rescaling.


tm_shape(World) + 
  tm_polygons("HPI") + 
  tm_layout(frame = TRUE,
            bg = FALSE, bg.color = "pink", # overrides bg = FALSE when color specified
            earth_boundary = TRUE, space.color = "yellow", frame.r = 20, scale = 2) + 
  tm_crs("auto")
#> [plot mode] fit legend/component: Some legend items or map compoments do not
#> fit well, and are therefore rescaled.
#> ℹ Set the tmap option `component.autoscale = FALSE` to disable rescaling.



tm_shape(World) + 
  tm_polygons("HPI") + 
  tm_layout(frame = TRUE,
            bg = FALSE, # only true way to get rid of background.
            earth_boundary = TRUE, space.color = "yellow", frame.r = 20, scale = 2) + 
  tm_crs("auto")
#> [plot mode] fit legend/component: Some legend items or map compoments do not
#> fit well, and are therefore rescaled.
#> ℹ Set the tmap option `component.autoscale = FALSE` to disable rescaling.

On the other hand, that is not the case with outer.bg Please see the example below. For consistency, I think outer.bg and outer.bg.color should behave the same way the bg and bg.color do.




tm_shape(World) + 
  tm_polygons("HPI") + 
  tm_layout(frame = TRUE, bg.color = "pink",
            outer.bg.color = "red", # outer background is not rendered
            earth_boundary = TRUE, space.color = "yellow", frame.r = 20, scale = 2) + 
  tm_crs("auto")
#> [plot mode] fit legend/component: Some legend items or map compoments do not
#> fit well, and are therefore rescaled.
#> ℹ Set the tmap option `component.autoscale = FALSE` to disable rescaling.


tm_shape(World) + 
  tm_polygons("HPI") + 
  tm_layout(frame = TRUE, bg.color = "pink",
            outer.bg = TRUE, outer.bg.color = "red", # outer background is rendered
            earth_boundary = TRUE, space.color = "yellow", frame.r = 20, scale = 2) + 
  tm_crs("auto")
#> [plot mode] fit legend/component: Some legend items or map compoments do not
#> fit well, and are therefore rescaled.
#> ℹ Set the tmap option `component.autoscale = FALSE` to disable rescaling.


tm_shape(World) + 
  tm_polygons("HPI") + 
  tm_layout(frame = TRUE, bg.color = "pink",
            outer.bg = FALSE, outer.bg.color = "red", # outer background is not rendered
            earth_boundary = TRUE, space.color = "yellow", frame.r = 20, scale = 2) + 
  tm_crs("auto")
#> [plot mode] fit legend/component: Some legend items or map compoments do not
#> fit well, and are therefore rescaled.
#> ℹ Set the tmap option `component.autoscale = FALSE` to disable rescaling.


tm_shape(World) + 
  tm_polygons("HPI") + 
  tm_layout(frame = TRUE, bg.color = "pink",
            outer.bg = FALSE, # this is again expected.
            earth_boundary = TRUE, space.color = "yellow", frame.r = 20, scale = 2) + 
  tm_crs("auto")
#> [plot mode] fit legend/component: Some legend items or map compoments do not
#> fit well, and are therefore rescaled.
#> ℹ Set the tmap option `component.autoscale = FALSE` to disable rescaling.

Created on 2025-05-28 with reprex v2.1.1.9000

Session info

sessioninfo::session_info()
#> Warning in system2("quarto", "-V", stdout = TRUE, env = paste0("TMPDIR=", :
#> running command '"quarto"
#> TMPDIR=C:/Users/pukar/AppData/Local/Temp/RtmpgBEjau/file5e4054dd7013 -V' had
#> status 1
#> ─ Session info ───────────────────────────────────────────────────────────────
#>  setting  value
#>  version  R version 4.5.0 (2025-04-11 ucrt)
#>  os       Windows 11 x64 (build 26100)
#>  system   x86_64, mingw32
#>  ui       RTerm
#>  language (EN)
#>  collate  English_United States.utf8
#>  ctype    English_United States.utf8
#>  tz       America/New_York
#>  date     2025-05-28
#>  pandoc   3.7 @ C:/PROGRA~1/Pandoc/ (via rmarkdown)
#>  quarto   NA @ C:\\PROGRA~1\\Quarto\\bin\\quarto.exe
#> 
#> ─ Packages ───────────────────────────────────────────────────────────────────
#>  package           * version    date (UTC) lib source
#>  abind               1.4-8      2024-09-12 [1] CRAN (R 4.5.0)
#>  base64enc           0.1-3      2015-07-28 [1] CRAN (R 4.5.0)
#>  class               7.3-23     2025-01-01 [2] CRAN (R 4.5.0)
#>  classInt            0.4-11     2025-01-08 [1] CRAN (R 4.5.0)
#>  cli                 3.6.5      2025-04-23 [1] CRAN (R 4.5.0)
#>  codetools           0.2-20     2024-03-31 [1] CRAN (R 4.5.0)
#>  colorspace          2.1-1      2024-07-26 [1] CRAN (R 4.5.0)
#>  cols4all            0.8        2024-10-16 [1] CRAN (R 4.5.0)
#>  crosstalk           1.2.1      2023-11-23 [1] CRAN (R 4.5.0)
#>  curl                6.2.3      2025-04-01 [1] https://ar-puuk.r-universe.dev (R 4.5.0)
#>  data.table          1.17.99    2025-04-09 [1] https://ar-puuk.r-universe.dev (R 4.5.0)
#>  DBI                 1.2.3.9027 2025-03-18 [1] https://ar-puuk.r-universe.dev (R 4.5.0)
#>  dichromat           2.0-0.1    2022-05-02 [1] CRAN (R 4.5.0)
#>  digest              0.6.37     2024-08-19 [1] CRAN (R 4.5.0)
#>  e1071               1.7-16     2024-09-16 [1] CRAN (R 4.5.0)
#>  evaluate            1.0.3      2025-01-10 [1] CRAN (R 4.5.0)
#>  fastmap             1.2.0      2024-05-15 [1] CRAN (R 4.5.0)
#>  fs                  1.6.6      2025-04-12 [1] CRAN (R 4.5.0)
#>  glue                1.8.0      2024-09-30 [1] CRAN (R 4.5.0)
#>  htmltools           0.5.8.1    2024-04-04 [1] CRAN (R 4.5.0)
#>  htmlwidgets         1.6.4      2023-12-06 [1] CRAN (R 4.5.0)
#>  KernSmooth          2.23-26    2025-01-01 [1] CRAN (R 4.5.0)
#>  knitr               1.50       2025-03-16 [1] CRAN (R 4.5.0)
#>  lattice             0.22-7     2025-04-02 [1] CRAN (R 4.5.0)
#>  leafem              0.2.4      2025-05-01 [1] Github (r-spatial/leafem@41cbf71)
#>  leaflegend          1.2.1      2024-05-09 [1] CRAN (R 4.5.0)
#>  leaflet             2.2.2      2024-03-26 [1] CRAN (R 4.5.0)
#>  leaflet.providers   2.0.0      2023-10-17 [1] CRAN (R 4.5.0)
#>  leafsync            0.1.0      2019-03-05 [1] CRAN (R 4.5.0)
#>  lifecycle           1.0.4      2023-11-07 [1] CRAN (R 4.5.0)
#>  logger              0.4.0      2024-10-22 [1] CRAN (R 4.5.0)
#>  lwgeom              0.2-14     2024-02-21 [1] CRAN (R 4.5.0)
#>  magrittr            2.0.3.9000 2025-05-25 [1] Github (tidyverse/magrittr@21093d0)
#>  maptiles            0.10.0     2025-05-11 [1] Github (riatelab/maptiles@8c35b5d)
#>  microbenchmark      1.5.0      2024-09-04 [1] CRAN (R 4.5.0)
#>  png                 0.1-8      2022-11-29 [1] CRAN (R 4.5.0)
#>  proxy               0.4-27     2022-06-09 [1] CRAN (R 4.5.0)
#>  R6                  2.6.1      2025-02-15 [1] CRAN (R 4.5.0)
#>  raster              3.6-32     2025-03-28 [1] CRAN (R 4.5.0)
#>  RColorBrewer        1.1-3      2022-04-03 [1] CRAN (R 4.5.0)
#>  Rcpp                1.0.14     2025-01-12 [1] CRAN (R 4.5.0)
#>  reprex              2.1.1.9000 2025-05-25 [1] Github (tidyverse/reprex@07cd5d7)
#>  rlang               1.1.6.9000 2025-05-25 [1] Github (tidyverse/rlang@bd757b6)
#>  rmarkdown           2.29       2024-11-04 [1] CRAN (R 4.5.0)
#>  rstudioapi          0.17.1     2024-10-22 [1] CRAN (R 4.5.0)
#>  s2                  1.1.9      2025-05-23 [1] CRAN (R 4.5.0)
#>  sessioninfo         1.2.3      2025-02-05 [1] CRAN (R 4.5.0)
#>  sf                  1.0-21     2025-05-15 [1] CRAN (R 4.5.0)
#>  sp                  2.2-0      2025-02-01 [1] CRAN (R 4.5.0)
#>  spacesXYZ           1.5-1      2025-02-10 [1] CRAN (R 4.5.0)
#>  stars               0.6-8      2025-02-01 [1] CRAN (R 4.5.0)
#>  terra               1.8-50     2025-05-09 [1] CRAN (R 4.5.0)
#>  tmap              * 4.1        2025-05-18 [1] Github (r-tmap/tmap@e24262a)
#>  tmaptools           3.2        2025-04-13 [1] https://r-tmap.r-universe.dev (R 4.5.0)
#>  units               0.8-7      2025-03-11 [1] CRAN (R 4.5.0)
#>  viridisLite         0.4.2      2023-05-02 [1] CRAN (R 4.5.0)
#>  withr               3.0.2      2024-10-28 [1] CRAN (R 4.5.0)
#>  wk                  0.9.4      2024-10-11 [1] CRAN (R 4.5.0)
#>  xfun                0.52       2025-04-02 [1] CRAN (R 4.5.0)
#>  XML                 3.99-0.18  2025-01-01 [1] CRAN (R 4.5.0)
#>  xml2                1.3.8      2025-03-14 [1] CRAN (R 4.5.0)
#>  yaml                2.3.10     2024-07-26 [1] CRAN (R 4.5.0)
#> 
#>  [1] C:/Users/pukar/AppData/Local/R/win-library/4.5
#>  [2] C:/Program Files/R/R-4.5.0/library
#>  * ── Packages attached to the search path.
#> 
#> ──────────────────────────────────────────────────────────────────────────────

ar-puuk avatar May 28 '25 16:05 ar-puuk

Yes outer.bgand bg should behave the same (but can have different defaults).

Initially I thought about setting outer.bg = NA, meaning TRUE if and only if outer.bg.color is specified. But I see your point. However I don't fully agree with this:

tm_shape(World) + 
  tm_polygons("HPI") + 
  tm_layout(frame = TRUE,
            bg = FALSE, bg.color = "pink", # overrides bg = FALSE when color specified
            earth_boundary = TRUE, space.color = "yellow", frame.r = 20, scale = 2) + 
  tm_crs("auto")

The devil is in the details: What would you like in this case?

tm_shape(World) + 
  tm_polygons("HPI") + 
  tm_layout(frame = TRUE,
            bg.color = "pink", bg = FALSE,
            earth_boundary = TRUE, space.color = "yellow", frame.r = 20, scale = 2) + 
  tm_crs("auto")

I haven't seen any R function in which the order of named arguments matter (except for self-named like data.frame). So it's tricky.

Fun edge case:

tm_shape(World) + 
  tm_polygons("HPI") + 
  tm_layout(
            frame.color = "pink", frame = FALSE, frame.lwd = 3) + 
  tm_crs("auto")

However, I see the point when the arguments are called in different elements:

tm_shape(World) + 
  tm_polygons("HPI") + 
  tm_layout(bg.color = "pink") +
  tm_layout(bg = FALSE)

# vs 

tm_shape(World) + 
  tm_polygons("HPI") + 
  tm_layout(bg = FALSE) +
  tm_layout(bg.color = "pink") 

Also note that when bg.color can override bg they are not completely independent anymore, something people preferred in https://github.com/r-tmap/tmap/issues/1078. Not a major issue, but still something to consider.

mtennekes avatar May 28 '25 19:05 mtennekes

What would you like in this case?

From your question, I wasn’t sure if you meant the two initial plots should behave differently — i.e., whether the order of the arguments should affect the output. On my machine, the plots render the same, and I don’t see any issue with how bg and bg.color currently behave.

My understanding is: if users want a transparent background, they should set bg = FALSE and not specify a bg.color. Here's a summary table based on current behavior:

bg = NA bg = TRUE bg = FALSE
bg.color specified ? Plots background with specified bg.color Overrides bg = FALSE and plots background with specified bg.color
bg.color not specified ? Plots background with default color #FFFFFF Transparent plot background

Initially I thought about setting outer.bg = NA, meaning TRUE if and only if outer.bg.color is specified. But I see your point. However, I don't fully agree with this:

I’d support outer.bg = NA as the default, as long as it behaves consistently with the table above, and includes a message like:

[!WARNING] "outer.bg = FALSE has been overridden because outer.bg.color was specified"

And finally, On my Windows laptop, I see no difference between the following three examples. All produce a pink background.

library(tmap)

tm_shape(World) + 
  tm_polygons("HPI") + 
  tm_layout(bg.color = "pink") +
  tm_layout(bg = FALSE) # I think you mean in this case bg = FALSE should override bg.color

# vs 

tm_shape(World) + 
  tm_polygons("HPI") + 
  tm_layout(bg = FALSE) +
  tm_layout(bg.color = "pink") # and in this case bg.color should override bg = FALSE

# vs

tm_shape(World) + 
  tm_polygons("HPI") + 
  tm_layout(bg = FALSE, bg.color = "pink") # I still propose this plots pink background with a warning/message

I assume the expected behavior is:

  1. bg = FALSE overrides bg.color (background is transparent).
  2. bg.color overrides bg = FALSE (background is colored).
  3. bg = FALSE, bg.color = "pink" still shows pink background with a warning.

Could you confirm what the intended behavior should be?

In summary:

  • Argument order within a single tm_layout() call should not matter.
  • If tm_layout() is called multiple times, the last call should take precedence.
  • When bg = FALSE and bg.color is set, the background is shown with a warning that bg = FALSE was overridden. The same with outer.bg and outer.bg.color.
  • I prefer bg and outer.bg to behave consistently with similar defaults, though I’m okay with outer.bg = NA if it aligns with the behavior above.
  • I do not know what to do about the frame = FALSE. In my computer frame.color = "pink", frame.lwd = 3 are ignored anyway.

ar-puuk avatar May 28 '25 20:05 ar-puuk

Agree with all of this :-)

I'll stick to bg = TRUE and outer.bg = FALSE as defaults. That is, for the default style white. For cobalt (`+ tm_style("cobalt")) it's set to TRUE.

I'll do the same with frame. In case frame = FALSE, and frame.color or frame.lwd is specified it will override frame to TRUE (now it's indeed being ignored). If frame = FALSE is set by the user (not just as part the style) I'll add the warning.

mtennekes avatar May 29 '25 07:05 mtennekes

@mtennekes -- is the attached outcome expected? In the past, bg.color = NA was removing the background color.

library(tmap)
library(spData)

tm_shape(hawaii) +
  tm_polygons() + 
  tm_title("Hawaii") +
  tm_layout(frame = FALSE, bg.color = NA, 
            title.position = c("LEFT", "BOTTOM"))

Created on 2025-06-27 with reprex v2.1.1

Nowosad avatar Jun 27 '25 12:06 Nowosad

This is expected,. but should be improved. Why is it expected?

  • We've decided earlier that NULL rather than NA will remove the color. Also see tm_shape(hawaii) + tm_polygons(col = NULL)
  • Many tmap options have NA values. Internally this means to-be-imputed. E.g. legend.frame.color, title.color etc. The vast majority of coloured things with color set to NA are imputed with attr.color, which is (with the current set op options) black.

Bottom line: there should be a clear message to inform users about the change NA -> NULL . And somehow we have to make bg.color = NA work. Because this is and outer.bg.color are only options for which this holds, it may be sufficient to catch them manually.

mtennekes avatar Jun 30 '25 08:06 mtennekes

Done. Not perfect but (hopefully) working

mtennekes avatar Jun 30 '25 19:06 mtennekes

Awesome

library(tmap)
library(spData)

tm_shape(hawaii) +
  tm_polygons() + 
  tm_title("Hawaii") +
  tm_layout(frame = FALSE, bg.color = NA, 
            title.position = c("LEFT", "BOTTOM"))
#> → [layout options] use `bg = FALSE` instead of `bg.color = NA`

Nowosad avatar Jul 01 '25 11:07 Nowosad