├── .Rbuildignore ├── .covrignore ├── .github ├── .gitignore └── workflows │ ├── R-CMD-check.yaml │ ├── pkgdown.yaml │ ├── recheck.yaml │ └── test-coverage.yaml ├── .gitignore ├── DESCRIPTION ├── LICENSE ├── NAMESPACE ├── NEWS.md ├── R ├── check_fix.R ├── data.R ├── docs.R ├── global-variables.R ├── messages.R ├── messages_deprecated.R ├── messages_v4_v3.R ├── misc_comp.R ├── misc_crs.R ├── misc_datetime.R ├── misc_from_mapview.R ├── misc_options.R ├── misc_other.R ├── misc_pointLabel.R ├── misc_stars.R ├── misc_symbols.R ├── misc_text.R ├── misc_trans_data.R ├── pkg.R ├── print.R ├── process_breaks.R ├── process_color.R ├── process_legend_format.R ├── process_meta.R ├── qtm.R ├── shapeTM.R ├── shiny.R ├── shp_functions.R ├── spatial_non_supported.R ├── spatial_raster.R ├── spatial_sf.R ├── spatial_sp.R ├── spatial_stars.R ├── spatial_terra.R ├── step1_helper_facets.R ├── step1_helper_meta.R ├── step1_rearrange.R ├── step2_data.R ├── step2_helper_data.R ├── step2_helper_facets.R ├── step3_trans.R ├── step4_helper_legends.R ├── step4_plot.R ├── submit_symbol.R ├── sysdata.rda ├── theme_ps.R ├── tm_add_legend.R ├── tm_animate.R ├── tm_chart.R ├── tm_comp_group.R ├── tm_components.R ├── tm_crs.R ├── tm_element.R ├── tm_facets.R ├── tm_group.R ├── tm_inset.R ├── tm_layers_aux.R ├── tm_layers_iso.R ├── tm_layers_lines.R ├── tm_layers_polygons.R ├── tm_layers_raster.R ├── tm_layers_rgb.R ├── tm_layers_sf.R ├── tm_layers_symbols.R ├── tm_layers_text.R ├── tm_layout.R ├── tm_legend.R ├── tm_options.R ├── tm_plot_order.R ├── tm_pos.R ├── tm_scale_.R ├── tm_scale_bivariate.R ├── tm_shape.R ├── tm_vars.R ├── tm_xylab.R ├── tmapChart.R ├── tmapGpar.R ├── tmapGridArrange.R ├── tmapGridAux.R ├── tmapGridComp.R ├── tmapGridComp_charts.R ├── tmapGridComp_funs.R ├── tmapGridComp_leg_landscape.R ├── tmapGridComp_leg_portrait.R ├── tmapGridInit.R ├── tmapGridLines.R ├── tmapGridPolygons.R ├── tmapGridProviders.R ├── tmapGridRaster.R ├── tmapGridRun.R ├── tmapGridShape.R ├── tmapGridSymbols.R ├── tmapGridText.R ├── tmapGridWrap.R ├── tmapGridXYlab.R ├── tmapGrid_misc.R ├── tmapLeaflet.R ├── tmapLeafletArrange.R ├── tmapLeafletAux.R ├── tmapLeafletComp.R ├── tmapLeafletComp_charts.R ├── tmapLeafletComp_funs.R ├── tmapLeafletComp_leg_portrait.R ├── tmapLeafletInit.R ├── tmapLeafletProviders.R ├── tmapLeafletRun.R ├── tmapLeafletShape.R ├── tmapLeafletShiny.R ├── tmapLeafletXYlab.R ├── tmapLeaflet_layers.R ├── tmapOnLoad.R ├── tmapScaleAsIs.R ├── tmapScaleBivariate.R ├── tmapScaleCategorical.R ├── tmapScaleContinuous.R ├── tmapScaleDiscrete.R ├── tmapScaleIntervals.R ├── tmapScaleRGB.R ├── tmapScaleRank.R ├── tmapScale_.R ├── tmapScale_defaults.R ├── tmapScale_misc.R ├── tmapShape.R ├── tmapShape_misc.R ├── tmapShape_simplification.R ├── tmapSplitShp.R ├── tmapTrans.R ├── tmap_animation.R ├── tmap_arrange.R ├── tmap_export.R ├── tmap_format.R ├── tmap_icons.R ├── tmap_mode.R ├── tmap_options.R ├── tmap_options_defaults.R ├── tmap_palettes.R ├── tmap_providers.R ├── tmap_save.R ├── tmap_style.R ├── tmap_style_catalogue.R ├── tmap_tip.R ├── tme_graphics.R ├── view_format_popups.R └── view_functions.R ├── README.Rmd ├── README.md ├── _pkgdown.yml ├── codecov.yml ├── cran-comments.md ├── data-raw ├── NLD.R ├── World.R ├── World_rivers.R ├── compass_png.R ├── land.R ├── metro.R └── sysdata.R ├── data ├── NLD_dist.rda ├── NLD_muni.rda ├── NLD_prov.rda ├── World.rda ├── World_rivers.rda ├── land.rda └── metro.rda ├── demo └── tutorials │ ├── legend_and_attributes_placement.R │ ├── rmarkdown_tmap.Rmd │ └── sfnetworks.R ├── examples ├── qtm.R ├── tm_add_legend.R ├── tm_animate.R ├── tm_basemap.R ├── tm_chart.R ├── tm_compass.R ├── tm_credits.R ├── tm_crs.R ├── tm_facets.R ├── tm_grid.R ├── tm_inset.R ├── tm_layout.R ├── tm_legend.R ├── tm_lines.R ├── tm_logo.R ├── tm_polygons.R ├── tm_raster.R ├── tm_rgb.R ├── tm_scale_continuous.R ├── tm_scale_rgb.R ├── tm_sf.R ├── tm_shape.R ├── tm_symbols.R ├── tm_text.R ├── tmapOutput.R ├── tmap_animation.R ├── tmap_arrange.R ├── tmap_mode.R ├── tmap_options.R ├── tmap_save.R └── tmap_style.R ├── inst ├── CITATION ├── ieee.csl ├── img │ ├── airplane.png │ ├── city.png │ ├── compass_4star.png │ ├── compass_8star.png │ ├── compass_arrow.png │ ├── compass_radar.png │ └── compass_rose.png └── tmap.bib ├── man ├── Netherlands.Rd ├── World.Rd ├── World_rivers.Rd ├── figures │ ├── README-unnamed-chunk-3-1.png │ ├── README-unnamed-chunk-4-1.png │ ├── README-unnamed-chunk-5-1.png │ ├── logo.png │ ├── shiny_plot.jpg │ └── shiny_view.jpg ├── get_fact_levels_na.Rd ├── get_scale_defaults.Rd ├── land.Rd ├── make_by_vars.Rd ├── metro.Rd ├── print.tm_element.Rd ├── print.tmap.Rd ├── qtm.Rd ├── reexports.Rd ├── renderTmap.Rd ├── shapeTM.Rd ├── theme_ps.Rd ├── tm_add_legend.Rd ├── tm_animate.Rd ├── tm_basemap.Rd ├── tm_chart.Rd ├── tm_comp_group.Rd ├── tm_compass.Rd ├── tm_const.Rd ├── tm_credits.Rd ├── tm_crs.Rd ├── tm_extra_innner_margin.Rd ├── tm_facets.Rd ├── tm_grid.Rd ├── tm_group.Rd ├── tm_inset.Rd ├── tm_iso.Rd ├── tm_layout.Rd ├── tm_legend.Rd ├── tm_lines.Rd ├── tm_logo.Rd ├── tm_minimap.Rd ├── tm_mouse_coordinates.Rd ├── tm_options.Rd ├── tm_plot.Rd ├── tm_plot_order.Rd ├── tm_polygons.Rd ├── tm_pos.Rd ├── tm_raster.Rd ├── tm_rgb.Rd ├── tm_scale.Rd ├── tm_scale_asis.Rd ├── tm_scale_bar.Rd ├── tm_scale_bivariate.Rd ├── tm_scale_categorical.Rd ├── tm_scale_continuous.Rd ├── tm_scale_discrete.Rd ├── tm_scale_intervals.Rd ├── tm_scale_rank.Rd ├── tm_scale_rgb.Rd ├── tm_scalebar.Rd ├── tm_seq.Rd ├── tm_sf.Rd ├── tm_shape.Rd ├── tm_symbols.Rd ├── tm_text.Rd ├── tm_title.Rd ├── tm_vars.Rd ├── tm_view.Rd ├── tm_xlab.Rd ├── tmap-deprecated.Rd ├── tmap-element.Rd ├── tmap-package.Rd ├── tmapAddLayerOptions.Rd ├── tmapGetShapeMeta1.Rd ├── tmapGetShapeMeta2.Rd ├── tmapMode.Rd ├── tmapShape.Rd ├── tmapSplitShp.Rd ├── tmapSubsetShp.Rd ├── tmap_animation.Rd ├── tmap_arrange.Rd ├── tmap_design_mode.Rd ├── tmap_devel_mode.Rd ├── tmap_icons.Rd ├── tmap_internal.Rd ├── tmap_last.Rd ├── tmap_leaflet.Rd ├── tmap_mode.Rd ├── tmap_options.Rd ├── tmap_providers.Rd ├── tmap_save.Rd ├── tmap_style.Rd ├── tmap_style_catalogue.Rd └── tmap_tip.Rd ├── pkgdown └── favicon │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-152x152.png │ ├── apple-touch-icon-180x180.png │ ├── apple-touch-icon-60x60.png │ ├── apple-touch-icon-76x76.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ └── favicon.ico ├── sandbox ├── color_blind_check.R ├── grid_design.R ├── grid_design.svg ├── issues.R ├── issues2.R ├── leaflegend.R ├── load_test_data.R ├── main.R ├── main2.R ├── palette_selection.R ├── palette_selection_old.R ├── test_data.R ├── test_grid.R ├── test_legend.R ├── testing_tmapVars.R ├── tests.R ├── todo-list.txt └── vv2.R ├── tests ├── helper_functions │ ├── facet_test_functions.R │ └── manual_traceback.R ├── testing_aux_layers.Rmd ├── testing_facet_vars.Rmd ├── testing_facetting.Rmd ├── testing_legends.Rmd ├── testing_panels.Rmd ├── testing_scales.Rmd ├── testing_stars.Rmd ├── testthat.R └── testthat │ ├── _snaps │ └── terra-stars.md │ ├── test-terra-stars.R │ ├── test-tm_components.R │ ├── test-tm_layers_aux.R │ ├── test-tm_layers_polygons.R │ ├── test-tm_lines.R │ ├── test-tm_scale.R │ ├── test-tmap_mode.R │ └── test-v3.R ├── tmap.Rproj └── vignettes ├── .gitignore ├── adv_comp_group.Rmd ├── adv_extensions.Rmd ├── adv_groups.Rmd ├── adv_margins.Rmd ├── adv_multivariate.Rmd ├── adv_options.Rmd ├── adv_positions.Rmd ├── adv_shiny.Rmd ├── basics_basemaps.Rmd ├── basics_charts.Rmd ├── basics_components.Rmd ├── basics_exporting.Rmd ├── basics_facets.Rmd ├── basics_layout.Rmd ├── basics_legends.Rmd ├── basics_modes.Rmd ├── basics_scales.Rmd ├── basics_vv.Rmd ├── examples_bubble.Rmd ├── examples_choro_NLD.Rmd ├── examples_choro_World.Rmd ├── examples_gridmaps.Rmd ├── examples_raster.Rmd ├── examples_terrain.Rmd ├── examples_topo_Africa.Rmd ├── ext_cartogram.Rmd ├── ext_glyphs.Rmd ├── ext_mapgl.Rmd ├── ext_networks.Rmd ├── figures ├── shiny_plot.png └── shiny_view.png ├── foundations_crs.Rmd ├── foundations_gg.Rmd ├── versus_ggplot2.Rmd ├── versus_mapsf.Rmd └── versus_mapview.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^CRAN-RELEASE$ 2 | ^Meta$ 3 | ^doc$ 4 | ^.*\.Rproj$ 5 | ^\.Rproj\.user$ 6 | examples 7 | demo 8 | test 9 | sandbox 10 | output 11 | local 12 | LICENSE 13 | README 14 | .Rprofile 15 | gdal-2.1.0 16 | gdal-2.1.0.tar.gz 17 | ubuntu_16_installation.sh 18 | ubuntu_17_installation.sh 19 | ^cran-comments\.md$ 20 | ^codecov\.yml$ 21 | ^_pkgdown\.yml$ 22 | ^docs$ 23 | ^pkgdown$ 24 | ^\.github$ 25 | ^data-raw$ 26 | ^vignettes/tmap-getstarted.Rmd$ 27 | ^tests/testthat/Rplots.pdf$ 28 | ^\.covrignore$ 29 | ^vignettes$ 30 | man/figures/shiny_plot.jpg 31 | man/figures/shiny_view.jpg 32 | ^CRAN-SUBMISSION$ 33 | -------------------------------------------------------------------------------- /.covrignore: -------------------------------------------------------------------------------- 1 | onLoad.R 2 | docs.R 3 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: R-CMD-check 10 | 11 | jobs: 12 | R-CMD-check: 13 | runs-on: ${{ matrix.config.os }} 14 | 15 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 16 | 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | config: 21 | - {os: macos-latest, r: 'release'} 22 | - {os: windows-latest, r: 'release'} 23 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} 24 | - {os: ubuntu-latest, r: 'release'} 25 | - {os: ubuntu-latest, r: 'oldrel-1'} 26 | 27 | env: 28 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 29 | R_KEEP_PKG_SOURCE: yes 30 | 31 | steps: 32 | - uses: actions/checkout@v4 33 | 34 | - uses: r-lib/actions/setup-pandoc@v2 35 | 36 | - uses: r-lib/actions/setup-r@v2 37 | with: 38 | r-version: ${{ matrix.config.r }} 39 | http-user-agent: ${{ matrix.config.http-user-agent }} 40 | use-public-rspm: true 41 | 42 | - uses: r-lib/actions/setup-r-dependencies@v2 43 | with: 44 | extra-packages: any::rcmdcheck 45 | needs: check 46 | 47 | - uses: r-lib/actions/check-r-package@v2 48 | with: 49 | upload-snapshots: true 50 | -------------------------------------------------------------------------------- /.github/workflows/pkgdown.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | release: 9 | types: [published] 10 | workflow_dispatch: 11 | 12 | name: pkgdown 13 | 14 | jobs: 15 | pkgdown: 16 | runs-on: ubuntu-latest 17 | # Only restrict concurrency for non-PR jobs 18 | concurrency: 19 | group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} 20 | env: 21 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 22 | permissions: 23 | contents: write 24 | steps: 25 | - uses: actions/checkout@v4 26 | 27 | - uses: r-lib/actions/setup-pandoc@v2 28 | 29 | - uses: r-lib/actions/setup-r@v2 30 | with: 31 | use-public-rspm: true 32 | 33 | - uses: r-lib/actions/setup-r-dependencies@v2 34 | with: 35 | extra-packages: any::pkgdown, local::. 36 | needs: website 37 | 38 | - name: Build site 39 | run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) 40 | shell: Rscript {0} 41 | 42 | - name: Deploy to GitHub pages 🚀 43 | if: github.event_name != 'pull_request' 44 | uses: JamesIves/github-pages-deploy-action@v4.5.0 45 | with: 46 | clean: false 47 | branch: gh-pages 48 | folder: docs 49 | -------------------------------------------------------------------------------- /.github/workflows/recheck.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | workflow_dispatch: 3 | inputs: 4 | which: 5 | type: choice 6 | description: Which dependents to check 7 | options: 8 | - strong 9 | - most 10 | 11 | name: Reverse dependency check 12 | 13 | jobs: 14 | revdep_check: 15 | name: Reverse check ${{ inputs.which }} dependents 16 | uses: r-devel/recheck/.github/workflows/recheck.yml@v1 17 | with: 18 | which: ${{ inputs.which }} 19 | subdirectory: '' #if your package is in a git subdir 20 | -------------------------------------------------------------------------------- /.github/workflows/test-coverage.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: test-coverage 10 | 11 | permissions: read-all 12 | 13 | jobs: 14 | test-coverage: 15 | runs-on: ubuntu-latest 16 | env: 17 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 18 | 19 | steps: 20 | - uses: actions/checkout@v4 21 | 22 | - uses: r-lib/actions/setup-r@v2 23 | with: 24 | use-public-rspm: true 25 | 26 | - uses: r-lib/actions/setup-r-dependencies@v2 27 | with: 28 | extra-packages: any::covr, any::xml2 29 | needs: coverage 30 | 31 | - name: Test coverage 32 | run: | 33 | cov <- covr::package_coverage( 34 | quiet = FALSE, 35 | clean = FALSE, 36 | install_path = file.path(normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), "package") 37 | ) 38 | covr::to_cobertura(cov) 39 | shell: Rscript {0} 40 | 41 | - uses: codecov/codecov-action@v4 42 | with: 43 | fail_ci_if_error: ${{ github.event_name != 'pull_request' && true || false }} 44 | file: ./cobertura.xml 45 | plugin: noop 46 | disable_search: true 47 | token: ${{ secrets.CODECOV_TOKEN }} 48 | 49 | - name: Show testthat output 50 | if: always() 51 | run: | 52 | ## -------------------------------------------------------------------- 53 | find '${{ runner.temp }}/package' -name 'testthat.Rout*' -exec cat '{}' \; || true 54 | shell: bash 55 | 56 | - name: Upload test results 57 | if: failure() 58 | uses: actions/upload-artifact@v4 59 | with: 60 | name: coverage-test-failures 61 | path: ${{ runner.temp }}/package 62 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Meta 2 | doc 3 | # History files 4 | .Rhistory 5 | .Rapp.history 6 | # Session Data files 7 | .RData 8 | # Example code in package build process 9 | *-Ex.R 10 | # Output files from R CMD build 11 | /*.tar.gz 12 | # Output files from R CMD check 13 | /*.Rcheck/ 14 | # RStudio files 15 | .Rproj.user/ 16 | # produced vignettes 17 | vignettes/tmap-nutshell_files/ 18 | vignettes/*.html 19 | vignettes/*.pdf 20 | vignettes/*.md 21 | # OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3 22 | .httr-oauth 23 | # knitr and R markdown default cache directories 24 | /*_cache/ 25 | /cache/ 26 | # Temporary files created by R markdown 27 | *.utf8.md 28 | *.knit.md 29 | .Rproj.user 30 | # Output 31 | /output/ 32 | # Test output 33 | /tests/testthat/output/ 34 | # R Profile 35 | .Rprofile 36 | # Local files 37 | /local/ 38 | docs 39 | /doc/ 40 | /Meta/ 41 | inst/doc 42 | 43 | tests/testthat/Rplots.pdf 44 | 45 | .DS_Store 46 | -------------------------------------------------------------------------------- /R/check_fix.R: -------------------------------------------------------------------------------- 1 | check_fix = function(sfc, shp_name, reproj, messages) { 2 | s2 = sf::sf_use_s2() 3 | 4 | isLarge = (inherits(sfc, c("sfc_MULTIPOLYGON", "sfc_MULTILINESTRING", "sfc_GEOMETRYCOLLECTION")) && length(sfc) >= 5000) 5 | if (isLarge && messages) message("Checking shape object \"", shp_name, " \". It is large, so it may take a while") 6 | 7 | if (!all(sf::st_is_valid(sfc))) { 8 | checkAgain = FALSE 9 | tryCatch({ 10 | if (messages) message("The shape object \"", shp_name, "\" is invalid", ifelse(reproj, " (after reprojection). ", ". "), "Trying to fix it...") 11 | sfc = sf::st_make_valid(sfc) 12 | }, error = function(e) { 13 | if (messages) message("Unsuccesful attempt with sf::st_make_valid") 14 | checkAgain = TRUE 15 | }) 16 | if (checkAgain || !all(sf::st_is_valid(sfc))) { 17 | suppressMessages(sf::sf_use_s2(!s2)) 18 | .TMAP$set_s2 = s2 19 | sfc = tryCatch({ 20 | sf::st_make_valid(sfc) 21 | }, error = function(e) { 22 | suppressMessages(sf::sf_use_s2(s2)) 23 | cli::cli_warn(c( 24 | "Unable to make {.code {shp_name}} valid.", 25 | i = "Invalid geometries are left out" 26 | )) 27 | isv = which(sf::st_is_valid(sfc)) 28 | sfc = sfc[isv] 29 | attr(sfc, "is_valid") = isv 30 | sfc 31 | }) 32 | if (messages) { 33 | cli::cli_inform(c( 34 | "Shape {shp_name} has been fixed with {.code s2 = {!s2}.", 35 | "If the map doesn't look correct, please run {.code sf::sf_use_s2({!s2})} before running the tmap code again." 36 | )) 37 | } 38 | 39 | } 40 | } 41 | sfc 42 | } 43 | -------------------------------------------------------------------------------- /R/global-variables.R: -------------------------------------------------------------------------------- 1 | # Will need investigating, maybe some are true flags 2 | # i.e. a function that needs to be prefixed, a variable that is unused, or misnamed 3 | # although most seem to come from data.table variables. 4 | # But this will reduce clutter in R CMD CHECK 5 | utils::globalVariables(c( 6 | ".", "..cols", "X__", "Y__", "asp", "attr.color", "bbox", 7 | "between_margin", "bi", "blue", "by1", "by1__", "by2", "by2__", "by2b__", 8 | "by3", "by3__", "ca", "cell.h", "cell.v", "columns", "comp", 9 | "crs", "crs_parameters", "dasp", "devsize", "facet_col", "facet_row", "fl", 10 | "fn", "gp", "green", "grid.labels.format", 11 | "grid.labels.inside_frame", "grid.labels.margin.x", "grid.labels.margin.y", 12 | "grid.labels.pos", "grid.labels.rot", "grid.labels.size", 13 | "grid.labels.space.x", "grid.labels.space.y", "hover", "id", 14 | "ids", "label.show", "labels.cardinal", "labels.inside_frame", 15 | "labels.pos", "labels.rot", "legH", "legW", 16 | "legend.present.auto", "legend.present.fix", "lfmv", "lineH", "lineW", 17 | "main_class", "mapping.args", "mfun", "nby", "ndiscr", "ord__", 18 | "outer.margins", "pages", "panel.label.height", 19 | "panel.labels", "panel.type", "panel.wrap.pos", "panel.xtab.pos", "pos.h", 20 | "pos.h.id", "pos.v", "pos.v.id", "red", "rows", "s1", "s2", "s3", "s4", 21 | "scale.factor", "set_bounds", 22 | "split_geometry_collection", "stack_auto", "t1", 23 | "t2", "t3", "t4", "text.fontface", "text.fontfamily", "title.bg.alpha", 24 | "tmapID__", "vneutral", 25 | "panel.show", "set_to_stack_message", "rev1", "rev2", "rev3", "facet.flip", "panel.show" 26 | )) 27 | 28 | # Add more to silence R CMD CHECK (see if some are false positive) 29 | utils::globalVariables(c( 30 | "aes", "alpha", "col_alpha", "frame", "grid.show", "label.na", "legend", 31 | "legend.bg.alpha", "lin", "m", "n", "overlays_tiles", "show", "show.labels", 32 | "show.warnings", "total", "trans.args", "type", "values", "xlab.rotation", 33 | "xlab.show", "xlab.side", "xlab.space", "xlab.text", "ylab.rotation", 34 | "ylab.show", "ylab.side", "ylab.space", "ylab.text", "z", 35 | "x", "y", "color", "freq", "bin", "bin1", "bin2", 36 | "nitems", "item.width", "page", "stack", 37 | "item.height", "absolute_fontsize", "rc_text", "show", "gp2", "trns", "nbins" 38 | )) 39 | -------------------------------------------------------------------------------- /R/messages_deprecated.R: -------------------------------------------------------------------------------- 1 | v3_tm_format = function(format, code) { 2 | id = "tm_format" 3 | ct = if (code == "") { 4 | paste0("Moreover, the format \"", format, "\" is unknown (also in tmap < 4.0)") 5 | } else { 6 | paste0("Instead, please use `", code, "`") 7 | } 8 | 9 | cli::cli_inform(c( 10 | "{.field [deprecated]} {.code tm_format(\"{format}\")} is deprecated as of tmap 4.0. {ct}" 11 | ), 12 | .frequency_id = id, 13 | .frequency = "always" 14 | ) 15 | } 16 | 17 | v3_tmap_format = function(format) { 18 | id = "tmap_format" 19 | 20 | ct = if (format %in% c("World", "World_wide", "NLD", "NLD_wide")) { 21 | paste0("Moreover, the format \"", format, "\" is unknown (also in tmap < 4.0)") 22 | } else { 23 | "" 24 | } 25 | 26 | cli::cli_inform(c( 27 | "{.field [deprecated]} {.code tmap_format({.str {format}})} is deprecated as of tmap 4.0. {ct}" 28 | ), 29 | .frequency_id = id, 30 | .frequency = "always" 31 | ) 32 | } 33 | 34 | v3_tmap_format_add = function(format) { 35 | id = "tmap_format_add" 36 | cli::cli_inform(c( 37 | "{.field [deprecated]} {.fn tmap_format_add} is deprecated as of tmap 4.0. Please use {.code tm_layout(...)} instead, or create a style with {.fn tmap_options_save}" 38 | ), 39 | .frequency_id = id, 40 | .frequency = "always" 41 | ) 42 | } 43 | -------------------------------------------------------------------------------- /R/misc_from_mapview.R: -------------------------------------------------------------------------------- 1 | is_rstudio = function () { 2 | if (requireNamespace("rstudioapi", quietly = TRUE)) { 3 | rstudioapi::isAvailable() && rstudioapi::versionInfo()$mode != 4 | "vscode" 5 | } 6 | else { 7 | FALSE 8 | } 9 | } 10 | 11 | get_ide = function () { 12 | if (is_rstudio()) { 13 | return("rstudio") 14 | } 15 | else if (is_vscode()) { 16 | return("vscode") 17 | } 18 | else { 19 | "other" 20 | } 21 | } 22 | 23 | ## need to assign global variable .vsc 24 | utils::globalVariables(c(".vsc")) 25 | 26 | is_vscode = function() { 27 | exists(".vsc") && exists("attach", envir = .vsc) 28 | } 29 | 30 | get_url_dir = function (url) gsub("file://|/index.html", "", url) 31 | -------------------------------------------------------------------------------- /R/misc_symbols.R: -------------------------------------------------------------------------------- 1 | pchs = stats::setNames(c(seq(0L, 25L, 1L), seq(100L, 109L, 1L)), 2 | c(c('open-rect', 'open-circle', 'open-triangle', 'simple-plus', 3 | 'simple-cross', 'open-diamond', 'open-down-triangle', 'cross-rect', 4 | 'simple-star', 'plus-diamond', 'plus-circle', 'hexagram', 'plus-rect', 5 | 'cross-circle', 'triangle-rect', 'solid-rect', 'solid-circle-md', 6 | 'solid-triangle', 'solid-diamond', 'solid-circle-bg', 'solid-circle-sm', 'circle', 7 | 'rect', 'diamond', 'triangle', 'down-triangle' 8 | ), 9 | c('rect', 'circle', 'triangle', 'plus', 'cross', 'diamond', 'star', 'stadium', 'line', 'polygon') 10 | )) 11 | 12 | 13 | get_pch_names = function(x) { 14 | if (is.numeric(x)) { 15 | if (!(all(x %in% pchs | x > 999))) { 16 | cli::cli_abort("Unknown symbol values") 17 | } 18 | y = names(pchs)[match(x, pchs)] 19 | y[x > 999] = x[x>999] 20 | y 21 | } else { 22 | if (!all(x %in% names(pchs))) { 23 | unknown <- unique(x[!x %in% names(pchs)]) 24 | cli::cli_abort("Unknown symbol values: {.val {unknown}}") 25 | } 26 | x 27 | } 28 | } 29 | # 30 | # get_pch_number = function(x) { 31 | # if (is.numeric(x)) { 32 | # if (!(all(x %in% pchs | x > 999))) stop("Unknown symbol values", call. = FALSE) 33 | # x 34 | # } else { 35 | # if (!all(x %in% names(pchs))) stop("Unknown symbol values", call. = FALSE) 36 | # unname(pchs[match(x, names(pchs))]) 37 | # } 38 | # } 39 | -------------------------------------------------------------------------------- /R/misc_trans_data.R: -------------------------------------------------------------------------------- 1 | trans_log = list( 2 | fun = function(x, base = exp(1)) log(x, base), 3 | rev = function(x, base = exp(1)) base^x, 4 | domain = c(1e-100, Inf) 5 | ) 6 | 7 | # trans_logistic = list( 8 | # fun = function(x) { 9 | # 1/ (1 + exp(-x)) 10 | # }, 11 | # rev = function(x) { 12 | # log(x/(1 - x)) 13 | # }, 14 | # domain = c(-Inf, Inf) 15 | # ) 16 | 17 | 18 | trans_sqrt = list( 19 | fun = sqrt, 20 | rev = function(x) x^2, 21 | domain = c(0, Inf) 22 | ) 23 | 24 | 25 | trans_log1p = list( 26 | fun = log1p, 27 | rev = expm1, 28 | domain = c(0, Inf) 29 | ) 30 | 31 | trans_pseudo_log = list( 32 | fun = function(x, base = exp(1), sigma = 1) asinh(x/(2 * sigma))/log(base), 33 | rev = function(x, base = exp(1), sigma = 1) 2 * sigma * sinh(x * log(base)), 34 | #d_transform = function(x) 1/(sqrt(4 + x^2/pseudo_log_sigma^2) * pseudo_log_sigma * log(pseudo_log_base)) 35 | #d_inverse = function(x) 2 * pseudo_log_sigma * cosh(x * log(pseudo_log_base)) * log(pseudo_log_base)) 36 | domain = c(-Inf, Inf) 37 | ) 38 | 39 | trans_identity = list( 40 | fun = function(x) x, 41 | rev = function(x) x, 42 | domain = c(-Inf, Inf) 43 | ) 44 | -------------------------------------------------------------------------------- /R/pkg.R: -------------------------------------------------------------------------------- 1 | #' Thematic Map Visualization 2 | #' 3 | #' Thematic maps are geographical maps in which spatial data distributions are visualized. 4 | #' This package offers a flexible, layer-based, and easy to use approach to create 5 | #' thematic maps, such as choropleths and bubble maps. It is based on the grammar 6 | #' of graphics, and resembles the syntax of ggplot2. 7 | #' 8 | #' @author Martijn Tennekes \email{mtennekes@@gmail.com} 9 | #' @seealso \href{https://r-tmap.github.io/tmap/index.html}{Main documentation} 10 | #' @concept GIS 11 | #' @concept thematic maps 12 | #' @concept statistical maps 13 | #' @concept choropleth 14 | #' @concept bubble map 15 | #' @references Tennekes, M., 2018, {tmap}: Thematic Maps in {R}, Journal of Statistical Software, 84(6), 1-39, \doi{10.18637/jss.v084.i06} 16 | "_PACKAGE" 17 | -------------------------------------------------------------------------------- /R/process_legend_format.R: -------------------------------------------------------------------------------- 1 | process_label_format = function(lf, mlf) { 2 | if (is.function(lf)) lf = list(fun = lf) 3 | 4 | to_be_assigned = setdiff(names(mlf), names(lf)) 5 | big.num.abbr.set = "big.num.abbr" %in% names(lf) 6 | lf[to_be_assigned] = mlf[to_be_assigned] 7 | attr(lf, "big.num.abbr.set") = big.num.abbr.set 8 | lf 9 | } 10 | 11 | # process_popup_format = function(gpf, gtlf, vars, show.warnings) { 12 | # # check if g$legend.format is list of lists or functions 13 | # islist = is.list(gpf) && length(gpf)>0 && is.list(gpf[[1]]) 14 | # 15 | # if (!islist) { 16 | # process_legend_format(gpf, gtlf, nx=1) 17 | # } else { 18 | # nms = names(gpf) 19 | # if (is.na(vars[1])) { 20 | # if (show.warnings) warning("popup.vars not specified whereas popup.format is a list", call. = FALSE) 21 | # return(process_legend_format(gpf[[1]], gtlf, nx=1)) 22 | # } 23 | # if (!all(nms %in% vars)) stop("popup.format names do not correspond to popup.vars", call. = FALSE) 24 | # lapply(vars, function(v) { 25 | # if (v %in% nms) { 26 | # process_legend_format(gpf[[v]], gtlf, nx=1) 27 | # } else { 28 | # process_legend_format(list(), gtlf, nx=1) 29 | # } 30 | # }) 31 | # } 32 | # } 33 | -------------------------------------------------------------------------------- /R/shapeTM.R: -------------------------------------------------------------------------------- 1 | #' Internal tmap function to create a tmap shape 2 | #' 3 | #' Internal tmap function to create a tmap shape 4 | #' 5 | #' @param shp Shape file 6 | #' @param tmapID tmap Identifier 7 | #' @param bbox bounding box 8 | #' @export 9 | #' @keywords internal 10 | shapeTM = function(shp, tmapID = NULL, bbox = NULL, ...) { 11 | # filter empty geometries 12 | if (inherits(shp, "sfc")) { 13 | is_empty = sf::st_is_empty(shp) 14 | shp = shp[!is_empty] 15 | tmapID = tmapID[!is_empty] 16 | } 17 | x = structure(list(shp = shp, tmapID = tmapID, bbox = bbox, ...), class = c("shapeTM", "list")) 18 | } 19 | 20 | 21 | stm_bbox = function(shpTM, tmapID, crs) { 22 | bbox = shpTM$bbox 23 | 24 | if (!is.null(bbox$x)) { 25 | if (identical(bbox$x, "FULL")) { 26 | bbox$x = sf::st_bbox(c(xmin = -180, xmax = 180, ymax = 90, ymin = -90), crs = sf::st_crs(4326)) 27 | } 28 | # to make sure the supplied bounding box will be converted in the correct crs 29 | bbox$projection = crs 30 | } else { 31 | shp = shpTM$shp 32 | shpID = shpTM$tmapID 33 | 34 | if (length(tmapID) == 0) return(sf::st_bbox(NA_real_)) 35 | # filter the shape? 36 | do_filter = (length(tmapID) != length(shpID)) || (!all(tmapID == shpID)) 37 | 38 | if (do_filter) { 39 | ids = match(tmapID, shpID) 40 | 41 | if (inherits(shp, "dimensions")) { 42 | m = matrix(NA, nrow = nrow(shp), ncol = ncol(shp)) 43 | m[ids] = TRUE 44 | 45 | s = stars::st_as_stars(list(values = m), dimensions = shp) 46 | shp = trim_stars(s) 47 | } else if (inherits(shp, c("sf", "sfc"))) { 48 | shp = shp[ids] 49 | } else { 50 | stop("unknown shape class") 51 | } 52 | } 53 | bbox$x = sf::st_bbox(shp) 54 | } 55 | do.call(tmaptools::bb, bbox) 56 | 57 | } 58 | 59 | 60 | stm_merge_bbox = function(blist) { 61 | crs = sf::st_crs(blist[[1]]) 62 | m = do.call(rbind, blist) 63 | sf::st_bbox(c(apply(m[, 1:2, drop = FALSE], 2, min), apply(m[, 3:4, drop = FALSE], 2, max)), crs = crs) 64 | } 65 | 66 | 67 | stm_bbox_all = function(shpTM) { 68 | sf::st_bbox(shpTM$shp) 69 | } 70 | 71 | bb_ext = function(bbx, ext = c(0, 0, 0, 0)) { 72 | dx = bbx[3] - bbx[1] 73 | dy = bbx[4] - bbx[2] 74 | 75 | bbx[2] = bbx[2] - ext[1] * dy 76 | bbx[1] = bbx[1] - ext[2] * dx 77 | bbx[4] = bbx[4] + ext[3] * dy 78 | bbx[3] = bbx[3] + ext[4] * dx 79 | bbx 80 | } 81 | 82 | bb_asp = function(bbx, asp) { 83 | sasp = get_asp_ratio(bbx) 84 | 85 | fact = sasp / asp 86 | 87 | if (fact > 1) { 88 | cy = mean(bbx[c(2,4)]) 89 | dy = bbx[4] - bbx[2] 90 | dy2 = dy * fact 91 | bbx[2] = cy - (dy2 / 2) 92 | bbx[4] = cy + (dy2 / 2) 93 | } else if (fact < 1) { 94 | cx = mean(bbx[c(1,3)]) 95 | dx = bbx[3] - bbx[1] 96 | dx2 = dx / fact 97 | bbx[1] = cx - (dx2 / 2) 98 | bbx[3] = cx + (dx2 / 2) 99 | } 100 | bbx 101 | } 102 | 103 | bb_ll_valid = function(bbx) { 104 | bbx[2] = max(bbx[2], -90) 105 | bbx[4] = min(bbx[4], 90) 106 | bbx 107 | } 108 | -------------------------------------------------------------------------------- /R/shp_functions.R: -------------------------------------------------------------------------------- 1 | assign_values = function(shp, dt, column) { 2 | shp[[1]][dt$tmapID__] = dt[[column]] 3 | shp 4 | } 5 | 6 | -------------------------------------------------------------------------------- /R/spatial_non_supported.R: -------------------------------------------------------------------------------- 1 | #' @export 2 | tmapGetShapeMeta1.default = function(shp, o) { 3 | stop("Specified shp argument of tm_shape is a ", class(shp)[1], ", which is not a recognized/supported spatial data class.", call. = FALSE) 4 | } 5 | 6 | #' @export 7 | tmapGetShapeMeta2.default = function(shp, smeta, o) { 8 | stop("Specified shp argument of tm_shape is a ", class(shp)[1], ", which is not a recognized/supported spatial data class.", call. = FALSE) 9 | } 10 | 11 | #' @export 12 | tmapSubsetShp.default = function(shp, vars) { 13 | stop("Specified shp argument of tm_shape is a ", class(shp)[1], ", which is not a recognized/supported spatial data class.", call. = FALSE) 14 | } 15 | 16 | #' @export 17 | tmapShape.default = function(shp, is.main, crs, bbox, unit, filter, shp_name, smeta, o, tmf) { 18 | stop("Specified shp argument of tm_shape is a ", class(shp)[1], ", which is not a recognized/supported spatial data class.", call. = FALSE) 19 | } 20 | -------------------------------------------------------------------------------- /R/spatial_raster.R: -------------------------------------------------------------------------------- 1 | #' @export 2 | tmapShape.Raster = function(shp, is.main, crs, bbox, unit, filter, shp_name, smeta, o, tmf) { 3 | tmapShape.SpatRaster(terra::rast(shp), is.main, crs, bbox, unit, filter, shp_name, smeta, o, tmf) 4 | } 5 | 6 | #' @export 7 | tmapSubsetShp.Raster = function(shp, vars) { 8 | tmapSubsetShp.SpatRaster(terra::rast(shp), vars) 9 | } 10 | 11 | #' @export 12 | tmapGetShapeMeta1.Raster = function(shp, o) { 13 | tmapGetShapeMeta1.SpatRaster(terra::rast(shp), o) 14 | } 15 | -------------------------------------------------------------------------------- /R/spatial_sp.R: -------------------------------------------------------------------------------- 1 | #' @export 2 | tmapShape.Spatial = function(shp, is.main, crs, bbox, unit, filter, shp_name, smeta, o, tmf) { 3 | tmapShape.sf(as(shp, "sf"), is.main, crs, bbox, unit, filter, shp_name, smeta, o, tmf) 4 | } 5 | 6 | #' @export 7 | tmapSubsetShp.Spatial = function(shp, vars) { 8 | tmapSubsetShp.sf(as(shp, "sf"), vars) 9 | } 10 | 11 | 12 | #' @export 13 | tmapGetShapeMeta1.Spatial = function(shp, o) { 14 | tmapGetShapeMeta1.SpatRaster(as(shp, "sf"), o) 15 | } 16 | -------------------------------------------------------------------------------- /R/step1_helper_meta.R: -------------------------------------------------------------------------------- 1 | preprocess_meta_step1 = function(o) { 2 | within(o, { 3 | 4 | pc = list(sepia_intensity=color.sepia_intensity, saturation=color.saturation, color_vision_deficiency_sim=color_vision_deficiency_sim) 5 | color.sepia_intensity = NULL 6 | color.saturation = NULL 7 | color_vision_deficiency_sim = NULL 8 | 9 | # color options: replace NA with attr.color 10 | # process colors: apply sepia and cvd sim 11 | for (nm in names(o)[grep("color(\\.light|\\.dark)?$", names(o))]) { 12 | assign(nm, local({ 13 | x = get(nm) 14 | if (is.na(x)) x = attr.color 15 | do.call("process_color", c(list(col=x), pc)) 16 | })) 17 | } 18 | 19 | outer.margins = rep(outer.margins, length.out = 4) 20 | 21 | inner.margins.extra = rep(inner.margins.extra, length.out = 4) 22 | 23 | inner.margins = if (is.list(inner.margins)) { 24 | lapply(inner.margins, function(im) { 25 | rep(im, length.out = 4) + inner.margins.extra 26 | }) 27 | } else { 28 | rep(inner.margins, length.out = 4) + inner.margins.extra 29 | } 30 | inner.margins.extra = NULL 31 | 32 | attr.color.light = is_light(attr.color) 33 | panel.label.rot = rep_len(panel.label.rot, 4L) 34 | 35 | # earth.bounds = if (is.logical(earth_boundary)) { 36 | # c(-180, -90, 180, 90) 37 | # } else { 38 | # as.vector(bb(earth_boundary)) 39 | # } 40 | # earth_boundary = !isFALSE(earth_boundary) 41 | 42 | earth_boundary.lwd = earth_boundary.lwd * scale 43 | #frame.lwd = frame.lwd * scale 44 | 45 | # set font face and family 46 | 47 | 48 | ## inherit values 49 | 50 | # fontface 51 | for (nm in names(o)[grep("fontface", names(o), fixed = TRUE)]) if (is.null(get(nm))) assign(nm, text.fontface) 52 | for (nm in names(o)[grep("fontfamily", names(o), fixed = TRUE)]) if (is.null(get(nm))) assign(nm, text.fontfamily) 53 | 54 | # special case: fontface is a visual variable. Therefore, check if value.const etc is NULL if so, replace 55 | if (is.null(value.const$fontface)) value.const$fontface = text.fontface 56 | if (is.null(value.blank$fontface)) value.blank$fontface = text.fontface 57 | if (is.null(value.na$fontface)) value.na$fontface = text.fontface 58 | if (is.null(value.null$fontface)) value.null$fontface = text.fontface 59 | 60 | 61 | 62 | }) 63 | } 64 | -------------------------------------------------------------------------------- /R/submit_symbol.R: -------------------------------------------------------------------------------- 1 | submit_symbols = function(x, grid, args) { 2 | if (any(vapply(x, is.null, logical(1)))) stop("one of more shapes are NULL") 3 | shapeLib = get("shapeLib", envir = .TMAP) 4 | justLib = get("justLib", envir = .TMAP) 5 | n = length(x) 6 | id = 999 + length(shapeLib) 7 | if (grid) { 8 | # symbols as grobs 9 | just_items = lapply(x, function(xs) { 10 | if (args$just.override) { 11 | args$just 12 | } else if ("iconUrl" %in% names(xs)) { 13 | if (all(c("iconWidth", "iconHeight", "iconAnchorX", "iconAnchorY") %in% names(xs))) { 14 | c(1-(xs$iconAnchorX / xs$iconWidth), xs$iconAnchorY / xs$iconHeight) 15 | } else NA 16 | } else NA 17 | }) 18 | 19 | items = lapply(x, function(xs) { 20 | if ("iconUrl" %in% names(xs)) { 21 | grb = icon2grob(xs) 22 | # take first one 23 | if (is.grob(grb)) grb else grb[[1]] 24 | } else if (is.grob(xs)) { 25 | xs 26 | } else NA 27 | }) 28 | } else { 29 | # symbols as images 30 | items = lapply(x, function(xs) { 31 | ic = if ("iconUrl" %in% names(xs)) { 32 | split_icon(xs)[[1]] 33 | } else if (is.grob(xs)) { 34 | grob2icon(xs, args$grob.dim, args$just) 35 | } else NA 36 | 37 | # add anchor based on just specs 38 | if (all(c("iconWidth", "iconHeight") %in% names(ic)) && 39 | ((!any(c("iconAnchorX", "iconAnchorY") %in% names(ic))) || args$just.override)) { 40 | ic$iconAnchorX = ic$iconWidth * (1-args$just[1]) 41 | ic$iconAnchorY = ic$iconHeight * args$just[2] 42 | } 43 | ic 44 | }) 45 | just_items = as.list(rep(NA, n)) 46 | } 47 | 48 | numbers = is.na(items) 49 | 50 | if (all(numbers)) return(unlist(x, use.names = FALSE)) 51 | 52 | new_id = id + 1:sum(!numbers) 53 | 54 | x2 = integer(n) 55 | x2[numbers] = unlist(x[numbers], use.names = FALSE) 56 | x2[!numbers] = new_id 57 | 58 | shapeLib = c(shapeLib, items[!numbers]) 59 | justLib = c(justLib, just_items[!numbers]) 60 | assign("shapeLib", shapeLib, envir = .TMAP) 61 | assign("justLib", justLib, envir = .TMAP) 62 | names(x2) = names(x) 63 | x2 64 | } 65 | 66 | -------------------------------------------------------------------------------- /R/sysdata.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/R/sysdata.rda -------------------------------------------------------------------------------- /R/tm_animate.R: -------------------------------------------------------------------------------- 1 | #' Specify an animation (experimental) 2 | #' 3 | #' @description `tm_animate` 4 | #' 5 | #' @param by group by variable used to create the animation frames. Note: it is called `pages` in the core function [tm_facets()]. 6 | #' @param nframes number of animation frames. This only app 7 | #' @param fps frames per second. Default: 30 for `tm_facets_animate` and 2 for `tm_facets_animate_slow`. 8 | #' @param play how should the animation be played? One of `"loop"`, `"pingpong"`, and `"once"` 9 | #' @param dpr device pixel ratio. The ratio between the physical pixel density of a device and its logical pixel density. 10 | #' @param ... passed on to [tm_facets()] 11 | #' @export 12 | #' @seealso [tm_facets()] which is the core function, and [tmap_animation()] used to save the animation 13 | #' @rdname tm_animate 14 | tm_animate = function(by = "VARS__", 15 | nframes = 60L, 16 | fps = 20L, 17 | play = c("loop", "pingpong", "once"), 18 | dpr = 2, 19 | ...) { 20 | args = list(...) 21 | args_called = names(rlang::call_match()[-1]) 22 | 23 | play = match.arg(play) 24 | 25 | tm = do.call("tm_facets", c(list(pages = by, type = NA, animate = TRUE, nframes = nframes, fps = fps, play = play, dpr = dpr), args[setdiff(names(args), "type")])) 26 | tm[[1]]$calls = args_called 27 | tm 28 | } 29 | 30 | #' @export 31 | #' @rdname tm_animate 32 | tm_animate_slow = function(by = "VARS__", 33 | nframes = 60L, 34 | fps = 2L, 35 | play = c("loop", "pingpong", "once"), 36 | dpr = 2, 37 | ...) { 38 | args = list(...) 39 | args_called = names(rlang::call_match()[-1]) 40 | 41 | play = match.arg(play) 42 | 43 | tm = do.call("tm_facets", c(list(pages = by, type = NA, animate = TRUE, nframes = nframes, fps = fps, play = play, dpr = dpr), args[setdiff(names(args), "type")])) 44 | tm[[1]]$calls = args_called 45 | tm 46 | } 47 | -------------------------------------------------------------------------------- /R/tm_comp_group.R: -------------------------------------------------------------------------------- 1 | #' Group components 2 | #' 3 | #' @param group_id id of the component group. Refers to the `group_id` argument of each component function, such as [tm_legend()] and [tm_title()]. 4 | #' @param position The position specification of the components in this group: an object created with `tm_pos_in()` or `tm_pos_out()`. Or, as a shortcut, a vector of two values, specifying the x and y coordinates. The first is `"left"`, `"center"` or `"right"` (or upper case, meaning tighter to the map frame), the second `"top"`, `"center"` or `"bottom"`. Numeric values are also supported, where 0, 0 means left bottom and 1, 1 right top. See also \href{https://r-tmap.github.io/tmap/articles/adv_positions}{vignette about positioning}. 5 | #' @param stack stacking `"horizontal"` or `"vertical"` 6 | #' @param frame_combine put frame around all components that are drawn on the same location. Whether a frame is drawn is still decided by the `frame` argument of the 'main' (first) component. 7 | #' @param equalize in case `frame_combine` is `FALSE`, should the separate frames be equalized, i.e. have the same width (when stacked vertically) or height (when stacked horizontally)? 8 | #' @param resize_as_group in case a component if rescaled because of the limited space, rescale the other components proportionally? 9 | #' @param stack_margin Margin between components 10 | #' @param offset Offset margin between frame and the components block 11 | #' @param frame Should a frame be drawn? By default `TRUE` for legends, charts and insets, and `FALSE` otherwise. 12 | #' @param frame.color frame color 13 | #' @param frame.alpha frame alpha transparancy 14 | #' @param frame.lwd frame line width 15 | #' @param frame.r Radius of the rounded frame corners. 0 means no rounding. 16 | #' @param bg Background color the components block. Is usually set in each component function, but if specified here, it will overwrite them. 17 | #' @param bg.color Background color the components block. Is usually set in each component function, but if specified here, it will overwrite them. 18 | #' @param bg.alpha Background alpha transparency of the components block. Is usually set in each component function, but if specified here, it will overwrite them. 19 | #' @return A [`tmap-element`] 20 | #' @export 21 | tm_comp_group = function( 22 | group_id, 23 | position, 24 | stack, # was 'stack' in each tm_legend or tm_ function 25 | frame_combine, 26 | equalize, 27 | resize_as_group, # from tm_legend/tm_. 28 | stack_margin, # margin between components 29 | offset, # offset margin 30 | frame , 31 | frame.color, 32 | frame.alpha, 33 | frame.lwd, 34 | frame.r, 35 | bg, 36 | bg.color, 37 | bg.alpha) { 38 | args = lapply(as.list(rlang::call_match()[-1]), eval, envir = parent.frame()) 39 | 40 | optname = paste0("component_", group_id) 41 | x = structure(list(args), names= optname) 42 | do.call(tm_options, x) 43 | } 44 | -------------------------------------------------------------------------------- /R/tm_group.R: -------------------------------------------------------------------------------- 1 | #' Layer group control 2 | #' 3 | #' Controls the layer groups in interactive maps (view mode): the layer control box (radio buttons or check boxes) and at which zoom levels the layers are displayed at. 4 | #' 5 | #' @param name group name that corresponds with the group name specified in the layer functions (e.g. [tm_polygons()]) 6 | #' @param control The group control determines how 7 | #' layer groups can be switched on and off. Options: `"radio"` for radio 8 | #' buttons (meaning only one group can be shown), `"check"` for check boxes 9 | #' (so multiple groups can be shown), and `"none"` for no control 10 | #' (the group cannot be (de)selected). 11 | #' @param zoom_levels The zoom levels at which the group is displays at. When specified `control` will be set to `"none"`. 12 | #' @seealso \href{https://r-tmap.github.io/tmap/articles/adv_groups}{vignette about layer groups} 13 | #' @export 14 | tm_group = function(name, control = NA, zoom_levels = NA) { 15 | optname = paste0("view_group_", name) 16 | x = structure(list(list(name = name, control = control, zoom_levels = zoom_levels)), names= optname) 17 | do.call(tm_options, x) 18 | } 19 | -------------------------------------------------------------------------------- /R/tm_inset.R: -------------------------------------------------------------------------------- 1 | #' Map component: inset maps and other objects 2 | #' 3 | #' Map component that adds an inset object, e.g. a mini map 4 | #' 5 | #' @param x object to draw. Can be: bounding box, tmap object, ggplot2 object, grob object, image file name. 6 | #' @param height height of the component in number of text line heights. 7 | #' @param width width of the component in number of text line heights. 8 | #' @param margins margins 9 | #' @param between_margin Margin between 10 | #' @inheritParams tm_title 11 | #' @example ./examples/tm_inset.R 12 | #' @export 13 | tm_inset = function(x = NULL, 14 | height, 15 | width, 16 | margins, 17 | between_margin, 18 | position, 19 | group_id, 20 | frame, frame.color, frame.alpha, frame.lwd, frame.r, bg, bg.color, bg.alpha, 21 | z) { 22 | args = lapply(as.list(rlang::call_match()[-1]), eval, envir = parent.frame()) 23 | 24 | args$group_id = args$group_id %||% NA_character_ 25 | args$z = args$z %||% NA_integer_ 26 | 27 | cls = if (is.null(x) || (inherits(x, "bbox"))) { 28 | "map" 29 | } else if (inherits(x, "tmap")) { 30 | "tmap" 31 | } else if (inherits(x, "ggplot")) { 32 | "gg" 33 | } else if (inherits(x, c("grob", "gList"))) { 34 | "grob" 35 | } else if (is.character(x)) { 36 | "image" 37 | } else { 38 | stop("Unsupported object") 39 | } 40 | 41 | cls2 = paste0("tm_inset_", cls) 42 | 43 | tm_element_list(do.call(tm_element, c(args, list(subclass = c(cls2, "tm_inset", "tm_component"))))) 44 | } 45 | -------------------------------------------------------------------------------- /R/tm_layers_iso.R: -------------------------------------------------------------------------------- 1 | #' Map layer: iso (contour) 2 | #' 3 | #' Map layer that draws iso (contour) lines. Stack of [tm_lines()] and [tm_labels_highlighted]. 4 | #' 5 | #' @param col `r .doc_vv("col")` 6 | #' @param text `r .doc_vv("text")` 7 | #' @param ... passed on to [tm_lines()] and [tm_labels_highlighted()]. For the text color and alpha transparency of the text labels, please use `text_col` and `text_alpha` instead of `col` and `col_alpha`. 8 | #' @param options_lines The options for [tm_lines()] 9 | #' @param options_labels The options for [tm_labels_highlighted()] 10 | #' @export 11 | tm_iso = function(col = tm_const(), 12 | text = tm_vars(x = 1), 13 | ..., 14 | options_lines = opt_tm_lines(), 15 | options_labels = opt_tm_labels()) { 16 | args = list(...) 17 | args$options = NULL 18 | argsL = args[intersect(names(formals("tm_lines")), names(args))] 19 | 20 | nms_col = c("col", "col.scale", "col.legend", "col.chart", "col.free", "col_alpha", "col_alpha.scale", "col_alpha.legend", "col_alpha.chart", "col_alpha.free") 21 | 22 | # update args for labels 23 | args[nms_col] = NULL 24 | rename_id = names(args) %in% paste0("text_", nms_col) 25 | 26 | names(args)[rename_id] = substr(names(args)[rename_id], 6, nchar(names(args)[rename_id])) 27 | argsT = args[intersect(names(formals("tm_labels_highlighted")), names(args))] 28 | 29 | do.call("tm_lines", c(list(col=col, options = options_lines), argsL)) + 30 | do.call("tm_labels_highlighted", c(list(text=text, options = options_labels), argsT)) 31 | } 32 | -------------------------------------------------------------------------------- /R/tm_plot_order.R: -------------------------------------------------------------------------------- 1 | #' Determine plotting order of features 2 | #' 3 | #' Determine plotting order of features. 4 | #' 5 | #' @param aes Visual variable for which the values determine the plotting order. 6 | #' Example: bubble map where the `"size"` aesthetic is used. 7 | #' A data variable (say population) is mapped via a continuous scale ([tm_scale_continuous()]) 8 | #' to bubble sizes. The bubbles are plotted in order of size. 9 | #' How is determined by the other arguments. Use `"DATA"` to keep the same 10 | #' order as in the data. Another special value are `"AREA"` and `"LENGTH"` 11 | #' which are preserved for polygons and lines respectively: rather than a data 12 | #' variable the polygon area / line lengths determines the plotting order. 13 | #' @param reverse Logical that determines whether the visual values are plotted 14 | #' in reversed order. The visual values (specified with tmap option `"values.var"`) 15 | #' are by default reversed, so plotted starting from the last value. 16 | #' In the bubble map example, this means that large bubbles are plotted first, 17 | #' hence at the bottom. 18 | #' @param na.order Where should features be plotted that have an `NA` value for 19 | #' (at least) one other aesthetic variable? In the (order) `"mix"`, at the `"bottom"`, 20 | #' or on `"top"`? In the bubble map example: if fill color is missing for some bubble, 21 | #' where should those bubbles be plotted? 22 | #' @param null.order Where should non-selected (aka null) features be plotted? 23 | #' @param null.below.na Should null features be plotted below NA features? 24 | #' @export 25 | tm_plot_order = function(aes, reverse = TRUE, na.order = c("mix", "bottom", "top"), null.order = c("bottom", "mix", "top"), null.below.na = TRUE) { 26 | na.order = match.arg(na.order) 27 | null.order = match.arg(null.order) 28 | structure(list(aes = aes, reverse = reverse, na.order = na.order, null.order = null.order, null.below.na = null.below.na), class = "tm_plot_order") 29 | } 30 | -------------------------------------------------------------------------------- /R/tm_vars.R: -------------------------------------------------------------------------------- 1 | #' tmap function to specify variables 2 | #' 3 | #' tmap function to specify all variables in the shape object 4 | #' 5 | #' @param x variable names, variable indices, or a dimension name 6 | #' @param dimvalues dimension values 7 | #' @param n if specified the first `n` variables are taken (or the first `n` dimension values) 8 | #' @param multivariate in case multiple variables are specified, should they serve as facets (FALSE) or as a multivariate visual variable? 9 | #' @param animate should the variable(s) be animated? (experimental) 10 | #' @export 11 | tm_vars = function(x = NA, dimvalues = NULL, n = NA, multivariate = FALSE, animate = FALSE) { 12 | structure(list(x = x, dimvalues = dimvalues, n = n, multivariate = multivariate, animate = animate), class = c("tmapVars", "list")) 13 | } 14 | 15 | 16 | # process visual variable specification. Can either be tmapVars (output of tm_vars) or a list of values. 17 | tmapVV = function(x) { 18 | if (is.null(x)) { 19 | x = structure(list("value.blank"), class = "tmapOption") 20 | 21 | } else if (!is.list(x) && length(x) == 1 && is.na(x)) { 22 | x = structure(list("value.const"), class = "tmapOption") 23 | } 24 | 25 | if (inherits(x, c("tmapOption", "tmapVars"))) return(x) 26 | 27 | # if (inherits(x, "tm_shape_vars")) return(structure(list(ids = x$ids, n = x$n), class = "tmapShpVars")) 28 | # if (inherits(x, "tm_mv_shape_vars")) return(structure(list(ids = x$ids, n = x$n), class = "tmapMVShpVars")) 29 | # if (inherits(x, "tmapDimVars")) return(x) 30 | 31 | cls = if (inherits(x, "AsIs")) "tmapAsIs" else if (inherits(x, "tmapUsrCls")) "tmapUsrCls" else "tbd" 32 | 33 | 34 | isL = is.list(x) 35 | 36 | if (cls == "tbd" && !isL) { 37 | if (is.character(x) && all(substr(x, 1, 1) == "*")) { 38 | x = substr(x, 2, nchar(x)) 39 | return(tm_vars(x, animate = TRUE)) 40 | } 41 | } 42 | 43 | isNestedL = isL && any(vapply(x, is.list, FUN.VALUE = logical(1))) 44 | isSpecialL = isL && !setequal(class(x), "list") 45 | isSpecialNestedL = isL && is.list(x[[1]]) && !setequal(class(x[[1]]), "list") 46 | if (!isL) { 47 | x = as.list(x) 48 | } else if (isSpecialL) { 49 | x = list(x) 50 | } 51 | 52 | if (cls == "tbd") cls = if (isSpecialL || isSpecialNestedL || isNestedL) "tmapSpecial" else "tmapStandard" 53 | 54 | if (cls == "tmapSpecial") { 55 | nms = seq_along(x) 56 | } else { 57 | nms = x 58 | } 59 | 60 | structure(x, names = nms, class = cls) 61 | } 62 | -------------------------------------------------------------------------------- /R/tm_xylab.R: -------------------------------------------------------------------------------- 1 | #' Map: x and y labels 2 | #' 3 | #' The x and y labels for maps 4 | #' 5 | #' @param text text of the title 6 | #' @param size font size of the title 7 | #' @param color color 8 | #' @param rotation rotation in degrees 9 | #' @param space space between label and map in number of line heights 10 | #' @param fontface font face 11 | #' @param fontfamily font family 12 | #' @param alpha alpha transparency of the text 13 | #' @param side side: `"top"` or `"bottom"` for `tm_xlab` and `"left"` or `"right"` for `tm_ylab` 14 | #' @export 15 | #' @export 16 | tm_xlab = function(text, size, color, rotation, space, fontface, fontfamily, alpha, side) { 17 | args = lapply(as.list(rlang::call_match()[-1]), eval, envir = parent.frame()) 18 | args$show = TRUE 19 | names(args) = paste("xlab", names(args), sep = ".") 20 | do.call(tm_options, args) 21 | } 22 | 23 | #' @export 24 | #' @rdname tm_xlab 25 | tm_ylab = function(text, size, color, rotation, space, fontface, fontfamily, alpha, side) { 26 | args = lapply(as.list(rlang::call_match()[-1]), eval, envir = parent.frame()) 27 | args$show = TRUE 28 | names(args) = paste("ylab", names(args), sep = ".") 29 | do.call(tm_options, args) 30 | } 31 | -------------------------------------------------------------------------------- /R/tmapGpar.R: -------------------------------------------------------------------------------- 1 | #' @param fill,col,shape,size,fill_alpha,col_alpha,lty,lwd,linejoin,lineend visual variables 2 | #' @param ... args 3 | #' @export 4 | #' @rdname tmap_internal 5 | tmapGpar = function(fill = NULL, 6 | col = NULL, 7 | shape = NULL, 8 | size = NULL, 9 | fill_alpha = NULL, 10 | col_alpha = NULL, 11 | #pattern = NULL, 12 | lty = NULL, 13 | lwd = NULL, 14 | linejoin = NULL, 15 | lineend = NULL, 16 | ...) { 17 | args = c(as.list(environment()), list(...)) 18 | structure(args, class = "tmapGpar") 19 | } 20 | 21 | #' @export 22 | #' @rdname tmap_internal 23 | tmapTpar = function(...) { 24 | args = c(as.list(environment()), list(...)) 25 | structure(args, class = "tmapTpar") 26 | } 27 | -------------------------------------------------------------------------------- /R/tmapGridArrange.R: -------------------------------------------------------------------------------- 1 | tmapGridArrange = function(tms, nx, ncol, nrow, opts, knit, show, args, options) { 2 | widths <- opts$widths 3 | heights = opts$heights 4 | if (is.na(widths[1])) widths <- rep(1/ncol, ncol) 5 | if (is.na(heights[1])) heights <- rep(1/nrow, nrow) 6 | 7 | grid.newpage() 8 | vp <- viewport(layout=grid.layout(nrow=nrow, ncol=ncol, widths = widths, heights=heights), name = "tmap_arrangement") 9 | pushViewport(vp) 10 | 11 | if (!is.null(opts$asp) || !is.null(opts$outer.margins)) { 12 | layout_args <- list(asp=opts$asp, outer.margins=opts$outer.margins) 13 | layout_args <- layout_args[!vapply(layout_args, is.null, logical(1))] 14 | tml <- do.call(tm_options, layout_args) 15 | } else { 16 | tml <- NULL 17 | } 18 | 19 | nc <- 1 20 | nr <- 1 21 | for (i in 1:nx) { 22 | tm <- tms[[i]] 23 | if (!is.null(tml)) tm <- tm + tml 24 | print(tm, vp = viewport(layout.pos.col = nc, layout.pos.row = nr)) 25 | nc <- nc + 1 26 | if (nc > ncol) { 27 | nc <- 1 28 | nr <- nr + 1 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /R/tmapGridLines.R: -------------------------------------------------------------------------------- 1 | #' @export 2 | #' @rdname tmap_internal 3 | tmapGridLines = function(shpTM, dt, gp, bbx, facet_row, facet_col, facet_page, id, pane, group, o, ...) { 4 | 5 | rc_text = frc(facet_row, facet_col) 6 | 7 | res = select_sf(shpTM, dt[!is.na(dt$lwd), ]) 8 | shp = res$shp 9 | dt = res$dt 10 | 11 | gp = impute_gp(gp, dt) 12 | gp = rescale_gp(gp, o$scale_down) 13 | 14 | gp = gp_to_gpar(gp, sel = "col", o = o, type = "lines") 15 | grb = sf::st_as_grob(shp, gp = gp, name = paste0("lines_", id)) 16 | 17 | gts = get("gts", .TMAP_GRID) 18 | gt = gts[[facet_page]] 19 | 20 | gt_name = paste0("gt_facet_", rc_text) 21 | 22 | gt = grid::addGrob(gt, grb, gPath = grid::gPath(gt_name)) 23 | 24 | gts[[facet_page]] = gt 25 | 26 | assign("gts", gts, envir = .TMAP_GRID) 27 | NULL 28 | } 29 | -------------------------------------------------------------------------------- /R/tmapGridPolygons.R: -------------------------------------------------------------------------------- 1 | #' @export 2 | #' @rdname tmap_internal 3 | tmapGridPolygons = function(shpTM, dt, gp, bbx, facet_row, facet_col, facet_page, id, pane, group, o, ...) { 4 | 5 | rc_text = frc(facet_row, facet_col) 6 | 7 | res = select_sf(shpTM, dt) 8 | shp = res$shp 9 | dt = res$dt 10 | gp = impute_gp(gp, dt) 11 | gp = rescale_gp(gp, o$scale_down) 12 | 13 | # none should contain NA's && (length or content should be different) 14 | diffAlpha = !anyNA(c(gp$fill_alpha, gp$col_alpha)) && !(length(gp$fill_alpha) == length(gp$col_alpha) && all(gp$fill_alpha == gp$col_alpha)) 15 | 16 | 17 | if (diffAlpha) { 18 | gp1 = gp_to_gpar(gp, sel = "fill", o = o, type = "polygons") 19 | gp2 = gp_to_gpar(gp, sel = "col", o = o, type = "polygons") 20 | grb1 = sf::st_as_grob(shp, gp = gp1, name = paste0("polygons_", id)) 21 | grb2 = sf::st_as_grob(shp, gp = gp2, name = paste0("polygon_borders_", id)) 22 | grb = grid::grobTree(grb1, grb2) 23 | } else { 24 | gp = gp_to_gpar(gp, sel = "all", o = o, type = "polygons") 25 | grb = sf::st_as_grob(shp, gp = gp, name = paste0("polygons_", id)) 26 | } 27 | 28 | 29 | gts = get("gts", .TMAP_GRID) 30 | gt = gts[[facet_page]] 31 | 32 | gt_name = paste0("gt_facet_", rc_text) 33 | 34 | gt = grid::addGrob(gt, grb, gPath = grid::gPath(gt_name)) 35 | 36 | gts[[facet_page]] = gt 37 | 38 | assign("gts", gts, envir = .TMAP_GRID) 39 | NULL 40 | } 41 | -------------------------------------------------------------------------------- /R/tmapGridProviders.R: -------------------------------------------------------------------------------- 1 | tmapGridProviders = function(credits) { 2 | x = maptiles::get_providers() 3 | if (credits) { 4 | lapply(x, "[[", "cit") 5 | } else { 6 | lapply(x, "[[", "src") 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /R/tmapGridRun.R: -------------------------------------------------------------------------------- 1 | tmapGridRun = function(o, q, show, knit, args) { 2 | gts = get("gts", .TMAP_GRID) 3 | if (show) { 4 | if (o$show_gif_ani) { 5 | d <- paste(tempdir(), "/tmap_plots", sep="/") 6 | dir.create(d, showWarnings = FALSE) 7 | devsize = c(grid::convertWidth(grid::unit(1, "npc"), unitTo = "inch", valueOnly = TRUE) * 72 * o$dpr, 8 | grid::convertHeight(grid::unit(1, "npc"), unitTo = "inch", valueOnly = TRUE) * 72 * o$dpr) 9 | } 10 | 11 | mapply(function(gt,i) { 12 | if (o$show_gif_ani) { 13 | png(paste0(d, "/plot", sprintf("%03d", i), ".png"), width = devsize[1], height = devsize[2], res = 72*o$dpr, type = "cairo-png") 14 | grid::grid.newpage() 15 | } else { 16 | if (is.null(o$vp) && i != 1L) grid::grid.newpage() 17 | } 18 | 19 | tryCatch({ 20 | grid::grid.draw(gt) 21 | }, error = function(e) { 22 | stop("Plot error. Try adding + tm_check_fix()", call. = FALSE) 23 | }) 24 | if (o$show_gif_ani) { 25 | dev.off() 26 | } 27 | 28 | }, gts, seq_along(gts), SIMPLIFY = FALSE) 29 | if (!is.null(o$vp)) upViewport(1) 30 | } 31 | if (length(gts) == 1) gts = gts[[1]] 32 | 33 | if (show && o$show_gif_ani) { 34 | files = list.files(path = d, pattern = "^plot[0-9]{3}\\.png$", full.names = TRUE) 35 | if (o$play == "pingpong") files = c(files, rev(files)) 36 | filename = tempfile(fileext = ".gif") 37 | create_animation(filename = filename, files = files, width = devsize[1], height = devsize[2], delay = NA, fps = o$fps, loop = o$play != "once", progress = FALSE, gif = TRUE, showAni = TRUE, dpr = o$dpr) 38 | } 39 | 40 | gts 41 | } 42 | -------------------------------------------------------------------------------- /R/tmapGridWrap.R: -------------------------------------------------------------------------------- 1 | get_panel_grob = function(label, o, g, rot, row, col) { 2 | panel.show = o$panel.label.frame || o$panel.label.bg 3 | frame.col = if (o$panel.label.frame) o$panel.label.frame.color else NA 4 | bg.col = if (o$panel.label.bg) o$panel.label.bg.color else NA 5 | if (panel.show) { 6 | if (o$panel.label.bg.alpha != o$panel.label.frame.alpha) { 7 | gpar_panel = grid::gpar(fill = bg.col, lwd=0, col = NA, alpha = o$panel.label.bg.alpha) 8 | gpar_panel_frame = grid::gpar(fill = NA, lwd=o$panel.label.frame.lwd * o$scale, col = frame.col, alpha = o$panel.label.frame.alpha) 9 | } else { 10 | gpar_panel = grid::gpar(fill = bg.col, lwd=o$panel.label.frame.lwd * o$scale, col = frame.col, alpha = o$panel.label.bg.alpha) 11 | gpar_panel_frame = NULL 12 | } 13 | } 14 | gpar_text = rescale_gp(grid::gpar(cex = o$panel.label.size * o$scale, col = o$panel.label.color, fontfamily = o$panel.label.fontfamily, fontface = o$panel.label.fontface, alpha = o$panel.label.alpha), o$scale_down) 15 | 16 | # resize due to not fitting 17 | gpar_text$cex = determine_scale(label = label, rot = rot, row = row, col = col, g = g, scale = gpar_text$cex) 18 | 19 | if (!is.na(label)) label = decode_expr(label) 20 | 21 | 22 | grid::grobTree( 23 | if (panel.show) { 24 | rndrectGrob(gp = gpar_panel, r = o$panel.label.frame.r * o$scale) 25 | } else NULL, 26 | if (panel.show && !is.null(gpar_panel_frame)) { 27 | rndrectGrob(gp = gpar_panel_frame, r = o$panel.label.frame.r * o$scale) 28 | } else NULL, 29 | grid::textGrob(label = label, rot = rot, gp = gpar_text) 30 | ) 31 | } 32 | 33 | tmapGridWrap = function(label, facet_row, facet_col, facet_page, o) { 34 | gts = get("gts", envir = .TMAP_GRID) 35 | g = get("g", envir = .TMAP_GRID) 36 | 37 | gt = gts[[facet_page]] 38 | 39 | rot = g$panel_rot 40 | row = g$rows_panel_ids[facet_row] 41 | col = g$cols_panel_ids[facet_col] 42 | 43 | grb = get_panel_grob(label, o, g, rot, row, col) 44 | 45 | gt = add_to_gt(gt, grb, row = row, col = col) 46 | 47 | gts[[facet_page]] = gt 48 | 49 | assign("gts", gts, envir = .TMAP_GRID) 50 | 51 | 52 | } 53 | 54 | tmapGridXtab = function(label, facet_row = NULL, facet_col = NULL, facet_page, o) { 55 | gts = get("gts", envir = .TMAP_GRID) 56 | g = get("g", envir = .TMAP_GRID) 57 | 58 | gt = gts[[facet_page]] 59 | 60 | if (is.null(facet_row)) { 61 | rot = g$panel_col_rot 62 | row = g$cols_panel_row_id 63 | col = g$cols_panel_col_ids[facet_col] 64 | } else { 65 | rot = g$panel_row_rot 66 | row = g$rows_panel_row_ids[facet_row] 67 | col = g$rows_panel_col_id 68 | } 69 | 70 | grb = get_panel_grob(label, o, g, rot, row, col) 71 | 72 | gt = add_to_gt(gt, grb, row = row, col = col) 73 | 74 | gts[[facet_page]] = gt 75 | 76 | assign("gts", gts, envir = .TMAP_GRID) 77 | 78 | 79 | } 80 | -------------------------------------------------------------------------------- /R/tmapGridXYlab.R: -------------------------------------------------------------------------------- 1 | tmapGridXlab = function(facet_page, o) { 2 | gts = get("gts", envir = .TMAP_GRID) 3 | g = get("g", envir = .TMAP_GRID) 4 | 5 | gt = gts[[facet_page]] 6 | 7 | row = g$xlab_row_id 8 | col = g$xlab_col_ids 9 | 10 | gpar_text = rescale_gp(grid::gpar(cex = o$xlab.size, col = o$xlab.color, fontfamily = o$xlab.fontfamily, fontface = o$xlab.fontface, alpha = o$xlab.alpha), o$scale_down) 11 | 12 | grb = grid::grobTree( 13 | grid::textGrob(label = o$xlab.text, rot = o$xlab.rotation, gp = gpar_text) 14 | ) 15 | 16 | gt = add_to_gt(gt, grb, row = row, col = col) 17 | gts[[facet_page]] = gt 18 | 19 | assign("gts", gts, envir = .TMAP_GRID) 20 | 21 | } 22 | 23 | 24 | tmapGridYlab = function(facet_page, o) { 25 | gts = get("gts", envir = .TMAP_GRID) 26 | g = get("g", envir = .TMAP_GRID) 27 | 28 | gt = gts[[facet_page]] 29 | 30 | row = g$ylab_row_ids 31 | col = g$ylab_col_id 32 | 33 | gpar_text = rescale_gp(grid::gpar(cex = o$ylab.size, col = o$ylab.color, fontfamily = o$ylab.fontfamily, fontface = o$ylab.fontface), o$scale_down) 34 | 35 | grb = grid::grobTree( 36 | grid::textGrob(label = o$ylab.text, rot = o$ylab.rotation, gp = gpar_text) 37 | ) 38 | 39 | gt = add_to_gt(gt, grb, row = row, col = col) 40 | gts[[facet_page]] = gt 41 | 42 | assign("gts", gts, envir = .TMAP_GRID) 43 | 44 | } 45 | -------------------------------------------------------------------------------- /R/tmapLeaflet.R: -------------------------------------------------------------------------------- 1 | get_facet_id = function(row, col, nrow, ncol) { 2 | col + (row - 1L) * ncol 3 | } 4 | 5 | get_lf = function(facet_row, facet_col, facet_page) { 6 | lfs = get("lfs", envir = .TMAP_LEAFLET) 7 | nrow = get("nrow", envir = .TMAP_LEAFLET) 8 | ncol = get("ncol", envir = .TMAP_LEAFLET) 9 | 10 | lfsi = lfs[[facet_page]] 11 | 12 | fr = max(1, facet_row) # facet_row can be -1 or -2 13 | fc = max(1, facet_col) # facet_row can be -1 or -2 14 | 15 | lfid = get_facet_id(fr, fc, nrow, ncol) 16 | 17 | lfsi[[lfid]] 18 | } 19 | 20 | assign_lf = function(lf, facet_row, facet_col, facet_page) { 21 | lfs = get("lfs", envir = .TMAP_LEAFLET) 22 | nrow = get("nrow", envir = .TMAP_LEAFLET) 23 | ncol = get("ncol", envir = .TMAP_LEAFLET) 24 | 25 | 26 | fr = max(1, facet_row) # facet_row can be -1 or -2 27 | fc = max(1, facet_col) # facet_row can be -1 or -2 28 | 29 | 30 | 31 | lfid = get_facet_id(fr, fc, nrow, ncol) 32 | 33 | lfs[[facet_page]][[lfid]] = lf 34 | assign("lfs", lfs, envir = .TMAP_LEAFLET) 35 | NULL 36 | } 37 | 38 | tmapLeafletWrap = function(label, facet_row, facet_col, facet_page, o) { 39 | 40 | NULL 41 | } 42 | 43 | tmapLeafletXtab = function(label, facet_row, facet_col, facet_page, o) { 44 | } -------------------------------------------------------------------------------- /R/tmapLeafletArrange.R: -------------------------------------------------------------------------------- 1 | tmapLeafletArrange = function(tms, nx, ncol, nrow, opts, knit, show, args, options) { 2 | res = lapply(tms, function(tm) { 3 | print(tm, show = FALSE) 4 | }) 5 | res2 = do.call(leafsync::latticeView, c(res, list(ncol=ncol, sync=ifelse(identical(opts$sync, TRUE), "all", "none"), no.initial.sync = FALSE))) 6 | 7 | # 8 | # lfs <- lapply(tms, function(tm) { 9 | # tmap_leaflet(tm, add.titles = FALSE) 10 | # }) 11 | # lfmv <- do.call(leafsync::latticeView, c(lfs, list(ncol=ncol, sync=ifelse(opts$sync, "all", "none")))) 12 | # 13 | # if (add.titles) lfmv <- view_add_leaflet_titles(lfmv) 14 | 15 | if (show) { 16 | if (knit) { 17 | kp <- get("knit_print", asNamespace("knitr")) 18 | return(do.call(kp, c(list(x=res2), args, list(options=options)))) 19 | } else { 20 | return(print(res2)) 21 | } 22 | } else res2 23 | } 24 | -------------------------------------------------------------------------------- /R/tmapLeafletAux.R: -------------------------------------------------------------------------------- 1 | tmapLeafletTilesPrep = function(a, bs, id, o) { 2 | tiles = lapply(1L:length(bs), function(i) a) 3 | .TMAP_LEAFLET$tiles[[id]] = tiles 4 | paste0(a$server, collapse = "__") 5 | } 6 | 7 | tmapLeafletTiles = function(bi, bbx, facet_row, facet_col, facet_page, id, pane, group, o) { 8 | 9 | lf = get_lf(facet_row, facet_col, facet_page) 10 | 11 | rc_text = frc(facet_row, facet_col) 12 | 13 | 14 | tiles = .TMAP_LEAFLET$tiles[[id]][[bi]] 15 | 16 | if (o$credits.defined) { 17 | opt = leaflet::tileOptions(attribution = "", maxNativeZoom = tiles$max.native.zoom, pane = pane) 18 | } else { 19 | opt = leaflet::tileOptions(maxNativeZoom = tiles$max.native.zoom, pane = pane) 20 | } 21 | if (!is.na(o$set_zoom_limits[2])) opt$maxZoom = o$set_zoom_limits[2] 22 | 23 | for (s in tiles$server) { 24 | if (s != "") { 25 | if ((substr(s, 1, 4) == "http")) { 26 | lf = leaflet::addTiles(lf, urlTemplate = s, group = s, options = opt) 27 | } else { 28 | lf = leaflet::addProviderTiles(lf, provider = s, group = s, options = opt) 29 | } 30 | } 31 | } 32 | 33 | assign_lf(lf, facet_row, facet_col, facet_page) 34 | NULL 35 | } 36 | 37 | tmapLeafletGridPrep = function(a, bs, id, o) { 38 | 39 | grid_intervals = vapply(bs, function(b) { 40 | # implementation similarish as plot mode but needs polishing 41 | dx = b[3] - b[1] 42 | dy = b[4] - b[2] 43 | # if not specified, aim for 15 lines in total 44 | n.x = if (!is.na(a$n.x)) a$n.x else if (is.na(a$x)) 7.5 else length(a$x) 45 | n.y = if (!is.na(a$n.y)) a$n.y else if (is.na(a$y)) 7.5 else length(a$x) 46 | 47 | x = pretty30(b[c(1,3)], n=n.x, longlat = !is.na(a$crs) && sf::st_is_longlat(a$crs)) 48 | y = pretty30(b[c(2,4)], n=n.y, longlat = !is.na(a$crs) && sf::st_is_longlat(a$crs)) 49 | 50 | max((x[2] - x[1]), (y[2]-y[1])) 51 | }, FUN.VALUE = numeric(1)) 52 | assign("grid_intervals", grid_intervals, envir = .TMAP_LEAFLET) 53 | 54 | return("grid") 55 | } 56 | 57 | tmapLeafletGrid = function(bi, bbx, facet_row, facet_col, facet_page, id, pane, group, o) { 58 | lf = get_lf(facet_row, facet_col, facet_page) 59 | rc_text = frc(facet_row, facet_col) 60 | 61 | grid_intervals = get("grid_intervals", envir = .TMAP_LEAFLET) 62 | 63 | lf = leaflet::addGraticule(lf, interval = grid_intervals[bi], options = pathOptions(pane = pane)) 64 | 65 | 66 | assign_lf(lf, facet_row, facet_col, facet_page) 67 | NULL 68 | } 69 | 70 | tmapLeafletGridXLab = function(bi, bbx, facet_row, facet_col, facet_page, o) { 71 | NULL 72 | } 73 | 74 | tmapLeafletGridYLab = function(bi, bbx, facet_row, facet_col, facet_page, o) { 75 | NULL 76 | } 77 | -------------------------------------------------------------------------------- /R/tmapLeafletComp_charts.R: -------------------------------------------------------------------------------- 1 | #' @method tmapLeafletCompPrepare tm_chart 2 | #' @export 3 | tmapLeafletCompPrepare.tm_chart = function(comp, o) { 4 | message("charts not implemented in view mode") 5 | comp 6 | } 7 | 8 | #' @method tmapLeafletCompPrepare tm_chart_none 9 | #' @export 10 | tmapLeafletCompPrepare.tm_chart_none = function(comp, o) { 11 | comp 12 | } 13 | 14 | 15 | #' @method tmapLeafletCompWidth tm_chart 16 | #' @export 17 | tmapLeafletCompWidth.tm_chart = function(comp, o) { 18 | comp 19 | } 20 | 21 | #' @method tmapLeafletCompHeight tm_chart 22 | #' @export 23 | tmapLeafletCompHeight.tm_chart = function(comp, o) { 24 | comp 25 | } 26 | 27 | #' @method tmapLeafletLegPlot tm_chart_histogram 28 | #' @export 29 | tmapLeafletLegPlot.tm_chart_histogram = function(comp, lf, o) { 30 | lf 31 | } 32 | #' @method tmapLeafletLegPlot tm_chart 33 | #' @export 34 | tmapLeafletLegPlot.tm_chart = function(comp, lf, o) { 35 | lf 36 | } 37 | -------------------------------------------------------------------------------- /R/tmapLeafletProviders.R: -------------------------------------------------------------------------------- 1 | tmapLeafletProviders = function(credits) { 2 | if (credits) { 3 | x = leaflet::providers.details 4 | lapply(x, function(xi) { 5 | xi$options$attribution 6 | }) 7 | } else { 8 | leaflet::providers 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /R/tmapLeafletShape.R: -------------------------------------------------------------------------------- 1 | tmapLeafletShape = function(bbx, facet_row, facet_col, facet_page, o) { 2 | bbx = unname(bbx) 3 | if (!.TMAP$proxy) { 4 | get_lf(facet_row, facet_col, facet_page) %>% 5 | leaflet::fitBounds(bbx[1], bbx[2], bbx[3], bbx[4]) %>% 6 | view_set_bounds(bbx, o) %>% 7 | assign_lf(facet_row, facet_col, facet_page) 8 | } 9 | NULL 10 | } 11 | 12 | tmapLeafletOverlay = function(bbx, facet_row, facet_col, facet_page, o) { 13 | NULL 14 | } 15 | -------------------------------------------------------------------------------- /R/tmapLeafletShiny.R: -------------------------------------------------------------------------------- 1 | # not working yet, see #1024 2 | renderTmapLeaflet = function(expr, env, quoted, execOnResize) { 3 | if (!quoted) 4 | expr = substitute(expr) 5 | expr = substitute(getFromNamespace("print.tmap", "tmap")(expr, in.shiny = TRUE)) 6 | htmlwidgets::shinyRenderWidget(expr, leafletOutput, env, 7 | quoted = TRUE) 8 | } 9 | 10 | tmapOutputLeaflet = function(outputId, width, height) { 11 | leaflet::leafletOutput(outputId, width = width, height = height) 12 | } 13 | 14 | 15 | tmapProxyLeaflet = function(mapId, session, x) { 16 | print.tmap(x, lf = leaflet::leafletProxy(mapId, session), show = FALSE, in.shiny = TRUE, proxy = TRUE) 17 | } 18 | -------------------------------------------------------------------------------- /R/tmapLeafletXYlab.R: -------------------------------------------------------------------------------- 1 | tmapLeafletXlab = function(facet_page, o) { 2 | NULL 3 | 4 | } 5 | 6 | 7 | tmapLeafletYlab = function(facet_page, o) { 8 | NULL 9 | } -------------------------------------------------------------------------------- /R/tmapOnLoad.R: -------------------------------------------------------------------------------- 1 | # envir = environment() 2 | .onLoad = function(...) { 3 | options(tmap.style = "white", tmap.mode = "plot", tmap.design.mode = FALSE, 4 | tmap.devel.mode = FALSE) 5 | assign("tmapOptions", .defaultTmapOptions, envir = .TMAP) 6 | 7 | # makeActiveBinding("tmap_pals", function() { 8 | # remove_non_letters = function(x) gsub("[-, _, \\,, (, ), \\ , \\.]", "", x) 9 | # hcl_pals = grDevices::hcl.pals() 10 | # base_pals = grDevices::palette.pals() 11 | # pals = ls(asNamespace("pals"))[substr(ls(asNamespace("pals")), 1, 4) != "pal."] 12 | # list(base_hcl = structure(as.list(hcl_pals), names = remove_non_letters(hcl_pals)), 13 | # base_pal = structure(as.list(base_pals), names = remove_non_letters(base_pals)), 14 | # pals = structure(as.list(pals), names = pals)) 15 | # }, env = envir) 16 | 17 | assign("last_map", NULL, envir = .TMAP) 18 | assign("last_map_new", NULL, envir = .TMAP) 19 | 20 | 21 | # flag for old v3 code 22 | assign("v3", FALSE, envir = .TMAP) 23 | 24 | assign("tips", sample(.tips), envir = .TMAP) 25 | assign("tip_nr", 1L, envir = .TMAP) 26 | 27 | assign("tmapStyles", .defaultTmapStyles, envir = .TMAP) 28 | 29 | .TMAP$round_to = as.vector(sapply((-9):9, function(i) { 30 | sapply(c(1, 2.5, 5), function(j) { 31 | j*10^i 32 | }) 33 | })) # needed for pretty ticks for continuous scale with trans enabled (like log scale) 34 | 35 | .TMAP$mode_last = "view" 36 | 37 | .TMAP_GRID$maptiles_urls = character(0) # needed for caching 38 | 39 | fill_providers() 40 | } 41 | 42 | .tips <- c( 43 | "tmap works with {.href [visual variables](https://r-tmap.github.io/tmap/articles/basics_vv)}.", 44 | "tmap can be {.href [extended](https://r-tmap.github.io/tmap/articles/adv_extensions)} in several ways.", 45 | "{.href [Charts](https://r-tmap.github.io/tmap/articles/basics_charts)} can be added next to legends.", 46 | "Layout {.href [styles](https://r-tmap.github.io/tmap/articles/adv_options#setting-options-and-styles)} can be created.", 47 | "Automatic {.href [map projection](https://r-tmap.github.io/tmap/articles/foundations_crs)} recommendations can be set via {.code tm_crs(crs = {.str auto})}.", 48 | "Layout can be adjusted to look identical as {.href [ggplot2](https://r-tmap.github.io/tmap/articles/versus_ggplot2#mimicking-ggplot2-layout)}.", 49 | "In {.str plot} mode, a special design-mode can be enabled via {.code tmap_design_mode()}." 50 | ) 51 | 52 | 53 | #' @rdname tmap_providers 54 | #' @export 55 | .tmap_providers <- new.env(FALSE, parent=globalenv()) 56 | 57 | 58 | #' @export 59 | #' @rdname tmap_internal 60 | .TMAP = new.env(FALSE, parent = globalenv()) 61 | 62 | #' @export 63 | #' @rdname tmap_internal 64 | .TMAP_LEAFLET = new.env(FALSE, parent = globalenv()) 65 | 66 | #' @export 67 | #' @rdname tmap_internal 68 | .TMAP_GRID = new.env(FALSE, parent = globalenv()) 69 | 70 | 71 | fill_providers = function() { 72 | rm(list = ls(envir = .tmap_providers), envir = .tmap_providers) 73 | y = tmap_providers(as.list = TRUE) 74 | list2env(y, envir = .tmap_providers) 75 | } 76 | 77 | -------------------------------------------------------------------------------- /R/tmapScaleAsIs.R: -------------------------------------------------------------------------------- 1 | #' @export 2 | #' @rdname tmap_internal 3 | tmapScaleAsIs = function(x1, scale, legend, chart, o, aes, layer, layer_args, sortRev, bypass_ord, submit_legend = TRUE) { 4 | legend = list(title = NA, 5 | nitems = 0, 6 | labels = NA, 7 | dvalues = NA, 8 | vvalues = NA, 9 | vneutral = NA, 10 | na.show = NA, 11 | scale = "AsIs", 12 | show = FALSE, 13 | active = FALSE) 14 | 15 | x1h = head(x1, 100) 16 | check_values(layer, aes, x1h) 17 | 18 | 19 | scale$values.scale = if (is.na(scale$values.scale)) getAesOption("values.scale", o, aes, layer) else scale$values.scale 20 | 21 | isna = is.na(x1) 22 | if (any(isna) && is.na(scale$value.na)) { 23 | x1[isna] = getAesOption("value.na", o, aes, layer) 24 | } 25 | 26 | sfun = paste0("tmapValuesScale_", aes) 27 | cfun = paste0("tmapValuesColorize_", aes) 28 | 29 | sc = o$scale * scale$values.scale 30 | 31 | x2 = do.call(sfun, list(x = x1, scale = sc)) 32 | values = do.call(cfun, list(x = x2, pc = o$pc)) 33 | 34 | vneutral = if (is.na(scale$value.neutral)) { 35 | getAesOption("value.neutral", o, aes, layer) 36 | } else { 37 | scale$value.neutral 38 | } 39 | 40 | 41 | legend$vneutral = do.call(sfun, list(x = do.call(cfun, list(x = vneutral, pc = o$pc)), scale = o$scale)) 42 | 43 | if (submit_legend) { 44 | if (bypass_ord) { 45 | format_aes_results(values, legend = legend, chart = chart) 46 | } else { 47 | format_aes_results(values, ord = 1L, legend = legend, chart = chart) 48 | } 49 | } else { 50 | list(vals = values, ids = 1L, legend = legend, chart = chart, bypass_ord = bypass_ord) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /R/tmapScaleRank.R: -------------------------------------------------------------------------------- 1 | #' @export 2 | #' @rdname tmap_internal 3 | tmapScaleRank = function(x1, scale, legend, chart, o, aes, layer, layer_args, sortRev, bypass_ord, submit_legend = TRUE) { 4 | 5 | # update misc argument from tmap option scale.misc.args 6 | scale = update_scale_args("rank", scale, aes, o) 7 | 8 | cls = data_class(x1, midpoint_enabled = !is.null(scale$midpoint)) 9 | maincls = class(scale)[1] 10 | 11 | if (attr(cls, "unique") && is.null(scale$limits) && is.null(scale$ticks)) stop("Unique value, so cannot determine continuous scale range. Please specify limits and/or ticks.", call. = FALSE) 12 | 13 | #if (cls[1] == "na") stop("data contain only NAs, so ", maincls, " cannot be applied", call. = FALSE) 14 | 15 | if (cls[1] != "num") { 16 | if (!is.factor(x1)) x1 = as.factor(x1) 17 | x1 = as.integer(x1) 18 | warning(maincls, " is supposed to be applied to numerical data", call. = FALSE) 19 | } 20 | 21 | 22 | x1 = rank(without_units(x1), na.last = "keep") 23 | 24 | if (aes %in% c("lty", "shape", "pattern")) stop("tm_scale_rank cannot be used for layer ", layer, ", aesthetic ", aes, call. = FALSE) 25 | 26 | scale = structure(c(scale, list(limits = NULL, outliers.trunc = NULL, trans = NULL, midpoint = NULL, 27 | trans.args = list())), class = c("tm_scale_continuous", "tm_scale", "list")) 28 | 29 | if (is.null(scale$ticks)) { 30 | scale$ticks = generate_rank_labels(max_rank = max(x1,na.rm=T), num_ticks = scale$n) 31 | } 32 | 33 | 34 | tmapScaleContinuous(x1, scale, legend, chart, o, aes, layer, layer_args, sortRev, bypass_ord, submit_legend) 35 | 36 | } 37 | 38 | generate_rank_labels = function(max_rank, num_ticks = 5) { 39 | ticks = c(1, max_rank) 40 | 41 | if (num_ticks > 2) { 42 | probs = seq(0, 1, length.out = num_ticks) 43 | probs = probs[-c(1, length(probs))] 44 | 45 | intermediate_ticks = quantile(1:max_rank, probs = probs) 46 | ticks = c(ticks, intermediate_ticks) 47 | } 48 | 49 | # Ensure the order 50 | ticks = sort(unique(round(ticks))) 51 | 52 | return(ticks) 53 | } 54 | -------------------------------------------------------------------------------- /R/tmapShape.R: -------------------------------------------------------------------------------- 1 | tmapReproject = function(...) { 2 | UseMethod("tmapReproject") 3 | } 4 | 5 | 6 | reproject_bbox = function(bbox, crs) { 7 | s = tmaptools::bb_poly(bbox) #st_as_sfc does not add intermediate points 8 | s2 = sf::st_transform(s, crs) 9 | sf::st_bbox(s2) 10 | } 11 | 12 | 13 | 14 | 15 | #' Internal method that processed shape objects 16 | #' 17 | #' Internal method that processed shape objects 18 | #' 19 | #' @param shp shp 20 | #' @param is.main is.main 21 | #' @param crs crs 22 | #' @param bbox Bounding box 23 | #' @param unit unit 24 | #' @param filter filter 25 | #' @param shp_name shp_name 26 | #' @param smeta smeta 27 | #' @param o o 28 | #' @param tmf tmf 29 | #' @export 30 | #' @import data.table 31 | #' @keywords internal 32 | tmapShape = function(shp, is.main, crs, bbox, unit, filter, shp_name, smeta, o, tmf) { 33 | UseMethod("tmapShape") 34 | } 35 | 36 | #' Internal method that subsets data from shape objects 37 | #' 38 | #' Internal method that subsets data from shape objects 39 | #' 40 | #' @param shp shape 41 | #' @param vars a vector of variable names 42 | #' @export 43 | #' @keywords internal 44 | tmapSubsetShp = function(shp, vars) { 45 | UseMethod("tmapSubsetShp") 46 | } 47 | 48 | #' Internal method that extracts meta data from shape objects 49 | #' 50 | #' Internal method that extracts meta data from shape objects 51 | #' 52 | #' @param shp the shape object 53 | #' @param o the list of options 54 | #' @export 55 | #' @keywords internal 56 | tmapGetShapeMeta1 = function(shp, o) { 57 | UseMethod("tmapGetShapeMeta1") 58 | } 59 | 60 | #' Internal method that extracts more meta data from shape objects 61 | #' 62 | #' Internal method that extracts meta data from shape objects 63 | #' 64 | #' @param shp the shape 65 | #' @param smeta meta (from `tmapGetShapeMeta1()`) 66 | #' @param o the list of options 67 | #' @export 68 | #' @keywords internal 69 | tmapGetShapeMeta2 = function(shp, smeta, o) { 70 | UseMethod("tmapGetShapeMeta2") 71 | } 72 | 73 | 74 | -------------------------------------------------------------------------------- /R/tmapShape_misc.R: -------------------------------------------------------------------------------- 1 | #' Internal tmap function to create by variables (used for faceting) 2 | #' 3 | #' Internal tmap function to create by variables (used for faceting) 4 | #' 5 | #' @param dt data.table 6 | #' @param tmf tmf object 7 | #' @param smeta smeta object 8 | #' @export 9 | #' @keywords internal 10 | make_by_vars = function(dt, tmf, smeta) { 11 | by123 = paste0("by", 1L:3L) 12 | by123__ = paste0("by", 1L:3L, "__") 13 | with(tmf, { 14 | if (length(b)) { 15 | for (w in b) { 16 | byvar = by123[w] 17 | byname = by123__[w] 18 | var = tmf[[byvar]] 19 | 20 | if (var == "FRAME__") { 21 | dt[, (byname):= NA_integer_] # dummy 22 | } else if (var %in% smeta$vars) { 23 | levs = smeta$vars_levs[[var]] 24 | if (is.null(levs)) { 25 | cli::cli_abort("Variable {.val {var}} is used as facetting variable. Therefore, it should be a factor.") 26 | } 27 | if (attr(levs, "showNA")) levs[length(levs)] = NA 28 | 29 | dt[, (byname):= match(get(get(..byvar)), levs)] 30 | } else if (tmf[[byvar]] %in% smeta$dims) { 31 | dt[, (byname):= match(get(get(..byvar)), smeta$dims_vals[[var]])] 32 | } 33 | } 34 | } 35 | }) 36 | invisible(NULL) 37 | } 38 | 39 | 40 | 41 | #' Internal tmap function that gets factor levels with NA's 42 | #' 43 | #' Internal tmap function that gets factor levels with NA's 44 | #' 45 | #' @param x vector 46 | #' @param o options 47 | #' @export 48 | #' @keywords internal 49 | get_fact_levels_na = function(x, o) { 50 | if (inherits(x, "sfc") || is.list(x)) { 51 | levs = NULL 52 | } else if (is.factor(x)) { 53 | if (o$drop.empty.facets) { 54 | tab = tabulate(x, nbins = nlevels(x)) 55 | anyna = (sum(tab) != length(x)) # note that NA can already be included in the levels (in that case anyna = FALSE) 56 | levs = levels(x)[tab != 0] 57 | } else { 58 | anyna = anyNA(x) 59 | levs = levels(x) 60 | } 61 | 62 | if (!o$drop.NA.facets && anyna) { 63 | showNA = TRUE 64 | levs = c(levs, o$na.text) 65 | } else if (!o$drop.NA.facets && any(is.na(levs))) { 66 | showNA = TRUE 67 | levs[is.na(levs)] = o$na.text 68 | } else if (o$drop.NA.facets && any(is.na(levs))) { 69 | showNA = FALSE 70 | levs = levs[!is.na(levs)] 71 | } else { 72 | showNA = FALSE 73 | } 74 | } else { 75 | u = unique(as.vector(x)) 76 | if (length(u) > o$facet.max) { 77 | levs = NULL 78 | } else { 79 | levs = as.character(sort(u)) 80 | if (!o$drop.NA.facets && any(is.na(u))) { 81 | showNA = TRUE 82 | levs = c(levs, o$na.text) 83 | } else { 84 | showNA = FALSE 85 | } 86 | } 87 | } 88 | if (!is.null(levs)) attr(levs, "showNA") = showNA 89 | levs 90 | } 91 | -------------------------------------------------------------------------------- /R/tmapShape_simplification.R: -------------------------------------------------------------------------------- 1 | downsample_stars = function(x, max.raster) { 2 | k = length(dim(x)) 3 | xy_dim = get_xy_dim(x) 4 | 5 | fact = round(sqrt(prod(xy_dim) / max.raster) - 1) 6 | 7 | n = dim(x) 8 | n[] = 0L 9 | n[names(xy_dim)] = fact 10 | 11 | if (inherits(x, "stars_proxy") || (fact > 0)) { 12 | y = stars::st_downsample(x, n) 13 | message("stars object downsampled to ", paste(get_xy_dim(y), collapse = " by "), " cells.") 14 | } else { 15 | y = x 16 | } 17 | y 18 | } 19 | 20 | downsample_SpatRaster = function(x, max.raster) { 21 | xy_dim = dim(x)[1:2] 22 | 23 | downsample = prod(xy_dim) > max.raster 24 | 25 | y = if (downsample) { 26 | terra::spatSample(x, max.raster, method="regular", as.raster=TRUE) 27 | } else x 28 | 29 | 30 | if (downsample) message("SpatRaster object downsampled to ", paste(dim(y)[1:2], collapse = " by "), " cells.") 31 | 32 | y 33 | } 34 | -------------------------------------------------------------------------------- /R/tmapSplitShp.R: -------------------------------------------------------------------------------- 1 | #' Internal method that split shape objects 2 | #' 3 | #' Internal method that split shape objects. So far, only used to split stars object 4 | #' (from dimension to attributes) 5 | #' 6 | #' @param shp shape 7 | #' @param split_stars_dim name of the dimension to split (`""` to skip) 8 | #' @export 9 | #' @keywords internal 10 | tmapSplitShp = function(shp, split_stars_dim, smeta) { 11 | UseMethod("tmapSplitShp") 12 | } 13 | 14 | #' @export 15 | tmapSplitShp.stars = function(shp, split_stars_dim, smeta) { 16 | if (split_stars_dim != "") { 17 | if (length(smeta$vars) > 1L) shp = merge(shp, name = "DIMVARS__") 18 | 19 | vals = stars::st_get_dimension_values(shp, split_stars_dim) 20 | shp = split(shp, split_stars_dim) 21 | names(shp) = vals 22 | } 23 | shp 24 | } 25 | 26 | #' @export 27 | tmapSplitShp.default = function(shp, split_stars_dim, smeta) { 28 | shp 29 | } -------------------------------------------------------------------------------- /R/tmap_export.R: -------------------------------------------------------------------------------- 1 | #' Export tmap to the format of the used graphics mode 2 | #' 3 | #' * `tmap_grob()` returns a [`grob`][grid::grob()] object (`"plot" mode`) 4 | #' * `tmap_leaflet()` a [`leaflet`][leaflet::leaflet()] object (`"view"` mode). 5 | #' 6 | #' @param x a tmap object. 7 | #' @param asp,scale the desired aspect ratio and scale of the map. Only applicable for `"plot"` mode. 8 | #' @param show show the map? 9 | #' @inheritDotParams print.tmap 10 | #' @return 11 | #' * `tmap_grob()` returns a [`grob`][grid::grob()] object (`"plot"` mode) 12 | #' * `tmap_leaflet()` a [`leaflet`][leaflet::leaflet()] object (`"view"` mode). 13 | #' In case small multiples are shown, a list is returned. 14 | #' @export 15 | #' @examples 16 | #' map = tm_shape(World) + tm_polygons() 17 | #' tmap_leaflet(map, show = TRUE) 18 | tmap_leaflet = function(x, 19 | #mode = "view", 20 | show = FALSE, 21 | #add.titles = TRUE, 22 | #in.shiny = FALSE, 23 | ...) { 24 | current_mode = getOption("tmap.mode") 25 | on.exit({ 26 | options(tmap.mode = current_mode) 27 | }) 28 | options(tmap.mode = "view") 29 | print.tmap(x, show = show, ...) 30 | } 31 | 32 | #' @rdname tmap_leaflet 33 | #' @export 34 | tmap_grob = function(x, 35 | asp = NA, 36 | scale = 1, 37 | show = FALSE, 38 | ...) { 39 | current_mode = getOption("tmap.mode") 40 | on.exit({ 41 | options(tmap.mode = current_mode) 42 | }) 43 | options(tmap.mode = "plot") 44 | print.tmap(x + tm_options(asp = asp, scale = scale), show = show, ...) 45 | } 46 | -------------------------------------------------------------------------------- /R/tmap_palettes.R: -------------------------------------------------------------------------------- 1 | #rm = rownames(tmaptools::tmap.pal.info) 2 | #dput(sapply(rm, cols4all:::c4a_name_convert)) 3 | 4 | pals_v3 = c(BrBG = "brewer.br_bg", PiYG = "brewer.pi_yg", PRGn = "brewer.prgn", 5 | PuOr = "brewer.pu_or", RdBu = "brewer.rd_bu", RdGy = "brewer.rd_gy", 6 | RdYlBu = "brewer.rd_yl_bu", RdYlGn = "brewer.rd_yl_gn", Spectral = "brewer.spectral", 7 | Accent = "brewer.accent", Dark2 = "brewer.dark2", Paired = "brewer.paired", 8 | Pastel1 = "brewer.pastel1", Pastel2 = "brewer.pastel2", Set1 = "brewer.set1", 9 | Set2 = "brewer.set2", Set3 = "brewer.set3", Blues = "brewer.blues", 10 | BuGn = "brewer.bu_gn", BuPu = "brewer.bu_pu", GnBu = "brewer.gn_bu", 11 | Greens = "brewer.greens", Greys = "brewer.greys", Oranges = "brewer.oranges", 12 | OrRd = "brewer.or_rd", PuBu = "brewer.pu_bu", PuBuGn = "brewer.pu_bu_gn", 13 | PuRd = "brewer.pu_rd", Purples = "brewer.purples", RdPu = "brewer.rd_pu", 14 | Reds = "brewer.reds", YlGn = "brewer.yl_gn", YlGnBu = "brewer.yl_gn_bu", 15 | YlOrBr = "brewer.yl_or_br", YlOrRd = "brewer.yl_or_rd") 16 | 17 | 18 | getPal = function(name, n = NA, rep = TRUE, range = NA, reversed = FALSE) { 19 | if (name %in% c("cat", "seq", "div")) { 20 | name = cols4all::c4a_options("defaults")$defaults[[name]] 21 | } 22 | 23 | cols4all::c4a(name, n = n, nm_invalid = {if (rep) "repeat" else "interpolate"}, range = range, reverse = reversed) 24 | } 25 | 26 | getPalNA = function(name) { 27 | if (name %in% c("cat", "seq", "div")) { 28 | name = cols4all::c4a_options("defaults")$defaults[[name]] 29 | } 30 | cols4all::c4a_na(name) 31 | } 32 | 33 | getPalBiv = function(name, m = NA, n = NA, rep = TRUE) { 34 | cols4all::c4a(name, m = m, n = n, nm_invalid = {if (rep) "repeat" else "interpolate"}) 35 | } 36 | 37 | getPalMeta = function(name, no.match = "null") { 38 | if (!is.character(name)) return(NULL) 39 | if (name %in% c("cat", "seq", "div")) { 40 | name = cols4all::c4a_options("defaults")$defaults[[name]] 41 | } 42 | if (name %in% names(pals_v3)) { 43 | oldname = name 44 | name = unname(pals_v3[oldname]) 45 | info = cols4all::c4a_info(name, verbose = FALSE) 46 | message_c4a(oldname, info, fullname = info$series == "brewer") 47 | } else { 48 | info = cols4all::c4a_info(name, no.match = no.match, verbose = FALSE) 49 | } 50 | info 51 | } 52 | -------------------------------------------------------------------------------- /R/tmap_providers.R: -------------------------------------------------------------------------------- 1 | #' @rdname tmap_providers 2 | #' @param provider provider name 3 | #' @export 4 | tmap_provider_credits = function(provider) { 5 | x = tmap_providers(credits = TRUE) 6 | if (provider %in% names(x)) { 7 | x[[provider]] 8 | } else 9 | "" 10 | } 11 | 12 | #' Get basemap tiles providers 13 | #' 14 | #' Get basemap tiles providers and the credits (attribution text). [tmap_providers()] returns a list (or vector) with provider nams (or credits). [tmap_provider_credits()] 15 | #' 16 | #' @param mode mode. If not specified the default mode is used 17 | #' @param credits If `TRUE` the credit (attribution) text is returned. If `FALSE` (default) the provider name. 18 | #' @param as.list Should the output be returned as list where names are provider names? By default `TRUE` when `credits` is also `TRUE`. 19 | #' @return list or vector (see `as.list`) with providers (or credits). [tmap_provider_credits()] returns the credits text for the provided provider. 20 | #' @export 21 | #' @name tmap_providers 22 | tmap_providers = function(mode, credits = FALSE, as.list = credits) { 23 | if (missing(mode)) mode = getOption("tmap.mode") 24 | gs = tmap_graphics_name(mode) 25 | 26 | fun = paste0("tmap", gs, "Providers") 27 | x = do.call(fun, list(credits = credits)) 28 | if (as.list) { 29 | x 30 | } else { 31 | unlist(x, use.names = FALSE) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /R/tmap_tip.R: -------------------------------------------------------------------------------- 1 | #' Print a random tip to the console 2 | #' 3 | #' @returns A message 4 | #' @export 5 | tmap_tip <- function() { 6 | nr = .TMAP$tip_nr 7 | tip = .TMAP$tips[nr] 8 | 9 | nr2 = if (nr == length(.TMAP$tips)) 1L else nr + 1L 10 | 11 | .TMAP$tip_nr = nr2 12 | 13 | cli::cli_inform(tip, .frequency_id = "tmap_tip", .frequency = "always") 14 | } 15 | -------------------------------------------------------------------------------- /R/tme_graphics.R: -------------------------------------------------------------------------------- 1 | # tme_graphics = function(init, polygons, symbols, lines, raster) { 2 | # structure(list(init = init, polygons = polygons, symbols = symbols, lines = lines, raster = raster), class = "tme_graphics") 3 | # } 4 | # 5 | # 6 | # 7 | # tme_graphics.grid = tme_graphics( 8 | # require = "grid", 9 | # init = function(bbx) { 10 | # if (!requireNamespace("grid")) stop("grid package required but not installed yet.") 11 | # grid.newpage() 12 | # grid::pushViewport(viewport(xscale = st_bbox(World)[c(1,3)], yscale = st_bbox(World)[c(2,4)])) 13 | # }, 14 | # polygons = function(x, col, alpha, border.col, border.lwd, border.lty) { 15 | # geoms = sf::st_geometry(x) 16 | # gp = gpar(fill=col, col=border.col, lwd=border.lwd, lty=border.lty) 17 | # sf::st_as_grob(geoms, gp = gp) 18 | # }, 19 | # symbols = function(x, size, col, shape, alpha, border.col, border.lwd, border.lty) { 20 | # geoms = sf::st_centroid(sf::st_geometry(x)) 21 | # co = sf::st_coordinates(geoms) 22 | # gp = gpar(fill=col, col=border.col, lwd=border.lwd, lty=border.lty) 23 | # 24 | # pointsGrob(x=co[,1], y = co[,2], 25 | # size = size, 26 | # pch = shape, 27 | # gp = get_symbol_gpar(x=symbol.shape2, 28 | # fill=symbol.col2, 29 | # col=bordercol, 30 | # lwd=symbol.border.lwd), 31 | # name=idName) 32 | # } 33 | # 34 | # 35 | # ) 36 | # 37 | # 38 | # tme_grid = function(init, ) 39 | # 40 | # 41 | # 42 | # 43 | # t_polygon = function(x, col, alpha, border.col, border.lwd, border.lty) { 44 | # 45 | # geoms = sf::st_geometry(x) 46 | # 47 | # gp=gpar(fill=col, col=border.col, lwd=border.lwd, lty=border.lty) 48 | # 49 | # st_as_grob(geoms, gp = gp) 50 | # } 51 | # 52 | -------------------------------------------------------------------------------- /R/view_format_popups.R: -------------------------------------------------------------------------------- 1 | view_format_popups <- function(id=NULL, titles, format, values) { 2 | 3 | 4 | 5 | # isnull <- vapply(values, is.null, logical(1)) 6 | # 7 | # titles <- titles[!isnull] 8 | # titles[names(titles)!=""] <- names(titles)[names(titles)!=""] 9 | # 10 | # values <- values[!isnull] 11 | 12 | # islist <- is.list(format) && length(format)>0 && is.list(format[[1]]) 13 | # if (!islist) { 14 | # format <- lapply(1:length(titles), function(i) format) 15 | # } 16 | h = lapply(format, function(f) { 17 | if (f$html.escape) { 18 | htmltools::htmlEscape 19 | } else { 20 | function(x) x 21 | } 22 | }) 23 | if (!is.null(id)) { 24 | labels <- paste("", h[[1]](id), "", sep="") 25 | } else { 26 | labels <- "" 27 | } 28 | 29 | titles_format <- mapply(function(ti, hi) { 30 | hi(ti) 31 | }, titles, h, SIMPLIFY = FALSE) 32 | values_format <- mapply(function(v, f, hi) { 33 | if (inherits(v, "units")) { 34 | popup_append <- paste0(" ", as.character(attr(v, "units"))) 35 | } else { 36 | popup_append <- "" 37 | } 38 | numbers <- hi(if (is.numeric(v)) do.call("fancy_breaks", c(list(vec=as.numeric(v), intervals=FALSE), f)) else v) 39 | paste0(numbers, popup_append) 40 | }, values, format, h, SIMPLIFY = FALSE) 41 | 42 | 43 | labels2 <- mapply(function(l, v) { 44 | paste0("", l, "", v, "") 45 | }, titles_format, values_format, SIMPLIFY=FALSE) 46 | 47 | labels3 <- paste0(do.call("paste", c(labels2, list(sep=""))), "") 48 | 49 | padding_right <- ifelse(length(titles_format) > 13, 15, 0) # add padding for horizontal scroll bar. These will appear on most browsers when there are over 13 normal lines (tested: RStudio, FF, Chrome) 50 | 51 | x <- paste0("
52 | ", labels3, "
", labels, "
") 53 | 54 | x 55 | } 56 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | 3 | coverage: 4 | status: 5 | project: 6 | default: 7 | target: auto 8 | threshold: 1% 9 | informational: true 10 | patch: 11 | default: 12 | target: auto 13 | threshold: 1% 14 | informational: true 15 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## Test environments 2 | * macOS (devel and release) 3 | * windows (devel and release) 4 | * Ubuntu (devel and release) 5 | 6 | ## Submission note 7 | 8 | * All reverse dependencies have been carefully checked 9 | 10 | ## R CMD check results 11 | 12 | 0 errors | 0 warnings | 0 note 13 | 14 | ## Reverse dependencies 15 | 16 | All reverse dependencies run OK 17 | -------------------------------------------------------------------------------- /data-raw/World_rivers.R: -------------------------------------------------------------------------------- 1 | library(rnaturalearth) 2 | library(sf) 3 | library(dplyr) 4 | 5 | rivers <- rnaturalearth::ne_download(scale = 50, type = "rivers_lake_centerlines_scale_rank", category = "physical", returnclass = "sf") 6 | rivers$strokeweig <- rivers$strokeweig * 10 7 | 8 | rivers <- rivers %>% select(name, type=featurecla, scalerank, strokelwd = strokeweig) 9 | 10 | #rivers$name <- factor(rivers$name) 11 | rivers$type <- factor(rivers$type) 12 | rivers$scalerank <- as.integer(rivers$scalerank) 13 | rivers$strokelwd <- as.numeric(rivers$strokelwd) 14 | 15 | Encoding(rivers$name) <- "latin1" 16 | rivers$name <- iconv( 17 | rivers$name, 18 | "latin1", 19 | "ASCII", 20 | "" 21 | ) 22 | x <- grep("I_WAS_NOT_ASCII", iconv(levels(rivers$name), "latin1", "ASCII", sub="I_WAS_NOT_ASCII")) 23 | 24 | rivers = sf::st_set_crs(rivers, 4326) 25 | 26 | rivers = rivers %>% 27 | dplyr::filter(!is.na(type)) 28 | 29 | 30 | rivers$geometry = rivers |> st_geometry() |> st_sfc(precision = 1000) %>% st_as_binary %>% st_as_sfc 31 | 32 | World_rivers = rivers 33 | 34 | World_rivers = st_set_crs(World_rivers, 4326) 35 | 36 | save(World_rivers, file="data/World_rivers.rda", compress="xz") 37 | -------------------------------------------------------------------------------- /data-raw/compass_png.R: -------------------------------------------------------------------------------- 1 | x = tm_shape(NLD_muni) + 2 | tm_polygons(fill = NA, col = NA) + 3 | tm_layout(frame = FALSE) 4 | 5 | x_arrow = x + tm_compass(position = tm_pos_in("center", "center"), size = 4, text.size = 5) 6 | x_radar = x + tm_compass(position = tm_pos_in("center", "center"), size = 4, text.size = 5, type = "radar") 7 | x_rose = x + tm_compass(position = tm_pos_in("center", "center"), size = 4, text.size = 5, type = "rose") 8 | x_4star = x + tm_compass(position = tm_pos_in("center", "center"), size = 4, text.size = 5, type = "4star") 9 | x_8star = x + tm_compass(position = tm_pos_in("center", "center"), size = 4, text.size = 5, type = "8star") 10 | 11 | png(filename = "inst/img/compass_arrow.png", bg = "transparent", width = 400, height = 400); x_arrow; dev.off() 12 | png(filename = "inst/img/compass_radar.png", bg = "transparent", width = 400, height = 400); x_radar; dev.off() 13 | png(filename = "inst/img/compass_rose.png", bg = "transparent", width = 400, height = 400); x_rose; dev.off() 14 | png(filename = "inst/img/compass_4star.png", bg = "transparent", width = 400, height = 400); x_4star; dev.off() 15 | png(filename = "inst/img/compass_8star.png", bg = "transparent", width = 400, height = 400); x_8star; dev.off() 16 | 17 | -------------------------------------------------------------------------------- /data-raw/sysdata.R: -------------------------------------------------------------------------------- 1 | ## v3 functions and arguments 2 | library(remotes) 3 | install_github("r-tmap/tmap@v3") 4 | 5 | library(tmap) 6 | 7 | get_tmap_funs = function() { 8 | nms = getNamespaceExports("tmap") 9 | funs = lapply(nms, function(f) { 10 | g = get(f) 11 | if (is.function(g)) { 12 | x = setdiff(names(do.call(formals, list(g))), "...") 13 | if (is.null(x)) x = character() 14 | x 15 | } else { 16 | NULL 17 | } 18 | }) 19 | names(funs) = nms 20 | funs[!sapply(funs, is.null)] 21 | } 22 | 23 | funs_v3 = get_tmap_funs() 24 | 25 | funs_v3$tm_polygons = unique(c(funs_v3$tm_fill, funs_v3$tm_polygons, funs_v3$tm_borders)) 26 | 27 | 28 | ## v4 functions and arguments 29 | devtools::load_all() 30 | 31 | funs_v4 = get_tmap_funs() 32 | usethis::use_data(funs_v3, funs_v4, internal = TRUE, overwrite = TRUE) 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /data/NLD_dist.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/data/NLD_dist.rda -------------------------------------------------------------------------------- /data/NLD_muni.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/data/NLD_muni.rda -------------------------------------------------------------------------------- /data/NLD_prov.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/data/NLD_prov.rda -------------------------------------------------------------------------------- /data/World.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/data/World.rda -------------------------------------------------------------------------------- /data/World_rivers.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/data/World_rivers.rda -------------------------------------------------------------------------------- /data/land.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/data/land.rda -------------------------------------------------------------------------------- /data/metro.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/data/metro.rda -------------------------------------------------------------------------------- /demo/tutorials/rmarkdown_tmap.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Embedding tmap in RMarkdown" 3 | output: html_notebook 4 | --- 5 | 6 | 7 | ```{r} 8 | library(tmap) 9 | ``` 10 | 11 | # Maps made in plot mode 12 | 13 | ```{r} 14 | tmap_mode("plot") 15 | data(World) 16 | tm_shape(World) + 17 | tm_polygons("HPI") 18 | ``` 19 | # Maps made in view mode 20 | 21 | 22 | ```{r} 23 | tmap_mode("view") 24 | data(World) 25 | tm_shape(World) + 26 | tm_polygons("HPI", id = "iso_a3", popup.vars = TRUE) 27 | ``` 28 | -------------------------------------------------------------------------------- /demo/tutorials/sfnetworks.R: -------------------------------------------------------------------------------- 1 | library(sfnetworks) 2 | 3 | sfn <- as_sfnetwork(roxel) 4 | 5 | tm_shape(sfn) + 6 | tm_lines(col = "type", lwd = 2) + 7 | tm_dots(size = .3) 8 | -------------------------------------------------------------------------------- /examples/qtm.R: -------------------------------------------------------------------------------- 1 | data(World, World_rivers, metro) 2 | 3 | # just the map 4 | qtm(World) 5 | 6 | # choropleth 7 | qtm(World, fill = "economy", style = "cobalt", crs = "+proj=eck4") 8 | 9 | qtm(World, col = NULL) + 10 | qtm(metro, size = "pop2010", 11 | size.legend = tm_legend("Metropolitan Areas")) 12 | 13 | # dot map 14 | \dontrun{ 15 | current.mode <- tmap_mode("view") 16 | qtm(metro, bbox = "China") 17 | tmap_mode(current.mode) # restore mode 18 | } 19 | 20 | \dontrun{ 21 | # without arguments, a plain interactive map is shown (the mode is set to view) 22 | qtm() 23 | 24 | # search query for OpenStreetMap nominatim 25 | qtm("Amsterdam") 26 | } 27 | -------------------------------------------------------------------------------- /examples/tm_add_legend.R: -------------------------------------------------------------------------------- 1 | \dontrun{ 2 | tm_shape(NLD_muni) + 3 | tm_borders() + 4 | tm_basemap("OpenStreetMap") + 5 | tm_add_legend(labels = c("Motorway", "Primary road", "Secondary road", "Railway"), 6 | col = c("#E892A1", "#FCD6A4", "#F8FABF", "#707070"), 7 | lty = c("solid", "solid", "solid", "dotted"), 8 | lwd = 3, 9 | type = "lines", 10 | bg.color = "grey92", 11 | bg.alpha = 1) 12 | } 13 | -------------------------------------------------------------------------------- /examples/tm_animate.R: -------------------------------------------------------------------------------- 1 | \dontrun{ 2 | tm_shape(metro) + 3 | tm_symbols(size = tm_vars(4:12), size.free = FALSE, size.legend = tm_legend("Population")) + 4 | tm_animate_slow() 5 | } 6 | -------------------------------------------------------------------------------- /examples/tm_basemap.R: -------------------------------------------------------------------------------- 1 | \dontrun{ 2 | if (requireNamespace("maptiles")) { 3 | # view mode 4 | current_mode = tmap_mode("view") 5 | tm_basemap("Stadia.StamenWatercolor") + 6 | tm_shape(World) + 7 | tm_polygons( 8 | "HPI", 9 | fill.scale = tm_scale(values = "reds"), 10 | fill_alpha.scale = 0.5) 11 | 12 | tm_shape(World, crs = "+proj=eqearth") + 13 | tm_polygons( 14 | "HPI", 15 | fill.scale = tm_scale(values = "reds"), 16 | fill_alpha.scale = 0.5) + 17 | tm_basemap(NULL) 18 | 19 | # plot mode: 20 | tmap_mode("plot") 21 | tm_basemap() + 22 | tm_shape(World) + 23 | tm_polygons("HPI") 24 | 25 | tm_basemap("OpenTopoMap") + 26 | tm_shape(World) + 27 | tm_polygons(fill = NA, col = "black") 28 | 29 | tm_basemap("CartoDB.PositronNoLabels") + 30 | tm_shape(NLD_prov, crs = 4236) + 31 | tm_borders() + 32 | tm_facets_wrap("name") + 33 | tm_tiles("CartoDB.PositronOnlyLabels") 34 | 35 | # restore mode 36 | tmap_mode(current_mode) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /examples/tm_chart.R: -------------------------------------------------------------------------------- 1 | tm_shape(World) + 2 | tm_polygons("HPI", 3 | fill.scale = tm_scale_intervals(), 4 | fill.chart = tm_chart_histogram()) 5 | -------------------------------------------------------------------------------- /examples/tm_compass.R: -------------------------------------------------------------------------------- 1 | tm_shape(NLD_muni) + 2 | tm_polygons("origin_native") + 3 | tm_compass(type = "8star", position = tm_pos_in("right", "bottom")) 4 | 5 | tm_shape(NLD_muni) + 6 | tm_polygons("origin_native") + 7 | tm_compass(type = "8star", position = tm_pos_out("right", "center", 8 | pos.h = "left", pos.v = "top")) 9 | 10 | tm_shape(NLD_muni) + 11 | tm_polygons("origin_native", 12 | fill.legend = tm_legend(position = tm_pos_in("left", "top"))) + 13 | tm_compass(type = "8star", position = tm_pos_in("left", "top")) 14 | 15 | tm_shape(NLD_muni) + 16 | tm_polygons("origin_native", 17 | fill.legend = tm_legend(position = tm_pos_in("left", "bottom"))) + 18 | tm_compass(type = "4star", position = tm_pos_in("left", "bottom", align.v = "bottom"), 19 | stack = "horizontal") + 20 | tm_layout(inner.margins = c(0.4, 0.1, 0.1, 0.1)) 21 | 22 | 23 | ### examples V3 24 | current.mode = tmap_mode("plot") 25 | 26 | data(NLD_muni) 27 | 28 | tm_shape(NLD_muni) + 29 | tm_polygons() + 30 | tm_format("NLD") + 31 | tm_compass(type = "8star") 32 | 33 | #qtm(NLD_muni, theme = "NLD") + tm_compass() 34 | #qtm(NLD_muni, theme = "NLD") + tm_compass(type="radar", position=c("left", "top"), show.labels = 3) 35 | 36 | # restore current mode 37 | tmap_mode(current.mode) 38 | -------------------------------------------------------------------------------- /examples/tm_credits.R: -------------------------------------------------------------------------------- 1 | tm_shape(NLD_muni) + 2 | tm_fill(col="population", convert2density=TRUE, 3 | style="kmeans", title = expression("Population (per " * km^2 * ")")) + 4 | tm_borders("grey25", alpha=.5) + 5 | tm_shape(NLD_prov) + 6 | tm_borders("grey40", lwd=2) + 7 | tm_format("NLD", bg.color="white", frame = TRUE) + 8 | tm_credits("(c) Statistics Netherlands (CBS) and\nKadaster Nederland", position=tm_pos_in("left", "bottom")) 9 | 10 | 11 | ############################################ 12 | ## tmap v3 example: 13 | ############################################ 14 | 15 | ## no backwards compatibility for position=c("left", "bottom") yet 16 | 17 | current.mode <- tmap_mode("plot") 18 | 19 | data(NLD_muni, NLD_prov) 20 | 21 | tm_shape(NLD_muni) + 22 | tm_fill(col="population", convert2density=TRUE, 23 | style="kmeans", title = expression("Population (per " * km^2 * ")")) + 24 | tm_borders("grey25", alpha=.5) + 25 | tm_shape(NLD_prov) + 26 | tm_borders("grey40", lwd=2) + 27 | tm_format("NLD", bg.color="white", frame = TRUE) + 28 | tm_credits("(c) Statistics Netherlands (CBS) and\nKadaster Nederland", position=c("left", "bottom")) 29 | 30 | # restore current mode 31 | tmap_mode(current.mode) 32 | -------------------------------------------------------------------------------- /examples/tm_crs.R: -------------------------------------------------------------------------------- 1 | SA = World[World$continent == "South America", ] 2 | 3 | # latlon coordinates (WGS84) 4 | tm_shape(SA) + 5 | tm_polygons() + 6 | tm_graticules() + 7 | tm_crs(4326) 8 | 9 | tm_list = lapply(c("global", "area", "distance", "shape"), FUN = function(property) { 10 | tm_shape(SA) + 11 | tm_polygons() + 12 | tm_graticules() + 13 | tm_crs(property = property) + 14 | tm_title(property) 15 | }) 16 | 17 | tmap_arrange(tm_list, nrow = 1) 18 | -------------------------------------------------------------------------------- /examples/tm_facets.R: -------------------------------------------------------------------------------- 1 | \dontrun{ 2 | tm_shape(NLD_dist) + 3 | tm_polygons("edu_appl_sci", 4 | fill.scale = tm_scale_intervals(values = "pu_gn", style = "kmeans", n = 7)) + 5 | tm_facets(by = "province") + 6 | tm_shape(NLD_muni) + 7 | tm_borders(lwd = 3) + 8 | tm_facets(by = "province") + 9 | tm_title("Population with a univeristy degree (incl appl. sciences), percentages") 10 | 11 | tm_shape(World) + 12 | tm_polygons(c("gender", "press"), 13 | fill.scale = list(tm_scale_intervals(values = "bu_br_div", midpoint = 0.5), 14 | tm_scale_intervals(values = "pu_gn_div", midpoint = 50)), 15 | fill.legend = tm_legend("")) + 16 | tm_layout(panel.labels = c("Gender Inequality Index (GII)", "World Press Freedom Index")) 17 | } 18 | -------------------------------------------------------------------------------- /examples/tm_grid.R: -------------------------------------------------------------------------------- 1 | \dontrun{ 2 | current.mode <- tmap_mode("plot") 3 | 4 | tm_shape(NLD_muni) + 5 | tm_polygons() + 6 | tm_grid() 7 | 8 | tm_shape(NLD_muni) + 9 | tm_polygons() + 10 | tm_grid(crs = 4326) 11 | 12 | tm_shape(NLD_muni) + 13 | tm_polygons() + 14 | tm_grid(crs = 3035, labels.inside.frame = TRUE) 15 | 16 | tm_shape(World) + 17 | tm_polygons() + 18 | tm_facets(by = "continent") + 19 | tm_grid(labels.inside.frame = TRUE) 20 | 21 | tm_shape(NLD_muni) + 22 | tm_polygons() + 23 | tm_graticules() 24 | 25 | tm_shape(NLD_muni) + 26 | tm_polygons() + 27 | tm_graticules(labels.pos = c("right", "top")) 28 | 29 | 30 | data(NLD_muni, World) 31 | 32 | tmap_arrange( 33 | qtm(NLD_muni) + tm_grid(), 34 | qtm(NLD_muni) + tm_graticules() 35 | ) 36 | 37 | qtm(World, shape.crs = "+proj=robin", style = "natural") + 38 | tm_graticules(ticks = FALSE) + 39 | tm_layout(frame=FALSE) 40 | 41 | tmap_mode(current.mode) 42 | } 43 | -------------------------------------------------------------------------------- /examples/tm_inset.R: -------------------------------------------------------------------------------- 1 | ## map 2 | bb = tmaptools::bb(NLD_prov[NLD_prov$name == "Utrecht",], ext = 1.05) 3 | 4 | bb_Randstad = 5 | sf::st_bbox(c(xmin = 120000, xmax = 150000, ymin = 460000, ymax = 500000), crs = 28992) 6 | 7 | tm_shape(NLD_dist) + 8 | tm_polygons( 9 | fill = "dwelling_value", 10 | fill.scale = tm_scale_continuous_pseudo_log(values = "-cols4all.pu_gn_div"), 11 | col = NULL) + 12 | tm_shape(NLD_muni) + 13 | tm_borders(col = "black", lwd = 0.5) + 14 | tm_shape(NLD_prov) + 15 | tm_borders(col = "black", lwd = 1.5) + 16 | tm_inset(bb_Randstad, height = 12, width = 12, position = c("left", "top")) + 17 | tm_compass(position = c("left", "top"), ) 18 | 19 | ## ggplot2 20 | if (requireNamespace("ggplot2")) { 21 | library(ggplot2) 22 | p = ggplot(World, aes(x = gender, y = press, colour = continent)) + 23 | geom_point() + 24 | theme_bw() 25 | 26 | tm_shape(World) + 27 | tm_polygons( 28 | fill = "gender", 29 | fill.scale = tm_scale(values = "-cols4all.pu_gn_div")) + 30 | tm_inset(p, height = 15, width = 20, position = tm_pos_in("left", "bottom")) 31 | } 32 | -------------------------------------------------------------------------------- /examples/tm_layout.R: -------------------------------------------------------------------------------- 1 | tm_shape(World) + 2 | tm_polygons() + 3 | tm_layout( 4 | bg.color = "steelblue", 5 | outer.bg.color = "gold", 6 | frame.lwd = 3, 7 | inner.margins = 0) 8 | 9 | tm_shape(World) + 10 | tm_polygons(fill = "HPI") + 11 | tm_style("classic") 12 | 13 | tm_shape(World) + 14 | tm_polygons(fill = "HPI") + 15 | tm_style("cobalt") 16 | -------------------------------------------------------------------------------- /examples/tm_legend.R: -------------------------------------------------------------------------------- 1 | # Example using different settings from tm_legend() 2 | 3 | tm_shape(World) + 4 | tm_polygons( 5 | fill = "HPI", 6 | fill.legend = tm_legend( 7 | title = "Home Price Index", 8 | design = "standard", 9 | title.color = "orange", 10 | bg.color = "purple", 11 | show = TRUE 12 | ), 13 | id = "name", 14 | # Format the labels using dollar sign 15 | fill.scale = tm_scale_intervals( 16 | label.format = function(x) format(x, big.mark = " ")), 17 | ) 18 | -------------------------------------------------------------------------------- /examples/tm_lines.R: -------------------------------------------------------------------------------- 1 | tm_shape(World_rivers) + 2 | tm_lines(lwd = "strokelwd", 3 | lwd.scale = tm_scale_asis(values.scale = 0.2, value.neutral = 2), 4 | col = "scalerank", 5 | col.scale = tm_scale_categorical(values = "seaborn.dark")) 6 | 7 | tm_shape(World) + 8 | tm_lines(col = "continent", 9 | col.scale = tm_scale_categorical(values = "seaborn.dark"), 10 | lty = "continent", 11 | lwd = 1.5, 12 | lty.legend = tm_legend_combine("col")) 13 | -------------------------------------------------------------------------------- /examples/tm_logo.R: -------------------------------------------------------------------------------- 1 | data(World) 2 | 3 | tm_shape(World) + 4 | tm_polygons("HPI", fill.scale = tm_scale_intervals(values = "brewer.rd_yl_gn")) + 5 | tm_logo(c("https://www.r-project.org/logo/Rlogo.png", 6 | system.file("help", "figures", "logo.png", package = "tmap"))) + 7 | tm_logo("http://blog.kulikulifoods.com/wp-content/uploads/2014/10/logo.png", 8 | height=5, position = c("left", "top")) 9 | -------------------------------------------------------------------------------- /examples/tm_polygons.R: -------------------------------------------------------------------------------- 1 | # load Africa country data 2 | data(World) 3 | Africa = World[World$continent == "Africa", ] 4 | Africa_border = sf::st_make_valid(sf::st_union(sf::st_buffer(Africa, 0.001))) # slow and ugly 5 | 6 | # without specifications 7 | tm_shape(Africa_border) + tm_polygons() 8 | tm_shape(Africa_border) + tm_fill() 9 | tm_shape(Africa_border) + tm_borders() 10 | 11 | # specification with visual variable values 12 | tm_shape(Africa) + 13 | tm_polygons(fill = "limegreen", col = "purple", lwd = 2, lty = "solid", col_alpha = 0.3) + 14 | tm_text("name", options = opt_tm_text(remove_overlap = TRUE)) + 15 | tm_shape(Africa_border) + 16 | tm_borders("darkred", lwd = 3) 17 | 18 | # specification with a data variable 19 | tm_shape(Africa) + 20 | tm_polygons(fill = "income_grp", fill.scale = tm_scale_categorical(values = "-tol.muted")) 21 | 22 | 23 | # continuous color scale with landscape legend 24 | tm_shape(Africa) + 25 | tm_polygons(fill = "inequality", 26 | fill.scale = tm_scale_continuous(values = "-scico.roma"), 27 | fill.legend = tm_legend( 28 | title = "", orientation = "landscape", 29 | position = tm_pos_out("center", "bottom"), frame = FALSE 30 | )) + 31 | tm_shape(Africa_border) + 32 | tm_borders(lwd = 2) + 33 | tm_title("Inequality index", position = tm_pos_in("right", "TOP"), frame = FALSE) + 34 | tm_layout(frame = FALSE) 35 | 36 | # bivariate scale 37 | tm_shape(World) + 38 | tm_polygons(tm_vars(c("inequality", "well_being"), multivariate = TRUE)) 39 | -------------------------------------------------------------------------------- /examples/tm_raster.R: -------------------------------------------------------------------------------- 1 | \dontrun{ 2 | # load land data 3 | data(land, World) 4 | 5 | tm_shape(land) + 6 | tm_raster("cover") 7 | 8 | tm_shape(land) + 9 | tm_raster("elevation", col.scale = tm_scale_continuous(values = terrain.colors(9))) + 10 | tm_shape(World) + 11 | tm_borders() 12 | } 13 | -------------------------------------------------------------------------------- /examples/tm_rgb.R: -------------------------------------------------------------------------------- 1 | \dontrun{ 2 | require(stars) 3 | file = system.file("tif/L7_ETMs.tif", package = "stars") 4 | 5 | L7 = stars::read_stars(file) 6 | 7 | tm_shape(L7) + 8 | tm_rgb() 9 | 10 | # the previous example was a shortcut of this call 11 | tm_shape(L7) + 12 | tm_rgb(col = tm_vars("band", dimvalues = 1:3, multivariate = TRUE)) 13 | 14 | # alternative format: using a stars dimension instead of attributes 15 | L7_alt = split(L7, "band") 16 | tm_shape(L7_alt) + 17 | tm_rgb() 18 | 19 | # with attribute names 20 | tm_shape(L7_alt) + 21 | tm_rgb(col = tm_vars(c("X1", "X2", "X3"), multivariate = TRUE)) 22 | 23 | # with attribute indices 24 | tm_shape(L7_alt) + 25 | tm_rgb(col = tm_vars(1:3, multivariate = TRUE)) 26 | 27 | if (requireNamespace("terra")) { 28 | L7_terra = terra::rast(file) 29 | 30 | tm_shape(L7_terra) + 31 | tm_rgb() 32 | 33 | # with layer names 34 | tm_shape(L7_terra) + 35 | tm_rgb(tm_vars(names(L7_terra)[1:3], multivariate = TRUE)) 36 | 37 | # with layer indices 38 | tm_shape(L7_alt) + 39 | tm_rgb(col = tm_vars(1:3, multivariate = TRUE)) 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /examples/tm_scale_continuous.R: -------------------------------------------------------------------------------- 1 | tm_shape(World) + 2 | tm_polygons( 3 | fill = "HPI", 4 | fill.scale = tm_scale_continuous(values = "scico.roma", midpoint = 30)) 5 | 6 | tm_shape(metro) + 7 | tm_bubbles( 8 | size = "pop1950", 9 | size.scale = tm_scale_continuous( 10 | values.scale = 1), 11 | size.legend = tm_legend("Population in 1950", frame = FALSE)) 12 | 13 | tm_shape(metro) + 14 | tm_bubbles( 15 | size = "pop1950", 16 | size.scale = tm_scale_continuous( 17 | values.scale = 2, 18 | limits = c(0, 12e6), 19 | ticks = c(1e5, 3e5, 8e5, 4e6, 1e7), 20 | labels = c("0 - 200,000", "200,000 - 500,000", "500,000 - 1,000,000", 21 | "1,000,000 - 10,000,000", "10,000,000 or more"), 22 | outliers.trunc = c(TRUE, TRUE)), 23 | size.legend = tm_legend("Population in 1950", frame = FALSE)) 24 | # Note that for this type of legend, we recommend tm_scale_intervals() 25 | -------------------------------------------------------------------------------- /examples/tm_scale_rgb.R: -------------------------------------------------------------------------------- 1 | \dontrun{ 2 | require(stars) 3 | file = system.file("tif/L7_ETMs.tif", package = "stars") 4 | 5 | L7 = stars::read_stars(file) 6 | 7 | tm_shape(L7) + 8 | tm_rgb(col.scale = tm_scale_rgb(probs = c(0, .99), stretch = TRUE)) 9 | 10 | tm_shape(L7) + 11 | tm_rgb(col.scale = tm_scale_rgb(stretch = "histogram")) 12 | } 13 | -------------------------------------------------------------------------------- /examples/tm_sf.R: -------------------------------------------------------------------------------- 1 | data(World) 2 | 3 | World$geometry[World$continent == "Africa"] <- 4 | sf::st_centroid(World$geometry[World$continent == "Africa"]) 5 | World$geometry[World$continent == "South America"] <- 6 | sf::st_cast(World$geometry[World$continent == "South America"], 7 | "MULTILINESTRING", group_or_split = FALSE) 8 | 9 | tm_shape(World, crs = "+proj=robin") + 10 | tm_sf() 11 | -------------------------------------------------------------------------------- /examples/tm_shape.R: -------------------------------------------------------------------------------- 1 | tm_shape(World, crs = "auto") + 2 | tm_polygons() 3 | 4 | tm_shape(World, crs = 3035, bb = "Europe") + 5 | tm_polygons() 6 | 7 | tm_shape(World, crs = "+proj=robin", filter = World$continent=="Africa") + 8 | tm_polygons() 9 | -------------------------------------------------------------------------------- /examples/tm_symbols.R: -------------------------------------------------------------------------------- 1 | ######################## 2 | ## plot symbol shapes 3 | ######################## 4 | 5 | # create grid of 25 points in the Atlantic 6 | atlantic_grid = cbind(expand.grid(x = -51:-47, y = 20:24), id = seq_len(25)) 7 | x = sf::st_as_sf(atlantic_grid, coords = c("x", "y"), crs = 4326) 8 | 9 | tm_shape(x, bbox = tmaptools::bb(x, ext = 1.2)) + 10 | tm_symbols(shape = "id", 11 | size = 2, 12 | lwd = 2, 13 | fill = "orange", 14 | col = "black", 15 | shape.scale = tm_scale_asis()) + 16 | tm_text("id", ymod = -2) 17 | -------------------------------------------------------------------------------- /examples/tm_text.R: -------------------------------------------------------------------------------- 1 | tm_shape(World, bbox = World) + 2 | tm_text("name", size="pop_est", col="continent", 3 | col.scale = tm_scale_categorical(values = "seaborn.dark"), 4 | col.legend = tm_legend_hide(), 5 | size.scale = tm_scale_continuous(values.scale = 4), 6 | size.legend = tm_legend_hide()) 7 | 8 | metro$upside_down = ifelse(sf::st_coordinates(metro)[,2] < 0, 180, 0) 9 | tm_shape(metro) + 10 | tm_text(text = "name", size = "pop2020", 11 | angle = "upside_down", size.legend = tm_legend_hide(), 12 | col = "upside_down", 13 | col.scale = tm_scale_categorical(values = c("#9900BB", "#228822")), 14 | col.legend = tm_legend_hide()) + 15 | tm_title_out("Which Hemisphere?", position = tm_pos_out("center", "top", pos.v = "bottom")) 16 | 17 | -------------------------------------------------------------------------------- /examples/tmapOutput.R: -------------------------------------------------------------------------------- 1 | if (interactive() && require("shiny")) { 2 | 3 | data(World) 4 | world_vars <- setdiff(names(World), c("iso_a3", "name", "sovereignt", "geometry")) 5 | 6 | current.mode <- tmap_mode("plot") 7 | 8 | shinyApp( 9 | ui = fluidPage( 10 | tmapOutput("map", height = "600px"), 11 | selectInput("var", "Variable", world_vars) 12 | ), 13 | server <- function(input, output, session) { 14 | output$map <- renderTmap({ 15 | tm_shape(World) + 16 | tm_polygons(input$var, zindex = 401) 17 | }) 18 | } 19 | ) 20 | 21 | tmap_mode("view") 22 | 23 | shinyApp( 24 | ui = fluidPage( 25 | tmapOutput("map", height = "600px"), 26 | selectInput("var", "Variable", world_vars) 27 | ), 28 | server <- function(input, output, session) { 29 | output$map <- renderTmap({ 30 | tm_shape(World, id = "iso_a3") + 31 | tm_polygons(fill = world_vars[1], zindex = 401) 32 | }) 33 | observe({ 34 | var <- input$var 35 | tmapProxy("map", session, { 36 | tm_remove_layer(401) + 37 | tm_shape(World, id = "iso_a3") + 38 | tm_polygons(fill = var, zindex = 401) 39 | }) 40 | }) 41 | },options = list(launch.browser=TRUE) 42 | ) 43 | 44 | tmap_mode(current.mode) 45 | } 46 | -------------------------------------------------------------------------------- /examples/tmap_animation.R: -------------------------------------------------------------------------------- 1 | \dontrun{ 2 | data(NLD_prov) 3 | 4 | m1 <- tm_shape(NLD_prov) + 5 | tm_polygons("yellow") + 6 | tm_facets(along = "name") 7 | 8 | tmap_animation(m1, delay=40) 9 | 10 | data(World, metro) 11 | 12 | m2 <- tm_shape(World, projection = "+proj=eck4", simplify = 0.5) + 13 | tm_fill() + 14 | tm_shape(metro) + 15 | tm_bubbles(size = paste0("pop", seq(1970, 2030, by=10)), 16 | col = "purple", 17 | border.col = "black", border.alpha = .5, 18 | scale = 2) + 19 | tm_facets(free.scales.symbol.size = FALSE, nrow=1,ncol=1) + 20 | tm_format("World") 21 | 22 | tmap_animation(m2, delay=100, outer.margins = 0) 23 | 24 | m3 <- lapply(seq(50, 85, by = 5), function(age) { 25 | World$at_most <- World$life_exp <= age 26 | World_sel <- World[which((World$life_exp <= age) & (World$life_exp > (age - 5))), ] 27 | tm_shape(World) + 28 | tm_polygons("at_most", palette = c("gray95", "gold"), legend.show = FALSE) + 29 | tm_shape(World_sel) + 30 | tm_text("name", size = "AREA", root = 5, remove_overlap = TRUE) + 31 | tm_layout(main.title = paste0("Life expectency at most ", age), frame = FALSE) 32 | }) 33 | 34 | tmap_animation(m3, width = 1200, height = 600, delay = 100) 35 | 36 | m4 <- tm_shape(World) + 37 | tm_polygons() + 38 | tm_shape(metro) + 39 | tm_bubbles(col = "red") + 40 | tm_text("name", ymod = -1) + 41 | tm_facets(by = "name", free.coords = FALSE, nrow = 1, ncol = 1) + 42 | tm_layout(panel.show = FALSE, frame = FALSE) 43 | 44 | tmap_animation(m4, filename = "World_cities.mp4", 45 | width=1200, height = 600, fps = 2, outer.margins = 0) 46 | } 47 | -------------------------------------------------------------------------------- /examples/tmap_arrange.R: -------------------------------------------------------------------------------- 1 | tm1 = tm_shape(World) + tm_polygons("HPI") 2 | tm2 = tm_shape(metro) + tm_bubbles(size = "pop2020") 3 | 4 | tmap_arrange(tm1, tm2) 5 | -------------------------------------------------------------------------------- /examples/tmap_mode.R: -------------------------------------------------------------------------------- 1 | current.mode = tmap_mode() 2 | 3 | tmap_mode("plot") 4 | 5 | tm_shape(World) + tm_polygons("HPI") 6 | 7 | tmap_mode("view") 8 | 9 | tm_shape(World) + tm_polygons("HPI") 10 | 11 | ttm() 12 | 13 | tm_shape(World) + tm_polygons("HPI") 14 | 15 | tmap_mode(current.mode) 16 | -------------------------------------------------------------------------------- /examples/tmap_options.R: -------------------------------------------------------------------------------- 1 | # get all options 2 | opt = tmap_options() 3 | 4 | # print as a tree 5 | if (requireNamespace("lobstr")) { 6 | lobstr::tree(opt) 7 | } 8 | 9 | # a fancy set of options: 10 | tmap_options( 11 | bg.color = "steelblue", 12 | outer.bg.color = "salmon", 13 | frame.color = "purple3", 14 | frame.lwd = 5, 15 | compass.type = "8star", 16 | legend.bg.color = "gold", 17 | legend.position = tm_pos_in(pos.h = "left", pos.v = "top") 18 | ) 19 | 20 | if (requireNamespace("lobstr")) { 21 | lobstr::tree( 22 | tmap_options_diff() 23 | ) 24 | } 25 | 26 | tm_shape(World) + 27 | tm_polygons("footprint") 28 | 29 | tmap_options_save("fancy") 30 | 31 | # the default style: 32 | tmap_style("white") 33 | 34 | tm_shape(World) + 35 | tm_polygons("footprint") 36 | 37 | tmap_style("fancy") 38 | 39 | tm_shape(World) + 40 | tm_polygons("footprint") 41 | 42 | # reset all options 43 | tmap_options_reset() 44 | -------------------------------------------------------------------------------- /examples/tmap_save.R: -------------------------------------------------------------------------------- 1 | \dontrun{ 2 | data(NLD_muni, NLD_prov) 3 | m <- tm_shape(NLD_muni) + 4 | tm_fill(col="population", convert2density=TRUE, 5 | style="kmeans", 6 | title=expression("Population (per " * km^2 * ")")) + 7 | tm_borders("black", alpha=.5) + 8 | tm_shape(NLD_prov) + 9 | tm_borders("grey25", lwd=2) + 10 | tm_style("classic") + 11 | tm_format("NLD", inner.margins = c(.02, .15, .06, .15)) + 12 | tm_scale_bar(position = c("left", "bottom")) + 13 | tm_compass(position=c("right", "bottom")) 14 | 15 | tmap_save(m, "choropleth.png", height = 7) # height interpreted in inches 16 | tmap_save(m, "choropleth_icon.png", height = 100, scale = .1) # height interpreted in pixels 17 | 18 | data(World) 19 | m2 <- tm_shape(World) + 20 | tm_fill("well_being", id="name", title="Well-being") + 21 | tm_format("World") 22 | 23 | # save image 24 | tmap_save(m2, "World_map.png", width=1920, height=1080, asp=0) 25 | 26 | # cut left inner margin to make sure Antarctica is snapped to frame 27 | tmap_save(m2 + tm_layout(inner.margins = c(0, -.1, 0.05, 0.01)), 28 | "World_map2.png", width=1920, height=1080, asp=0) 29 | 30 | # save interactive plot 31 | tmap_save(m2, "World_map.html") 32 | } 33 | -------------------------------------------------------------------------------- /examples/tmap_style.R: -------------------------------------------------------------------------------- 1 | tmap_style() 2 | 3 | tm_shape(World) + tm_polygons("HPI") 4 | 5 | tmap_style("cobalt") 6 | 7 | tm_shape(World) + tm_polygons("HPI") 8 | 9 | # for backwards compatibility, the styles of tmap versions 1-3 are also included: 10 | 11 | tmap_style("v3") 12 | 13 | tm_shape(World) + tm_polygons("HPI") 14 | 15 | tmap_style("cobalt_v3") 16 | 17 | tm_shape(World) + tm_polygons("HPI") 18 | -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | bibentry(bibtype = "Article", 2 | title = "{tmap}: Thematic Maps in {R}", 3 | author = person(given = "Martijn", 4 | family = "Tennekes", 5 | email = "mtennekes@gmail.com"), 6 | journal = "Journal of Statistical Software", 7 | year = "2018", 8 | volume = "84", 9 | number = "6", 10 | pages = "1--39", 11 | doi = "10.18637/jss.v084.i06", 12 | 13 | header = "To cite tmap/tmaptools in publications use:" 14 | ) 15 | 16 | -------------------------------------------------------------------------------- /inst/img/airplane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/inst/img/airplane.png -------------------------------------------------------------------------------- /inst/img/city.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/inst/img/city.png -------------------------------------------------------------------------------- /inst/img/compass_4star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/inst/img/compass_4star.png -------------------------------------------------------------------------------- /inst/img/compass_8star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/inst/img/compass_8star.png -------------------------------------------------------------------------------- /inst/img/compass_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/inst/img/compass_arrow.png -------------------------------------------------------------------------------- /inst/img/compass_radar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/inst/img/compass_radar.png -------------------------------------------------------------------------------- /inst/img/compass_rose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/inst/img/compass_rose.png -------------------------------------------------------------------------------- /inst/tmap.bib: -------------------------------------------------------------------------------- 1 | @Manual{c4a, 2 | title = {cols4all: Colors for all}, 3 | author = {Martijn Tennekes}, 4 | year = {2024}, 5 | note = {R package version 0.8}, 6 | url = {https://CRAN.R-project.org/package=cols4all}, 7 | } 8 | 9 | 10 | @Manual{r, 11 | title = {R: A Language and Environment for Statistical Computing}, 12 | author = {{R Core Team}}, 13 | organization = {R Foundation for Statistical Computing}, 14 | address = {Vienna, Austria}, 15 | year = {2022}, 16 | url = {https://www.R-project.org/}, 17 | } 18 | 19 | 20 | @Book{ggplot2, 21 | author = {Hadley Wickham}, 22 | title = {ggplot2: Elegant Graphics for Data Analysis}, 23 | publisher = {Springer-Verlag New York}, 24 | year = {2016}, 25 | isbn = {978-3-319-24277-4}, 26 | url = {https://ggplot2.tidyverse.org}, 27 | } 28 | 29 | @book{ware2021, 30 | title={Information Visualization: Perception for Design}, 31 | author={Ware, Colin}, 32 | year={2021}, 33 | edition={4}, 34 | publisher={Morgan Kaufmann} 35 | } 36 | 37 | @book{wilkinson2005, 38 | address = {New York}, 39 | author = {Wilkinson, Leland. and Wills, Graham}, 40 | booktitle = {The grammar of graphics}, 41 | edition = {2nd ed.}, 42 | isbn = {0387245448}, 43 | publisher = {Springer}, 44 | series = {Statistics and computing}, 45 | title = {The grammar of graphics}, 46 | year = {2005} 47 | } 48 | -------------------------------------------------------------------------------- /man/World_rivers.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{World_rivers} 5 | \alias{World_rivers} 6 | \title{Spatial data of rivers} 7 | \format{ 8 | An object of class \code{sf} (inherits from \code{data.frame}) with 1632 rows and 5 columns. 9 | } 10 | \source{ 11 | \url{https://www.naturalearthdata.com} 12 | } 13 | \usage{ 14 | World_rivers 15 | } 16 | \description{ 17 | Spatial data of rivers 18 | } 19 | \note{ 20 | In tmap <= 3, this dataset was called \code{rivers}. 21 | } 22 | \keyword{datasets} 23 | -------------------------------------------------------------------------------- /man/figures/README-unnamed-chunk-3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/man/figures/README-unnamed-chunk-3-1.png -------------------------------------------------------------------------------- /man/figures/README-unnamed-chunk-4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/man/figures/README-unnamed-chunk-4-1.png -------------------------------------------------------------------------------- /man/figures/README-unnamed-chunk-5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/man/figures/README-unnamed-chunk-5-1.png -------------------------------------------------------------------------------- /man/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/man/figures/logo.png -------------------------------------------------------------------------------- /man/figures/shiny_plot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/man/figures/shiny_plot.jpg -------------------------------------------------------------------------------- /man/figures/shiny_view.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/man/figures/shiny_view.jpg -------------------------------------------------------------------------------- /man/get_fact_levels_na.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tmapShape_misc.R 3 | \name{get_fact_levels_na} 4 | \alias{get_fact_levels_na} 5 | \title{Internal tmap function that gets factor levels with NA's} 6 | \usage{ 7 | get_fact_levels_na(x, o) 8 | } 9 | \arguments{ 10 | \item{x}{vector} 11 | 12 | \item{o}{options} 13 | } 14 | \description{ 15 | Internal tmap function that gets factor levels with NA's 16 | } 17 | \keyword{internal} 18 | -------------------------------------------------------------------------------- /man/get_scale_defaults.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tmapScale_misc.R 3 | \name{get_scale_defaults} 4 | \alias{get_scale_defaults} 5 | \title{Internal tmap function get scale values} 6 | \usage{ 7 | get_scale_defaults(scale, o, aes, layer, cls, ct = NULL) 8 | } 9 | \arguments{ 10 | \item{scale}{scale} 11 | 12 | \item{o}{o} 13 | 14 | \item{aes}{aes} 15 | 16 | \item{layer}{layer} 17 | 18 | \item{cls}{cls} 19 | 20 | \item{ct}{ct} 21 | } 22 | \description{ 23 | Internal tmap function get scale values 24 | } 25 | \keyword{internal} 26 | -------------------------------------------------------------------------------- /man/land.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{land} 5 | \alias{land} 6 | \title{Spatial data of global land cover} 7 | \format{ 8 | An object of class \code{stars} with 1080 rows and 540 columns. 9 | } 10 | \usage{ 11 | land 12 | } 13 | \description{ 14 | Spatial data of global land cover, percent tree cover, and elevation of class \code{\link[stars:st_as_stars]{stars}}. 15 | Two attributes in this object relates to global land cover. 16 | The cover layer classifies the status of land cover of the whole globe into 20 categories, while 17 | the cover_cls layer uses 8 simplified categories. 18 | Percent Tree Cover (trees) represents the density of trees on the ground, and the last attribute represents elevation. 19 | } 20 | \details{ 21 | \strong{Important:} publication of these maps is only allowed when cited to Tateishi et al. (2014), and when "Geospatial Information Authority of Japan, Chiba University and collaborating organizations." is shown. 22 | } 23 | \references{ 24 | Production of Global Land Cover Data - GLCNMO2008, Tateishi, R., Thanh Hoan, N., Kobayashi, T., Alsaaideh, B., Tana, G., Xuan Phong, D. (2014), Journal of Geography and Geology, 6 (3). 25 | } 26 | \keyword{datasets} 27 | -------------------------------------------------------------------------------- /man/make_by_vars.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tmapShape_misc.R 3 | \name{make_by_vars} 4 | \alias{make_by_vars} 5 | \title{Internal tmap function to create by variables (used for faceting)} 6 | \usage{ 7 | make_by_vars(dt, tmf, smeta) 8 | } 9 | \arguments{ 10 | \item{dt}{data.table} 11 | 12 | \item{tmf}{tmf object} 13 | 14 | \item{smeta}{smeta object} 15 | } 16 | \description{ 17 | Internal tmap function to create by variables (used for faceting) 18 | } 19 | \keyword{internal} 20 | -------------------------------------------------------------------------------- /man/metro.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{metro} 5 | \alias{metro} 6 | \title{Spatial data of metropolitan areas} 7 | \format{ 8 | An object of class \code{sf} (inherits from \code{data.frame}) with 436 rows and 13 columns. 9 | } 10 | \source{ 11 | \url{https://population.un.org/wup/} 12 | } 13 | \usage{ 14 | metro 15 | } 16 | \description{ 17 | \code{metro} includes a population time series from 1950 to (forecasted) 2030. All metro areas with over 1 million inhabitants in 2010 are included. 18 | } 19 | \references{ 20 | United Nations, Department of Economic and Social Affairs, Population Division (2014). World Urbanization Prospects: The 2014 Revision, CD-ROM Edition. 21 | } 22 | \keyword{datasets} 23 | -------------------------------------------------------------------------------- /man/print.tm_element.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_element.R 3 | \name{print.tm_element} 4 | \alias{print.tm_element} 5 | \alias{print.tm_shape} 6 | \title{Print tm_element} 7 | \usage{ 8 | \method{print}{tm_element}(x, ...) 9 | 10 | \method{print}{tm_shape}(x, ...) 11 | } 12 | \arguments{ 13 | \item{x}{x} 14 | 15 | \item{...}{passed on} 16 | } 17 | \description{ 18 | Print tm_element 19 | } 20 | \keyword{internal} 21 | -------------------------------------------------------------------------------- /man/print.tmap.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/print.R 3 | \name{print.tmap} 4 | \alias{print.tmap} 5 | \alias{knit_print.tmap} 6 | \title{Draw thematic map} 7 | \usage{ 8 | \method{print}{tmap}( 9 | x, 10 | return.asp = FALSE, 11 | show = TRUE, 12 | vp = NULL, 13 | knit = FALSE, 14 | options = NULL, 15 | in.shiny = FALSE, 16 | proxy = FALSE, 17 | ... 18 | ) 19 | 20 | \method{knit_print}{tmap}(x, ..., options = NULL) 21 | } 22 | \arguments{ 23 | \item{x}{tmap object.} 24 | 25 | \item{return.asp}{should the aspect ratio be returned?} 26 | 27 | \item{show}{show the map} 28 | 29 | \item{vp}{viewport (for \code{"plot"} mode)} 30 | 31 | \item{knit}{A logical, should knit?} 32 | 33 | \item{options}{A vector of options} 34 | 35 | \item{in.shiny}{A logical, is the map drawn in \strong{shiny}?} 36 | 37 | \item{proxy}{A logical, if \code{in.shiny}, is \code{\link[=tmapProxy]{tmapProxy()}} used?} 38 | 39 | \item{...}{passed on internally (for developers: in \code{"view"} mode, the proxy leaflet object is passed to \code{tmapLeafletInit}).} 40 | } 41 | \description{ 42 | Draw thematic map 43 | } 44 | -------------------------------------------------------------------------------- /man/reexports.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_layers_aux.R 3 | \docType{import} 4 | \name{reexports} 5 | \alias{reexports} 6 | \alias{providers} 7 | \title{Objects exported from other packages} 8 | \keyword{internal} 9 | \description{ 10 | These objects are imported from other packages. Follow the links 11 | below to see their documentation. 12 | 13 | \describe{ 14 | \item{leaflet}{\code{\link[leaflet]{providers}}} 15 | }} 16 | 17 | -------------------------------------------------------------------------------- /man/shapeTM.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/shapeTM.R 3 | \name{shapeTM} 4 | \alias{shapeTM} 5 | \title{Internal tmap function to create a tmap shape} 6 | \usage{ 7 | shapeTM(shp, tmapID = NULL, bbox = NULL, ...) 8 | } 9 | \arguments{ 10 | \item{shp}{Shape file} 11 | 12 | \item{tmapID}{tmap Identifier} 13 | 14 | \item{bbox}{bounding box} 15 | } 16 | \description{ 17 | Internal tmap function to create a tmap shape 18 | } 19 | \keyword{internal} 20 | -------------------------------------------------------------------------------- /man/theme_ps.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/theme_ps.R 3 | \name{theme_ps} 4 | \alias{theme_ps} 5 | \title{ggplot2 theme for proportional symbols} 6 | \usage{ 7 | theme_ps( 8 | base_size = 12, 9 | base_family = "", 10 | plot.axes = FALSE, 11 | plot.legend = FALSE 12 | ) 13 | } 14 | \arguments{ 15 | \item{base_size}{base size} 16 | 17 | \item{base_family}{base family} 18 | 19 | \item{plot.axes}{should the axes be shown?} 20 | 21 | \item{plot.legend}{should the legend(s) be shown?} 22 | } 23 | \description{ 24 | ggplot2 theme for proportional symbols. By default, this theme only shows the 25 | plotting area, so without titles, axes, and legend. 26 | } 27 | -------------------------------------------------------------------------------- /man/tm_add_legend.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_add_legend.R 3 | \name{tm_add_legend} 4 | \alias{tm_add_legend} 5 | \title{Map component: manual legend} 6 | \usage{ 7 | tm_add_legend( 8 | ..., 9 | labels = "", 10 | type = "symbols", 11 | title = "", 12 | design = NULL, 13 | orientation = NULL, 14 | position = NULL, 15 | group_id = NA_character_, 16 | group = NA, 17 | group.control = "check", 18 | z = NA_integer_ 19 | ) 20 | } 21 | \arguments{ 22 | \item{...}{visual variables and arguments passed on to \code{tm_legend()}. 23 | By default, the argument \code{type} is set to \code{"symbols"}, which means that the 24 | supported visual variables are: \code{"fill"}, \code{"col"}, \code{"shape"}, \code{"size"}, 25 | \code{"fill_alpha"}, \code{"col_alpha"}, \code{"lty"}, \code{"lwd"}, \code{"linejoin"}, and \code{"lineend"}. 26 | The number of legend items will be equal to the maximum number of specific values (and specified labels.)} 27 | 28 | \item{labels}{labels by default \code{""} (so omitted)} 29 | 30 | \item{type}{the layer type from which the visual variables (see \code{...}) are taken. 31 | Options: \code{"symbols"} (default), \code{"lines"}, \code{"polygons"}, and \code{"text"}.} 32 | 33 | \item{title}{The title of the legend.} 34 | 35 | \item{design}{The design of the legend.} 36 | 37 | \item{orientation}{The orientation of the legend.} 38 | 39 | \item{position}{The position of the legend. A tm_pos object, or a shortcut of two values: horizontal (left, center, right) and vertical (top, center, bottom). See tm_pos for details} 40 | 41 | \item{group_id}{Component group id name. All components (e.g. legends, titles, etc) with the same \code{group_id} will be grouped. The specifications of how they are placed (e.g. stacking, margins etc.) are determined in \code{\link[=tm_comp_group]{tm_comp_group()}} where its argument \code{id} should correspond to \code{group_id}.} 42 | 43 | \item{group}{Name of the group to which this layer belongs. This is only 44 | relevant in view mode, where layer groups can be switched (see \code{group.control})} 45 | 46 | \item{group.control}{In view mode, the group control determines how 47 | layer groups can be switched on and off. Options: \code{"radio"} for radio 48 | buttons (meaning only one group can be shown), \code{"check"} for check boxes 49 | (so multiple groups can be shown), and \code{"none"} for no control 50 | (the group cannot be (de)selected).} 51 | 52 | \item{z}{z index, e.g. the place of the component relative to the other componets} 53 | } 54 | \description{ 55 | Map component that adds a manual legend. 56 | } 57 | \examples{ 58 | \dontrun{ 59 | tm_shape(NLD_muni) + 60 | tm_borders() + 61 | tm_basemap("OpenStreetMap") + 62 | tm_add_legend(labels = c("Motorway", "Primary road", "Secondary road", "Railway"), 63 | col = c("#E892A1", "#FCD6A4", "#F8FABF", "#707070"), 64 | lty = c("solid", "solid", "solid", "dotted"), 65 | lwd = 3, 66 | type = "lines", 67 | bg.color = "grey92", 68 | bg.alpha = 1) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /man/tm_animate.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_animate.R 3 | \name{tm_animate} 4 | \alias{tm_animate} 5 | \alias{tm_animate_slow} 6 | \title{Specify an animation (experimental)} 7 | \usage{ 8 | tm_animate( 9 | by = "VARS__", 10 | nframes = 60L, 11 | fps = 20L, 12 | play = c("loop", "pingpong", "once"), 13 | dpr = 2, 14 | ... 15 | ) 16 | 17 | tm_animate_slow( 18 | by = "VARS__", 19 | nframes = 60L, 20 | fps = 2L, 21 | play = c("loop", "pingpong", "once"), 22 | dpr = 2, 23 | ... 24 | ) 25 | } 26 | \arguments{ 27 | \item{by}{group by variable used to create the animation frames. Note: it is called \code{pages} in the core function \code{\link[=tm_facets]{tm_facets()}}.} 28 | 29 | \item{nframes}{number of animation frames. This only app} 30 | 31 | \item{fps}{frames per second. Default: 30 for \code{tm_facets_animate} and 2 for \code{tm_facets_animate_slow}.} 32 | 33 | \item{play}{how should the animation be played? One of \code{"loop"}, \code{"pingpong"}, and \code{"once"}} 34 | 35 | \item{dpr}{device pixel ratio. The ratio between the physical pixel density of a device and its logical pixel density.} 36 | 37 | \item{...}{passed on to \code{\link[=tm_facets]{tm_facets()}}} 38 | } 39 | \description{ 40 | \code{tm_animate} 41 | } 42 | \seealso{ 43 | \code{\link[=tm_facets]{tm_facets()}} which is the core function, and \code{\link[=tmap_animation]{tmap_animation()}} used to save the animation 44 | } 45 | -------------------------------------------------------------------------------- /man/tm_comp_group.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_comp_group.R 3 | \name{tm_comp_group} 4 | \alias{tm_comp_group} 5 | \title{Group components} 6 | \usage{ 7 | tm_comp_group( 8 | group_id, 9 | position, 10 | stack, 11 | frame_combine, 12 | equalize, 13 | resize_as_group, 14 | stack_margin, 15 | offset, 16 | frame, 17 | frame.color, 18 | frame.alpha, 19 | frame.lwd, 20 | frame.r, 21 | bg, 22 | bg.color, 23 | bg.alpha 24 | ) 25 | } 26 | \arguments{ 27 | \item{group_id}{id of the component group. Refers to the \code{group_id} argument of each component function, such as \code{\link[=tm_legend]{tm_legend()}} and \code{\link[=tm_title]{tm_title()}}.} 28 | 29 | \item{position}{The position specification of the components in this group: an object created with \code{tm_pos_in()} or \code{tm_pos_out()}. Or, as a shortcut, a vector of two values, specifying the x and y coordinates. The first is \code{"left"}, \code{"center"} or \code{"right"} (or upper case, meaning tighter to the map frame), the second \code{"top"}, \code{"center"} or \code{"bottom"}. Numeric values are also supported, where 0, 0 means left bottom and 1, 1 right top. See also \href{https://r-tmap.github.io/tmap/articles/adv_positions}{vignette about positioning}.} 30 | 31 | \item{stack}{stacking \code{"horizontal"} or \code{"vertical"}} 32 | 33 | \item{frame_combine}{put frame around all components that are drawn on the same location. Whether a frame is drawn is still decided by the \code{frame} argument of the 'main' (first) component.} 34 | 35 | \item{equalize}{in case \code{frame_combine} is \code{FALSE}, should the separate frames be equalized, i.e. have the same width (when stacked vertically) or height (when stacked horizontally)?} 36 | 37 | \item{resize_as_group}{in case a component if rescaled because of the limited space, rescale the other components proportionally?} 38 | 39 | \item{stack_margin}{Margin between components} 40 | 41 | \item{offset}{Offset margin between frame and the components block} 42 | 43 | \item{frame}{Should a frame be drawn? By default \code{TRUE} for legends, charts and insets, and \code{FALSE} otherwise.} 44 | 45 | \item{frame.color}{frame color} 46 | 47 | \item{frame.alpha}{frame alpha transparancy} 48 | 49 | \item{frame.lwd}{frame line width} 50 | 51 | \item{frame.r}{Radius of the rounded frame corners. 0 means no rounding.} 52 | 53 | \item{bg}{Background color the components block. Is usually set in each component function, but if specified here, it will overwrite them.} 54 | 55 | \item{bg.color}{Background color the components block. Is usually set in each component function, but if specified here, it will overwrite them.} 56 | 57 | \item{bg.alpha}{Background alpha transparency of the components block. Is usually set in each component function, but if specified here, it will overwrite them.} 58 | } 59 | \value{ 60 | A \code{\link{tmap-element}} 61 | } 62 | \description{ 63 | Group components 64 | } 65 | -------------------------------------------------------------------------------- /man/tm_const.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_scale_.R 3 | \name{tm_const} 4 | \alias{tm_const} 5 | \title{tmap function to define a constant visual value} 6 | \usage{ 7 | tm_const() 8 | } 9 | \description{ 10 | tmap function to define a constant visual value 11 | } 12 | -------------------------------------------------------------------------------- /man/tm_credits.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_components.R 3 | \name{tm_credits} 4 | \alias{tm_credits} 5 | \title{Map component: (credits) text} 6 | \usage{ 7 | tm_credits( 8 | text, 9 | size, 10 | color, 11 | padding, 12 | fontface, 13 | fontfamily, 14 | alpha, 15 | stack, 16 | just, 17 | frame, 18 | frame.lwd, 19 | frame.r, 20 | bg, 21 | bg.color, 22 | bg.alpha, 23 | position, 24 | group_id, 25 | width, 26 | height, 27 | z, 28 | ... 29 | ) 30 | } 31 | \arguments{ 32 | \item{text}{text} 33 | 34 | \item{size}{font size} 35 | 36 | \item{color}{font color} 37 | 38 | \item{padding}{padding} 39 | 40 | \item{fontface}{font face, bold, italic} 41 | 42 | \item{fontfamily}{font family} 43 | 44 | \item{alpha}{alpha transparency of the text} 45 | 46 | \item{stack}{stack with other map components, either \code{"vertical"} or \code{"horizontal"}.} 47 | 48 | \item{just}{just} 49 | 50 | \item{frame}{frame should a frame be drawn?} 51 | 52 | \item{frame.lwd}{frame line width} 53 | 54 | \item{frame.r}{Radius of the rounded frame corners. 0 means no rounding.} 55 | 56 | \item{bg}{Show background?} 57 | 58 | \item{bg.color}{Background color} 59 | 60 | \item{bg.alpha}{Background transparency} 61 | 62 | \item{position}{The position specification of the component: an object created with \code{tm_pos_in()} or \code{tm_pos_out()}. Or, as a shortcut, a vector of two values, specifying the x and y coordinates. The first is \code{"left"}, \code{"center"} or \code{"right"} (or upper case, meaning tighter to the map frame), the second \code{"top"}, \code{"center"} or \code{"bottom"}. Numeric values are also supported, where 0, 0 means left bottom and 1, 1 right top. See also \href{https://r-tmap.github.io/tmap/articles/adv_positions}{vignette about positioning}. In case multiple components should be combined (stacked), use \code{group_id} and specify \code{component} in \code{\link[=tm_comp_group]{tm_comp_group()}}.} 63 | 64 | \item{group_id}{Component group id name. All components (e.g. legends, titles, etc) with the same \code{group_id} will be grouped. The specifications of how they are placed (e.g. stacking, margins etc.) are determined in \code{\link[=tm_comp_group]{tm_comp_group()}} where its argument \code{id} should correspond to \code{group_id}.} 65 | 66 | \item{width, height}{width and height of the component.} 67 | 68 | \item{z}{z index, e.g. the place of the component relative to the other componets} 69 | 70 | \item{...}{to catch deprecated arguments} 71 | } 72 | \description{ 73 | Map component that adds a text, typically used as credits. This function is the same as \code{\link[=tm_title]{tm_title()}} but with different default values. 74 | } 75 | \seealso{ 76 | \href{https://r-tmap.github.io/tmap/articles/basics_components}{Vignette about components} 77 | } 78 | -------------------------------------------------------------------------------- /man/tm_extra_innner_margin.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_layout.R 3 | \name{tm_place_legends_right} 4 | \alias{tm_place_legends_right} 5 | \alias{tm_place_legends_left} 6 | \alias{tm_place_legends_bottom} 7 | \alias{tm_place_legends_top} 8 | \alias{tm_place_legends_inside} 9 | \alias{tm_extra_innner_margin} 10 | \alias{tm_extra_inner_margin} 11 | \title{tmap layout: helper functions} 12 | \usage{ 13 | tm_place_legends_right(width = NA) 14 | 15 | tm_place_legends_left(width = NA) 16 | 17 | tm_place_legends_bottom(height = NA) 18 | 19 | tm_place_legends_top(height = NA) 20 | 21 | tm_place_legends_inside(pos.h = NULL, pos.v = NULL) 22 | 23 | tm_extra_inner_margin(left = 0, right = 0, top = 0, bottom = 0) 24 | } 25 | \arguments{ 26 | \item{width}{width} 27 | 28 | \item{height}{height} 29 | 30 | \item{pos.h, pos.v}{position (horizontal and vertical)} 31 | 32 | \item{left, right, top, bottom}{extra margins} 33 | } 34 | \description{ 35 | tmap layout: helper functions 36 | } 37 | -------------------------------------------------------------------------------- /man/tm_group.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_group.R 3 | \name{tm_group} 4 | \alias{tm_group} 5 | \title{Layer group control} 6 | \usage{ 7 | tm_group(name, control = NA, zoom_levels = NA) 8 | } 9 | \arguments{ 10 | \item{name}{group name that corresponds with the group name specified in the layer functions (e.g. \code{\link[=tm_polygons]{tm_polygons()}})} 11 | 12 | \item{control}{The group control determines how 13 | layer groups can be switched on and off. Options: \code{"radio"} for radio 14 | buttons (meaning only one group can be shown), \code{"check"} for check boxes 15 | (so multiple groups can be shown), and \code{"none"} for no control 16 | (the group cannot be (de)selected).} 17 | 18 | \item{zoom_levels}{The zoom levels at which the group is displays at. When specified \code{control} will be set to \code{"none"}.} 19 | } 20 | \description{ 21 | Controls the layer groups in interactive maps (view mode): the layer control box (radio buttons or check boxes) and at which zoom levels the layers are displayed at. 22 | } 23 | \seealso{ 24 | \href{https://r-tmap.github.io/tmap/articles/adv_groups}{vignette about layer groups} 25 | } 26 | -------------------------------------------------------------------------------- /man/tm_iso.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_layers_iso.R 3 | \name{tm_iso} 4 | \alias{tm_iso} 5 | \title{Map layer: iso (contour)} 6 | \usage{ 7 | tm_iso( 8 | col = tm_const(), 9 | text = tm_vars(x = 1), 10 | ..., 11 | options_lines = opt_tm_lines(), 12 | options_labels = opt_tm_labels() 13 | ) 14 | } 15 | \arguments{ 16 | \item{col}{Visual variable that determines the color. See details.} 17 | 18 | \item{text}{Visual variable that determines the text. See details.} 19 | 20 | \item{...}{passed on to \code{\link[=tm_lines]{tm_lines()}} and \code{\link[=tm_labels_highlighted]{tm_labels_highlighted()}}. For the text color and alpha transparency of the text labels, please use \code{text_col} and \code{text_alpha} instead of \code{col} and \code{col_alpha}.} 21 | 22 | \item{options_lines}{The options for \code{\link[=tm_lines]{tm_lines()}}} 23 | 24 | \item{options_labels}{The options for \code{\link[=tm_labels_highlighted]{tm_labels_highlighted()}}} 25 | } 26 | \description{ 27 | Map layer that draws iso (contour) lines. Stack of \code{\link[=tm_lines]{tm_lines()}} and \link{tm_labels_highlighted}. 28 | } 29 | -------------------------------------------------------------------------------- /man/tm_mouse_coordinates.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_components.R 3 | \name{tm_mouse_coordinates} 4 | \alias{tm_mouse_coordinates} 5 | \title{Map component: mouse coordinates} 6 | \usage{ 7 | tm_mouse_coordinates(stack, position, group_id, z) 8 | } 9 | \arguments{ 10 | \item{stack}{stack with other map components, either \code{"vertical"} or \code{"horizontal"}.} 11 | 12 | \item{position}{The position specification of the component: an object created with \code{tm_pos_in()} or \code{tm_pos_out()}. Or, as a shortcut, a vector of two values, specifying the x and y coordinates. The first is \code{"left"}, \code{"center"} or \code{"right"} (or upper case, meaning tighter to the map frame), the second \code{"top"}, \code{"center"} or \code{"bottom"}. Numeric values are also supported, where 0, 0 means left bottom and 1, 1 right top. See also \href{https://r-tmap.github.io/tmap/articles/adv_positions}{vignette about positioning}. In case multiple components should be combined (stacked), use \code{group_id} and specify \code{component} in \code{\link[=tm_comp_group]{tm_comp_group()}}.} 13 | 14 | \item{group_id}{Component group id name. All components (e.g. legends, titles, etc) with the same \code{group_id} will be grouped. The specifications of how they are placed (e.g. stacking, margins etc.) are determined in \code{\link[=tm_comp_group]{tm_comp_group()}} where its argument \code{id} should correspond to \code{group_id}.} 15 | 16 | \item{z}{z index, e.g. the place of the component relative to the other componets} 17 | } 18 | \description{ 19 | Map component that adds mouse coordinates 20 | } 21 | \seealso{ 22 | \href{https://r-tmap.github.io/tmap/articles/basics_components}{Vignette about components} 23 | } 24 | -------------------------------------------------------------------------------- /man/tm_plot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_layout.R 3 | \name{tm_plot} 4 | \alias{tm_plot} 5 | \title{Plot mode options} 6 | \usage{ 7 | tm_plot(use_gradient, limit_latitude_3857) 8 | } 9 | \arguments{ 10 | \item{use_gradient}{Use gradient fill using \link[grid:patterns]{linearGradient()}} 11 | 12 | \item{limit_latitude_3857}{Vector of two limit latitude values for maps printed in Web Mercator projection (EPSG 3857). If \code{c(-90, 90)} the poles will be inflated too much. The Web Mercator is defines as \code{c(-85.06, 85.06)}, but the default setting in tmap is \code{c(-84, 84)}.} 13 | } 14 | \description{ 15 | Plot mode options. This option is specific to the plot mode. 16 | } 17 | -------------------------------------------------------------------------------- /man/tm_plot_order.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_plot_order.R 3 | \name{tm_plot_order} 4 | \alias{tm_plot_order} 5 | \title{Determine plotting order of features} 6 | \usage{ 7 | tm_plot_order( 8 | aes, 9 | reverse = TRUE, 10 | na.order = c("mix", "bottom", "top"), 11 | null.order = c("bottom", "mix", "top"), 12 | null.below.na = TRUE 13 | ) 14 | } 15 | \arguments{ 16 | \item{aes}{Visual variable for which the values determine the plotting order. 17 | Example: bubble map where the \code{"size"} aesthetic is used. 18 | A data variable (say population) is mapped via a continuous scale (\code{\link[=tm_scale_continuous]{tm_scale_continuous()}}) 19 | to bubble sizes. The bubbles are plotted in order of size. 20 | How is determined by the other arguments. Use \code{"DATA"} to keep the same 21 | order as in the data. Another special value are \code{"AREA"} and \code{"LENGTH"} 22 | which are preserved for polygons and lines respectively: rather than a data 23 | variable the polygon area / line lengths determines the plotting order.} 24 | 25 | \item{reverse}{Logical that determines whether the visual values are plotted 26 | in reversed order. The visual values (specified with tmap option \code{"values.var"}) 27 | are by default reversed, so plotted starting from the last value. 28 | In the bubble map example, this means that large bubbles are plotted first, 29 | hence at the bottom.} 30 | 31 | \item{na.order}{Where should features be plotted that have an \code{NA} value for 32 | (at least) one other aesthetic variable? In the (order) \code{"mix"}, at the \code{"bottom"}, 33 | or on \code{"top"}? In the bubble map example: if fill color is missing for some bubble, 34 | where should those bubbles be plotted?} 35 | 36 | \item{null.order}{Where should non-selected (aka null) features be plotted?} 37 | 38 | \item{null.below.na}{Should null features be plotted below NA features?} 39 | } 40 | \description{ 41 | Determine plotting order of features. 42 | } 43 | -------------------------------------------------------------------------------- /man/tm_scale.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_scale_.R 3 | \name{tm_scale} 4 | \alias{tm_scale} 5 | \title{Scales: automatic scale} 6 | \usage{ 7 | tm_scale(...) 8 | } 9 | \arguments{ 10 | \item{...}{arguments passed on to the applied scale function \verb{tm_scale_*()}} 11 | } 12 | \description{ 13 | Scales in tmap are configured by the family of functions with prefix \code{tm_scale}. 14 | Such function should be used for the input of the \code{.scale} arguments in the 15 | layer functions (e.g. \code{fill.scale} in \code{\link[=tm_polygons]{tm_polygons()}}). The function \code{tm_scale()} 16 | is a scale that is set automatically given by the data type (factor, numeric, and integer) 17 | and the visual variable. The tmap option \code{scales.var} contains information 18 | which scale is applied when. 19 | } 20 | \seealso{ 21 | \code{\link[=tm_scale_asis]{tm_scale_asis()}}, \code{\link[=tm_scale_ordinal]{tm_scale_ordinal()}}, \code{\link[=tm_scale_categorical]{tm_scale_categorical()}}, 22 | \code{\link[=tm_scale_intervals]{tm_scale_intervals()}}, \code{\link[=tm_scale_discrete]{tm_scale_discrete()}}, \code{\link[=tm_scale_continuous]{tm_scale_continuous()}}, 23 | \code{\link[=tm_scale_rank]{tm_scale_rank()}}, \code{\link[=tm_scale_continuous_log]{tm_scale_continuous_log()}}, \code{\link[=tm_scale_continuous_log2]{tm_scale_continuous_log2()}}, 24 | \code{\link[=tm_scale_continuous_log10]{tm_scale_continuous_log10()}}, \code{\link[=tm_scale_continuous_log1p]{tm_scale_continuous_log1p()}}, \code{\link[=tm_scale_continuous_sqrt]{tm_scale_continuous_sqrt()}}, 25 | \code{\link[=tm_scale_continuous_pseudo_log]{tm_scale_continuous_pseudo_log()}}, \code{\link[=tm_scale_rgb]{tm_scale_rgb()}}, \code{\link[=tm_scale_bivariate]{tm_scale_bivariate()}} 26 | } 27 | -------------------------------------------------------------------------------- /man/tm_scale_asis.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_scale_.R 3 | \name{tm_scale_asis} 4 | \alias{tm_scale_asis} 5 | \title{Scales: as is} 6 | \usage{ 7 | tm_scale_asis(values.scale = NA, value.neutral = NA, value.na = NA, ...) 8 | } 9 | \arguments{ 10 | \item{values.scale}{(generic scale argument) Scaling of the values. Only useful for size-related visual variables, such as \code{size} of \code{\link[=tm_symbols]{tm_symbols()}} and \code{lwd} of \code{\link[=tm_lines]{tm_lines()}}.} 11 | 12 | \item{value.neutral}{(generic scale argument) Value that can be considered neutral. This is used for legends of other visual variables of the same map layer. E.g. when both \code{fill} and \code{size} are used for \code{\link[=tm_symbols]{tm_symbols()}} (using filled circles), the size legend items are filled with the \code{value.neutral} color from the \code{fill.scale} scale, and fill legend items are bubbles of size \code{value.neutral} from the \code{size.scale} scale.} 13 | 14 | \item{value.na}{(generic scale argument) Value used for missing values. See tmap option \code{"value.na"} for defaults per visual variable.} 15 | 16 | \item{...}{Arguments caught (and not used) from the automatic function \code{\link[=tm_scale]{tm_scale()}}} 17 | } 18 | \description{ 19 | Scales in tmap are configured by the family of functions with prefix \code{tm_scale}. 20 | Such function should be used for the input of the \code{.scale} arguments in the 21 | layer functions (e.g. \code{fill.scale} in \code{\link[=tm_polygons]{tm_polygons()}}). 22 | The function \code{tm_scale_asis()} is used to take data values as they are and use them as such for the visual variable. 23 | } 24 | \seealso{ 25 | \code{\link[=tm_scale]{tm_scale()}} 26 | } 27 | -------------------------------------------------------------------------------- /man/tm_scale_rgb.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_scale_.R 3 | \name{tm_scale_rgb} 4 | \alias{tm_scale_rgb} 5 | \alias{tm_scale_rgba} 6 | \title{Scales: RGB} 7 | \usage{ 8 | tm_scale_rgb( 9 | value.na = NA, 10 | stretch = FALSE, 11 | probs = c(0, 1), 12 | max_color_value = 255L 13 | ) 14 | 15 | tm_scale_rgba( 16 | value.na = NA, 17 | stretch = FALSE, 18 | probs = c(0, 1), 19 | max_color_value = 255 20 | ) 21 | } 22 | \arguments{ 23 | \item{value.na}{value for missing values} 24 | 25 | \item{stretch}{should each (r, g, b) band be stretched? Possible values: \code{"percent"} (same as \code{TRUE}), \code{"histogram"}, \code{FALSE}. 26 | In the first case, the values are stretched to \verb{probs[1]...probs[2]}. In the second case, a histogram equalization is performed} 27 | 28 | \item{probs}{probability (quantile) values when \code{stretch = "percent"}} 29 | 30 | \item{max_color_value}{maximum value} 31 | } 32 | \description{ 33 | Scales in tmap are configured by the family of functions with prefix \code{tm_scale}. 34 | Such function should be used for the input of the \code{.scale} arguments in the layer 35 | functions (e.g. \code{fill.scale} in \code{\link[=tm_polygons]{tm_polygons()}}). 36 | The function \code{\link[=tm_scale_rgb]{tm_scale_rgb()}} is used to transform r, g, b band variables to colors. This function is adopted from (and works similar as) \code{\link[stars:st_rgb]{stars::st_rgb()}} 37 | } 38 | \examples{ 39 | \dontrun{ 40 | require(stars) 41 | file = system.file("tif/L7_ETMs.tif", package = "stars") 42 | 43 | L7 = stars::read_stars(file) 44 | 45 | tm_shape(L7) + 46 | tm_rgb(col.scale = tm_scale_rgb(probs = c(0, .99), stretch = TRUE)) 47 | 48 | tm_shape(L7) + 49 | tm_rgb(col.scale = tm_scale_rgb(stretch = "histogram")) 50 | } 51 | } 52 | \seealso{ 53 | \code{\link[=tm_scale]{tm_scale()}} and \code{\link[stars:st_rgb]{stars::st_rgb()}} 54 | } 55 | -------------------------------------------------------------------------------- /man/tm_seq.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tmapScale_defaults.R 3 | \name{tm_seq} 4 | \alias{tm_seq} 5 | \title{Specify a numeric sequence} 6 | \usage{ 7 | tm_seq( 8 | from = 0, 9 | to = 1, 10 | power = c("lin", "sqrt", "sqrt_perceptual", "quadratic") 11 | ) 12 | } 13 | \arguments{ 14 | \item{from, to}{The numeric range, default 0 and 1 respectively} 15 | 16 | \item{power}{The power component, a number or or one of \code{"lin"}, \code{"sqrt"}, \code{"sqrt_perceptual"}, \code{"quadratic"}, which correspond to 1, 0.5, 0.5716, 2 respectively. See details.} 17 | } 18 | \description{ 19 | Specify a numeric sequence, for numeric scales like \code{\link[=tm_scale_continuous]{tm_scale_continuous()}}. This function is needed when there is a non-linear relationship between the numeric data values and the visual variables. E.g. to make relationship with the area of bubbles linear, the square root of input variables should be used to calculate the radius of the bubbles. 20 | } 21 | \details{ 22 | The perceived area of larger symbols is often underestimated. Flannery (1971) experimentally derived a method to compensate this for symbols. This compensation is obtained by using the power exponent of 0.5716 instead of 0.5, or by setting \code{power} to \code{"sqrt_perceptual"} 23 | } 24 | -------------------------------------------------------------------------------- /man/tm_title.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_components.R 3 | \name{tm_title} 4 | \alias{tm_title} 5 | \alias{tm_title_in} 6 | \alias{tm_title_out} 7 | \title{Map component: title} 8 | \usage{ 9 | tm_title( 10 | text, 11 | size, 12 | color, 13 | padding, 14 | fontface, 15 | fontfamily, 16 | alpha, 17 | stack, 18 | just, 19 | frame, 20 | frame.color, 21 | frame.alpha, 22 | frame.lwd, 23 | frame.r, 24 | bg, 25 | bg.color, 26 | bg.alpha, 27 | position, 28 | group_id, 29 | width, 30 | height, 31 | z 32 | ) 33 | 34 | tm_title_in(text, ..., position = tm_pos_in("left", "top")) 35 | 36 | tm_title_out(text, ..., position = tm_pos_out("center", "top")) 37 | } 38 | \arguments{ 39 | \item{text}{text} 40 | 41 | \item{size}{font size} 42 | 43 | \item{color}{font color} 44 | 45 | \item{padding}{padding} 46 | 47 | \item{fontface}{font face, bold, italic} 48 | 49 | \item{fontfamily}{font family} 50 | 51 | \item{alpha}{alpha transparency of the text} 52 | 53 | \item{stack}{stack with other map components, either \code{"vertical"} or \code{"horizontal"}.} 54 | 55 | \item{just}{just} 56 | 57 | \item{frame}{frame should a frame be drawn?} 58 | 59 | \item{frame.color}{frame color} 60 | 61 | \item{frame.alpha}{frame alpha transparancy} 62 | 63 | \item{frame.lwd}{frame line width} 64 | 65 | \item{frame.r}{Radius of the rounded frame corners. 0 means no rounding.} 66 | 67 | \item{bg}{Show background?} 68 | 69 | \item{bg.color}{Background color} 70 | 71 | \item{bg.alpha}{Background transparency} 72 | 73 | \item{position}{The position specification of the component: an object created with \code{tm_pos_in()} or \code{tm_pos_out()}. Or, as a shortcut, a vector of two values, specifying the x and y coordinates. The first is \code{"left"}, \code{"center"} or \code{"right"} (or upper case, meaning tighter to the map frame), the second \code{"top"}, \code{"center"} or \code{"bottom"}. Numeric values are also supported, where 0, 0 means left bottom and 1, 1 right top. See also \href{https://r-tmap.github.io/tmap/articles/adv_positions}{vignette about positioning}. In case multiple components should be combined (stacked), use \code{group_id} and specify \code{component} in \code{\link[=tm_comp_group]{tm_comp_group()}}.} 74 | 75 | \item{group_id}{Component group id name. All components (e.g. legends, titles, etc) with the same \code{group_id} will be grouped. The specifications of how they are placed (e.g. stacking, margins etc.) are determined in \code{\link[=tm_comp_group]{tm_comp_group()}} where its argument \code{id} should correspond to \code{group_id}.} 76 | 77 | \item{width, height}{width and height of the component.} 78 | 79 | \item{z}{z index, e.g. the place of the component relative to the other componets} 80 | 81 | \item{...}{passed on to \code{tm_title()}} 82 | } 83 | \description{ 84 | Map component that adds a title 85 | } 86 | \seealso{ 87 | \href{https://r-tmap.github.io/tmap/articles/basics_components}{Vignette about components} 88 | } 89 | -------------------------------------------------------------------------------- /man/tm_vars.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_vars.R 3 | \name{tm_vars} 4 | \alias{tm_vars} 5 | \title{tmap function to specify variables} 6 | \usage{ 7 | tm_vars( 8 | x = NA, 9 | dimvalues = NULL, 10 | n = NA, 11 | multivariate = FALSE, 12 | animate = FALSE 13 | ) 14 | } 15 | \arguments{ 16 | \item{x}{variable names, variable indices, or a dimension name} 17 | 18 | \item{dimvalues}{dimension values} 19 | 20 | \item{n}{if specified the first \code{n} variables are taken (or the first \code{n} dimension values)} 21 | 22 | \item{multivariate}{in case multiple variables are specified, should they serve as facets (FALSE) or as a multivariate visual variable?} 23 | 24 | \item{animate}{should the variable(s) be animated? (experimental)} 25 | } 26 | \description{ 27 | tmap function to specify all variables in the shape object 28 | } 29 | -------------------------------------------------------------------------------- /man/tm_view.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_layout.R 3 | \name{tm_view} 4 | \alias{tm_view} 5 | \title{View mode options} 6 | \usage{ 7 | tm_view( 8 | use_browser, 9 | use_WebGL, 10 | control.position, 11 | control.bases, 12 | control.overlays, 13 | control.collapse, 14 | set_bounds, 15 | set_view, 16 | set_zoom_limits, 17 | use_circle_markers, 18 | leaflet.options, 19 | ... 20 | ) 21 | } 22 | \arguments{ 23 | \item{use_browser}{If \code{TRUE} it opens an external browser, and \code{FALSE} (default) it opens the internal IDEs (e.g. RStudio) browser.} 24 | 25 | \item{use_WebGL}{use webGL for points, lines, and polygons. For large spatial objects, this is much faster than the standard leaflet layer functions. However, it can not always be used for two reasons. First, the number of visual variables are limited; only fill, size, and color (for lines) are supported. Second, projected CRS's are not supported. Furthermore, it has the drawback that polygon borders are not as sharp. By default only \code{TRUE} for large spatial objects (500 or more features) when the mentioned criteria are met. 26 | By default \code{TRUE} if no other visual variables are used.} 27 | 28 | \item{control.position}{The position of the control. A tm_pos object, or a shortcut of two values: horizontal (left, center, right) and vertical (top, center, bottom). See tm_pos for details} 29 | 30 | \item{control.bases}{base layers} 31 | 32 | \item{control.overlays}{overlay layers} 33 | 34 | \item{control.collapse}{Should the box be collapsed or expanded?} 35 | 36 | \item{set_bounds}{logical that determines whether maximum bounds are set, 37 | or a bounding box. Not applicable in plot mode. 38 | In view mode, this is passed on to \link[leaflet:map-methods]{setMaxBounds()}} 39 | 40 | \item{set_view}{numeric vector that determines the view. 41 | Either a vector of three: \code{lng}, \code{lat}, and \code{zoom}, or a single value: 42 | \code{zoom}. See \link[leaflet:map-methods]{setView()}. 43 | Only applicable if \code{bbox} is not specified} 44 | 45 | \item{set_zoom_limits}{numeric vector of two that set the minimum and maximum 46 | zoom levels (see \link[leaflet:map-options]{tileOptions()}).} 47 | 48 | \item{use_circle_markers}{If \code{TRUE} (default) circle shaped symbols (e.g. \code{tm_dots()} and \code{tm_symbols()}) will be rendered as \link[leaflet:map-layers]{addCircleMarkers()} instead of \link[leaflet:map-layers]{addMarkers()}. The former is faster, the latter can support any symbol since it is based on icons} 49 | 50 | \item{leaflet.options}{options passed on to 51 | \link[leaflet:leaflet]{leafletOptions()}} 52 | 53 | \item{...}{to catch deprecated arguments} 54 | } 55 | \description{ 56 | View mode options. These options are specific to the view mode. 57 | } 58 | \seealso{ 59 | \code{\link[=tm_group]{tm_group()}} 60 | } 61 | -------------------------------------------------------------------------------- /man/tm_xlab.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_xylab.R 3 | \name{tm_xlab} 4 | \alias{tm_xlab} 5 | \alias{tm_ylab} 6 | \title{Map: x and y labels} 7 | \usage{ 8 | tm_xlab(text, size, color, rotation, space, fontface, fontfamily, alpha, side) 9 | 10 | tm_ylab(text, size, color, rotation, space, fontface, fontfamily, alpha, side) 11 | } 12 | \arguments{ 13 | \item{text}{text of the title} 14 | 15 | \item{size}{font size of the title} 16 | 17 | \item{color}{color} 18 | 19 | \item{rotation}{rotation in degrees} 20 | 21 | \item{space}{space between label and map in number of line heights} 22 | 23 | \item{fontface}{font face} 24 | 25 | \item{fontfamily}{font family} 26 | 27 | \item{alpha}{alpha transparency of the text} 28 | 29 | \item{side}{side: \code{"top"} or \code{"bottom"} for \code{tm_xlab} and \code{"left"} or \code{"right"} for \code{tm_ylab}} 30 | } 31 | \description{ 32 | The x and y labels for maps 33 | } 34 | -------------------------------------------------------------------------------- /man/tmap-deprecated.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tmap_format.R 3 | \name{tmap_format} 4 | \alias{tmap_format} 5 | \alias{tmap_format_add} 6 | \alias{tm_format} 7 | \title{Deprecated: format} 8 | \usage{ 9 | tmap_format(format) 10 | 11 | tmap_format_add(..., name) 12 | 13 | tm_format(format, ...) 14 | } 15 | \arguments{ 16 | \item{format}{Name of the format} 17 | 18 | \item{...}{not used} 19 | 20 | \item{name}{Name of the format} 21 | } 22 | \description{ 23 | In tmap < 4.0 it was possible to set shape-specific options, such as margins and legend position. However, this has become superfluous because in tmap > 4.0 legends are by default placed outside the map area. If needed, a shape-specific set of options can be stored as a style with tmap_options_save. 24 | } 25 | \keyword{internal} 26 | -------------------------------------------------------------------------------- /man/tmap-element.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_element.R 3 | \name{tmap-element} 4 | \alias{tmap-element} 5 | \alias{+.tmap} 6 | \title{Stacking of tmap elements} 7 | \usage{ 8 | \method{+}{tmap}(e1, e2) 9 | } 10 | \arguments{ 11 | \item{e1}{first tmap element} 12 | 13 | \item{e2}{second tmap element} 14 | } 15 | \description{ 16 | The plus operator allows you to stack tmap elements (functions with a prefix \code{tm_}) 17 | } 18 | -------------------------------------------------------------------------------- /man/tmap-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pkg.R 3 | \docType{package} 4 | \name{tmap-package} 5 | \alias{tmap} 6 | \alias{tmap-package} 7 | \title{Thematic Map Visualization} 8 | \description{ 9 | Thematic maps are geographical maps in which spatial data distributions are visualized. 10 | This package offers a flexible, layer-based, and easy to use approach to create 11 | thematic maps, such as choropleths and bubble maps. It is based on the grammar 12 | of graphics, and resembles the syntax of ggplot2. 13 | } 14 | \references{ 15 | Tennekes, M., 2018, {tmap}: Thematic Maps in {R}, Journal of Statistical Software, 84(6), 1-39, \doi{10.18637/jss.v084.i06} 16 | } 17 | \seealso{ 18 | \href{https://r-tmap.github.io/tmap/index.html}{Main documentation} 19 | } 20 | \author{ 21 | Martijn Tennekes \email{mtennekes@gmail.com} 22 | } 23 | \concept{GIS} 24 | \concept{bubble map} 25 | \concept{choropleth} 26 | \concept{statistical maps} 27 | \concept{thematic maps} 28 | -------------------------------------------------------------------------------- /man/tmapAddLayerOptions.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tmap_options.R 3 | \name{tmapAddLayerOptions} 4 | \alias{tmapAddLayerOptions} 5 | \title{Internal tmap function to add a default value for the layer functions} 6 | \usage{ 7 | tmapAddLayerOptions(option, id, value) 8 | } 9 | \arguments{ 10 | \item{option, }{one of: \code{"value.const"}, \code{"value.na"}, \code{"value.blank"}, \code{"values.var"}, \code{'values.range'}, \code{"value.neutral"}, \code{"scales.var"}} 11 | 12 | \item{id}{name of the visual variable with layer, in the format \code{"x.y"}, 13 | where \code{x} is the visual variable and \code{y} is the layer. 14 | It is also possible to set \code{x} only; then it applies to all layer functions.} 15 | 16 | \item{value}{value} 17 | } 18 | \description{ 19 | Internal tmap function to add a default value for the layer functions 20 | } 21 | \keyword{internal} 22 | -------------------------------------------------------------------------------- /man/tmapGetShapeMeta1.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tmapShape.R 3 | \name{tmapGetShapeMeta1} 4 | \alias{tmapGetShapeMeta1} 5 | \title{Internal method that extracts meta data from shape objects} 6 | \usage{ 7 | tmapGetShapeMeta1(shp, o) 8 | } 9 | \arguments{ 10 | \item{shp}{the shape object} 11 | 12 | \item{o}{the list of options} 13 | } 14 | \description{ 15 | Internal method that extracts meta data from shape objects 16 | } 17 | \keyword{internal} 18 | -------------------------------------------------------------------------------- /man/tmapGetShapeMeta2.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tmapShape.R 3 | \name{tmapGetShapeMeta2} 4 | \alias{tmapGetShapeMeta2} 5 | \title{Internal method that extracts more meta data from shape objects} 6 | \usage{ 7 | tmapGetShapeMeta2(shp, smeta, o) 8 | } 9 | \arguments{ 10 | \item{shp}{the shape} 11 | 12 | \item{smeta}{meta (from \code{tmapGetShapeMeta1()})} 13 | 14 | \item{o}{the list of options} 15 | } 16 | \description{ 17 | Internal method that extracts meta data from shape objects 18 | } 19 | \keyword{internal} 20 | -------------------------------------------------------------------------------- /man/tmapMode.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tmap_options.R 3 | \name{tmapMode} 4 | \alias{tmapMode} 5 | \title{Internal method for submitting a new mode} 6 | \usage{ 7 | tmapMode(id, name, ...) 8 | } 9 | \arguments{ 10 | \item{id}{id of the mode: please use lowercase and one-word. This will be used with \code{\link[=tmap_mode]{tmap_mode()}}.} 11 | 12 | \item{name}{name of the mode: please use title case. This will be used to recognize internal functions, e.g. \code{tmapLeafletInit}} 13 | 14 | \item{...}{mode specific options} 15 | } 16 | \description{ 17 | Internal method for submitting a new mode 18 | } 19 | \keyword{internal} 20 | -------------------------------------------------------------------------------- /man/tmapShape.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tmapShape.R 3 | \name{tmapShape} 4 | \alias{tmapShape} 5 | \title{Internal method that processed shape objects} 6 | \usage{ 7 | tmapShape(shp, is.main, crs, bbox, unit, filter, shp_name, smeta, o, tmf) 8 | } 9 | \arguments{ 10 | \item{shp}{shp} 11 | 12 | \item{is.main}{is.main} 13 | 14 | \item{crs}{crs} 15 | 16 | \item{bbox}{Bounding box} 17 | 18 | \item{unit}{unit} 19 | 20 | \item{filter}{filter} 21 | 22 | \item{shp_name}{shp_name} 23 | 24 | \item{smeta}{smeta} 25 | 26 | \item{o}{o} 27 | 28 | \item{tmf}{tmf} 29 | } 30 | \description{ 31 | Internal method that processed shape objects 32 | } 33 | \keyword{internal} 34 | -------------------------------------------------------------------------------- /man/tmapSplitShp.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tmapSplitShp.R 3 | \name{tmapSplitShp} 4 | \alias{tmapSplitShp} 5 | \title{Internal method that split shape objects} 6 | \usage{ 7 | tmapSplitShp(shp, split_stars_dim, smeta) 8 | } 9 | \arguments{ 10 | \item{shp}{shape} 11 | 12 | \item{split_stars_dim}{name of the dimension to split (\code{""} to skip)} 13 | } 14 | \description{ 15 | Internal method that split shape objects. So far, only used to split stars object 16 | (from dimension to attributes) 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/tmapSubsetShp.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tmapShape.R 3 | \name{tmapSubsetShp} 4 | \alias{tmapSubsetShp} 5 | \title{Internal method that subsets data from shape objects} 6 | \usage{ 7 | tmapSubsetShp(shp, vars) 8 | } 9 | \arguments{ 10 | \item{shp}{shape} 11 | 12 | \item{vars}{a vector of variable names} 13 | } 14 | \description{ 15 | Internal method that subsets data from shape objects 16 | } 17 | \keyword{internal} 18 | -------------------------------------------------------------------------------- /man/tmap_design_mode.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tmap_mode.R 3 | \name{tmap_design_mode} 4 | \alias{tmap_design_mode} 5 | \title{Set the design mode} 6 | \usage{ 7 | tmap_design_mode(design.mode) 8 | } 9 | \arguments{ 10 | \item{design.mode}{Logical value that determines the design mode. 11 | If omitted then the design mode is toggled.} 12 | } 13 | \description{ 14 | When the so-called "design mode" is enabled, inner and outer margins, 15 | legend position, and aspect ratio are shown explicitly in plot mode. 16 | Also, information about aspect ratios is printed in the console. 17 | This function sets the global option \code{tmap.design.mode}. 18 | It can be used as toggle function without arguments. 19 | } 20 | \seealso{ 21 | \code{\link[=tmap_options]{tmap_options()}} 22 | } 23 | -------------------------------------------------------------------------------- /man/tmap_devel_mode.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tmap_mode.R 3 | \name{tmap_devel_mode} 4 | \alias{tmap_devel_mode} 5 | \title{Set the development mode} 6 | \usage{ 7 | tmap_devel_mode(devel.mode) 8 | } 9 | \arguments{ 10 | \item{devel.mode}{logical value that determines the development mode. 11 | If omitted then the development mode is toggled.} 12 | } 13 | \description{ 14 | When the so-called "development mode" is enabled, helpful messages and timings 15 | are printed in the console 16 | } 17 | -------------------------------------------------------------------------------- /man/tmap_icons.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tmap_icons.R 3 | \name{tmap_icons} 4 | \alias{tmap_icons} 5 | \alias{marker_icon} 6 | \title{Specify icons} 7 | \usage{ 8 | tmap_icons( 9 | file, 10 | names = NULL, 11 | width = 48, 12 | height = 48, 13 | keep.asp = TRUE, 14 | just = c("center", "center"), 15 | merge = NA, 16 | as.local = TRUE, 17 | ... 18 | ) 19 | 20 | marker_icon() 21 | } 22 | \arguments{ 23 | \item{file}{character value/vector containing the file path(s) or url(s).} 24 | 25 | \item{names}{names to be given to the icons. Useful when icons are assigned to factor levels.} 26 | 27 | \item{width}{width of the icon. If \code{keep.asp}, this is interpreted as the maximum width.} 28 | 29 | \item{height}{height of the icon. If \code{keep.asp}, this is interpreted as the maximum height.} 30 | 31 | \item{keep.asp}{keep the aspect ratio of the png image. If \code{TRUE} and the aspect 32 | ratio differs from \code{width/height}, either \code{width} or \code{height} is adjusted accordingly.} 33 | 34 | \item{just}{justification of the icons relative to the point coordinates. 35 | The first value specifies horizontal and the second value vertical justification. 36 | Possible values are: \code{"left"} , \code{"right"}, \code{"center"}, \code{"bottom"}, and \code{"top"}. 37 | Numeric values of 0 specify left alignment and 1 right alignment. 38 | The default value of \code{just} is \code{c("center", "center")}.} 39 | 40 | \item{merge}{merge icons to one icon list (see return value)? If \code{FALSE}, a list is created per file. By default \code{TRUE}, unless \code{names} are specified.} 41 | 42 | \item{as.local}{if the \code{file} is a url, should it be saved to local temporary file?} 43 | 44 | \item{...}{arguments passed on to \code{\link[leaflet:icons]{leaflet::icons()}}. 45 | When \code{iconWidth}, \code{iconHeight}, \code{iconAnchorX}, and \code{iconAnchorY} are specified, 46 | they override \code{width} and \code{height}, and \code{just}.} 47 | } 48 | \value{ 49 | icon data (see \code{\link[leaflet:icons]{leaflet::icons()}}) 50 | } 51 | \description{ 52 | Specifies icons from a png images, which can be used as markers in thematic maps. 53 | The function \code{marker_icon()} is the specification of the default marker. 54 | } 55 | \seealso{ 56 | \code{\link[=tm_symbols]{tm_symbols()}} 57 | } 58 | -------------------------------------------------------------------------------- /man/tmap_last.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_element.R 3 | \name{tmap_last} 4 | \alias{tmap_last} 5 | \title{Retrieve the last map to be modified or created} 6 | \usage{ 7 | tmap_last() 8 | } 9 | \value{ 10 | call 11 | } 12 | \description{ 13 | Retrieve the last map to be modified or created. Works in the same way 14 | as \code{ggplot2::last_plot()}, although there is a difference: 15 | \code{tmap_last()} returns the last call instead of the stacked \code{\link{tmap-element}}s. 16 | } 17 | \seealso{ 18 | \code{\link[=tmap_save]{tmap_save()}} 19 | } 20 | -------------------------------------------------------------------------------- /man/tmap_leaflet.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tmap_export.R 3 | \name{tmap_leaflet} 4 | \alias{tmap_leaflet} 5 | \alias{tmap_grob} 6 | \title{Export tmap to the format of the used graphics mode} 7 | \usage{ 8 | tmap_leaflet(x, show = FALSE, ...) 9 | 10 | tmap_grob(x, asp = NA, scale = 1, show = FALSE, ...) 11 | } 12 | \arguments{ 13 | \item{x}{a tmap object.} 14 | 15 | \item{show}{show the map?} 16 | 17 | \item{...}{ 18 | Arguments passed on to \code{\link[=print.tmap]{print.tmap}} 19 | \describe{ 20 | \item{\code{return.asp}}{should the aspect ratio be returned?} 21 | \item{\code{vp}}{viewport (for \code{"plot"} mode)} 22 | \item{\code{knit}}{A logical, should knit?} 23 | \item{\code{in.shiny}}{A logical, is the map drawn in \strong{shiny}?} 24 | \item{\code{proxy}}{A logical, if \code{in.shiny}, is \code{\link[=tmapProxy]{tmapProxy()}} used?} 25 | \item{\code{options}}{A vector of options} 26 | }} 27 | 28 | \item{asp, scale}{the desired aspect ratio and scale of the map. Only applicable for \code{"plot"} mode.} 29 | } 30 | \value{ 31 | \itemize{ 32 | \item \code{tmap_grob()} returns a \code{\link[grid:grid.grob]{grob}} object (\code{"plot"} mode) 33 | \item \code{tmap_leaflet()} a \code{\link[leaflet:leaflet]{leaflet}} object (\code{"view"} mode). 34 | In case small multiples are shown, a list is returned. 35 | } 36 | } 37 | \description{ 38 | \itemize{ 39 | \item \code{tmap_grob()} returns a \code{\link[grid:grid.grob]{grob}} object (\verb{"plot" mode}) 40 | \item \code{tmap_leaflet()} a \code{\link[leaflet:leaflet]{leaflet}} object (\code{"view"} mode). 41 | } 42 | } 43 | \examples{ 44 | map = tm_shape(World) + tm_polygons() 45 | tmap_leaflet(map, show = TRUE) 46 | } 47 | -------------------------------------------------------------------------------- /man/tmap_providers.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tmapOnLoad.R, R/tmap_providers.R 3 | \docType{data} 4 | \name{.tmap_providers} 5 | \alias{.tmap_providers} 6 | \alias{tmap_provider_credits} 7 | \alias{tmap_providers} 8 | \title{Get basemap tiles providers} 9 | \format{ 10 | An object of class \code{environment} of length 44. 11 | } 12 | \usage{ 13 | .tmap_providers 14 | 15 | tmap_provider_credits(provider) 16 | 17 | tmap_providers(mode, credits = FALSE, as.list = credits) 18 | } 19 | \arguments{ 20 | \item{provider}{provider name} 21 | 22 | \item{mode}{mode. If not specified the default mode is used} 23 | 24 | \item{credits}{If \code{TRUE} the credit (attribution) text is returned. If \code{FALSE} (default) the provider name.} 25 | 26 | \item{as.list}{Should the output be returned as list where names are provider names? By default \code{TRUE} when \code{credits} is also \code{TRUE}.} 27 | } 28 | \value{ 29 | list or vector (see \code{as.list}) with providers (or credits). \code{\link[=tmap_provider_credits]{tmap_provider_credits()}} returns the credits text for the provided provider. 30 | } 31 | \description{ 32 | Get basemap tiles providers and the credits (attribution text). \code{\link[=tmap_providers]{tmap_providers()}} returns a list (or vector) with provider nams (or credits). \code{\link[=tmap_provider_credits]{tmap_provider_credits()}} 33 | } 34 | \keyword{datasets} 35 | -------------------------------------------------------------------------------- /man/tmap_style.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tmap_style.R 3 | \name{tmap_style} 4 | \alias{tmap_style} 5 | \title{Set or get the default tmap style} 6 | \usage{ 7 | tmap_style(style) 8 | } 9 | \arguments{ 10 | \item{style}{Name of the style. When omitted, \code{tmap_style()} returns the current style 11 | and also shows all available styles. When the style is specified,\code{tmap_style()} 12 | sets the style accordingly. Note that in that case, all tmap options (see \code{\link[=tmap_options]{tmap_options()}}) 13 | will be reset according to the style definition. 14 | See \code{\link[=tm_layout]{tm_layout()}} for predefined styles, and \code{tmap_style_catalogue()} for creating a catalogue.} 15 | } 16 | \value{ 17 | The style before changing 18 | } 19 | \description{ 20 | Set or get the default tmap style. Without arguments, the current style is returned. 21 | Also the available styles are displayed. When a style is set, the corresponding tmap 22 | options (see \code{\link[=tmap_options]{tmap_options()}}) will be set accordingly. 23 | The default style (i.e. when loading the package) is \code{"white"}. 24 | } 25 | \details{ 26 | Note that \code{\link[=tm_style]{tm_style()}} is used within a plot call (so it only affects that plot), 27 | whereas \code{tmap_style()} sets the style globally. 28 | 29 | After loading a style, the options that defined this style 30 | (i.e. the difference with the default \code{"white"} style) can be obtained by \code{\link[=tmap_options_diff]{tmap_options_diff()}}. 31 | 32 | The documentation of \code{\link[=tmap_options]{tmap_options()}} (details and the examples) shows how to create a new style. 33 | } 34 | \examples{ 35 | tmap_style() 36 | 37 | tm_shape(World) + tm_polygons("HPI") 38 | 39 | tmap_style("cobalt") 40 | 41 | tm_shape(World) + tm_polygons("HPI") 42 | 43 | # for backwards compatibility, the styles of tmap versions 1-3 are also included: 44 | 45 | tmap_style("v3") 46 | 47 | tm_shape(World) + tm_polygons("HPI") 48 | 49 | tmap_style("cobalt_v3") 50 | 51 | tm_shape(World) + tm_polygons("HPI") 52 | } 53 | \seealso{ 54 | \itemize{ 55 | \item \code{\link[=tmap_options]{tmap_options()}} for tmap options 56 | \item \code{\link[=tmap_style_catalogue]{tmap_style_catalogue()}} to create a style catalogue of all available styles. 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /man/tmap_style_catalogue.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tmap_style_catalogue.R 3 | \name{tmap_style_catalogue} 4 | \alias{tmap_style_catalogue} 5 | \alias{tmap_style_catalog} 6 | \title{Create a style catalogue} 7 | \usage{ 8 | tmap_style_catalogue(path = "./tmap_style_previews", styles = NA) 9 | 10 | tmap_style_catalog(path = "./tmap_style_previews", styles = NA) 11 | } 12 | \arguments{ 13 | \item{path}{path where the png images are stored} 14 | 15 | \item{styles}{vector of styles function names (see \code{\link[=tmap_style]{tmap_style()}}) for which a preview is generated. By default, a preview is generated for all loaded styles.} 16 | } 17 | \description{ 18 | Create a style catalogue for each predefined tmap style. The result is a set of png images, one for each style. 19 | } 20 | -------------------------------------------------------------------------------- /man/tmap_tip.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tmap_tip.R 3 | \name{tmap_tip} 4 | \alias{tmap_tip} 5 | \title{Print a random tip to the console} 6 | \usage{ 7 | tmap_tip() 8 | } 9 | \value{ 10 | A message 11 | } 12 | \description{ 13 | Print a random tip to the console 14 | } 15 | -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/pkgdown/favicon/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/pkgdown/favicon/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/pkgdown/favicon/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/pkgdown/favicon/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/pkgdown/favicon/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/pkgdown/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/pkgdown/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/pkgdown/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/pkgdown/favicon/favicon.ico -------------------------------------------------------------------------------- /sandbox/grid_design.R: -------------------------------------------------------------------------------- 1 | library(grid) 2 | 3 | o = tmap_options() 4 | 5 | # calculate margins (using grid system) 6 | o = process_margins(o) 7 | 8 | #o$nby = get_nby(o$fl) 9 | tf = tm_facets_wrap() 10 | o = c(o, tf[[1]]) 11 | 12 | 13 | o$n = 9#prod(o$nby) 14 | o$asp = NA 15 | o$ncols = NA 16 | o$nrows = NA 17 | o$sasp = 2 18 | o$npages = 1 19 | o = how_many_rows(o) 20 | #o$x 21 | #o$nrows = 6 22 | #o$meta.margins = c(0.2,0.1,0,0) 23 | #o$panel.type = "wrap" 24 | 25 | tmapGridInit2(o) 26 | 27 | gts = get("gts", envir = .TMAP_GRID) 28 | g = get("g", envir = .TMAP_GRID) 29 | 30 | bbx = sf::st_bbox(World) 31 | 32 | 33 | g$fasp 34 | 35 | 36 | 37 | 38 | 39 | 40 | tmapGridShape = function(bbx, facet_row, facet_col, facet_page) { 41 | gts = get("gts", envir = .TMAP_GRID) 42 | g = get("g", envir = .TMAP_GRID) 43 | 44 | 45 | basp = (bbx[3] - bbx[1]) / (bbx[4] - bbx[2]) 46 | 47 | fbbx = bb_asp(bbx, g$fasp) 48 | 49 | rc_text = frc(facet_row, facet_col) 50 | 51 | rowid = g$rows_facet_ids[facet_row] 52 | colid = g$cols_facet_ids[facet_col] 53 | 54 | 55 | gtmap = grid::grobTree(grid::rectGrob(gp=grid::gpar(col="blue", lwd = 4, fill = NA), name = paste0("blue_rect_", rc_text)), 56 | vp = grid::vpStack(grid::viewport(layout.pos.col = colid, layout.pos.row = rowid, name = paste0("vp_facet_", rc_text)), 57 | grid::viewport(xscale = fbbx[c(1,3)], yscale = fbbx[c(2,4)], name = paste0("vp_map_", rc_text), clip = TRUE)), name = paste0("gt_facet_", rc_text)) 58 | 59 | gts[[facet_page]] = grid::addGrob(gts[[facet_page]], gtmap, gPath = grid::gPath("gt_facets")) 60 | 61 | #assign("devsize", devsize, envir = .TMAP_GRID) 62 | #assign("dasp", dasp, envir = .TMAP_GRID) 63 | assign("gts", gts, envir = .TMAP_GRID) 64 | #assign("bbx", bbx, envir = .TMAP_GRID) 65 | 66 | 67 | } 68 | -------------------------------------------------------------------------------- /sandbox/issues2.R: -------------------------------------------------------------------------------- 1 | f = system.file("shapes/world.gpkg", package = "spData") 2 | world = read_sf(f) 3 | tanzania = read_sf(f, query = 'SELECT * FROM world WHERE name_long = "Tanzania"') 4 | 5 | tmap_design_mode() 6 | 7 | tm_shape(tanzania) + 8 | tm_polygons(lwd = 2) + 9 | tm_scalebar(c(0, 200, 400), position = tm_pos_out("center", "bottom")) 10 | 11 | 12 | # problem 1: alignment 13 | # problem 2: scalebar (comp in general?) width: wsu[3] = fW, margins make it smaller. Why are margins not included in fW? 14 | 15 | 16 | tmap_design_mode() 17 | 18 | tm_shape(tanzania) + 19 | tm_polygons(lwd = 2) + 20 | tm_title("gfjgklds hgfjdhkljghkl ;gfdgjklgf", position = tm_pos_out("center", "bottom")) 21 | 22 | tm_shape(tanzania) + 23 | tm_polygons(lwd = 2) + 24 | tm_compass(position = tm_pos_out("center", "bottom"), frame = TRUE) 25 | 26 | 27 | tm_shape(tanzania) + 28 | tm_polygons(lwd = 2) + 29 | tm_scalebar(c(0, 200, 400), position = tm_pos_out("center", "bottom"), margins = rep(0,4)) + 30 | tm_compass(position = tm_pos_out("center", "bottom"), frame = TRUE, margins = rep(0,4)) 31 | 32 | 33 | # problem 3: 34 | tm_shape(World) + 35 | tm_polygons(lwd = 2) + 36 | tm_compass(position = tm_pos_out("center", "bottom"), frame = TRUE) 37 | 38 | tm_shape(World) + 39 | tm_polygons(lwd = 2, fill = "life_exp") + 40 | tm_compass(position = tm_pos_out("center", "bottom"), frame = TRUE) 41 | 42 | 43 | 44 | tm_shape(World) + 45 | tm_polygons(lwd = 2, fill = "life_exp") + 46 | tm_compass(position = tm_pos_out("center", "bottom"), frame = TRUE) 47 | 48 | # process_meta 381 49 | # problem: don't know yet if autoout is placed t/b or l/r. 50 | # autoout right bottom 51 | -------------------------------------------------------------------------------- /sandbox/load_test_data.R: -------------------------------------------------------------------------------- 1 | library(stars) 2 | library(sf) 3 | library(data.table) 4 | library(pryr) 5 | library(profvis) 6 | 7 | 8 | source("sandbox/test_data.R") 9 | World$gdp_est_mln = World$gdp_cap_est * World$pop_est / 1e6 10 | World$well_being2 = round(World$well_being * rnorm(nrow(World), mean = 1, sd = .2), 1) 11 | set.seed = 1234 12 | World$r1 = round(runif(nrow(World), min = 0, max = 255)) 13 | World$g1 = round(runif(nrow(World), min = 0, max = 255)) 14 | World$b1 = round(runif(nrow(World), min = 0, max = 255)) 15 | World$r2 = round(pmin(pmax(World$r1 + rnorm(nrow(World), mean = 0, sd = 50), 0), 255)) 16 | World$g2 = round(pmin(pmax(World$g1 + rnorm(nrow(World), mean = 0, sd = 50), 0), 255)) 17 | World$b2 = round(pmin(pmax(World$b1 + rnorm(nrow(World), mean = 0, sd = 50), 0), 255)) 18 | 19 | World$alpha_class = factor(floor(seq(1, 5, length.out = nrow(World) + 1)[1:nrow(World)]), labels = LETTERS[1:4]) 20 | World$pop_class = cut(World$pop_est, breaks = c(0, 10, 100, 1000, Inf) * 1e6, labels = c("Small", "Medium", "Large", "Extra Large")) 21 | 22 | World$income_grp_int = as.integer(World$income_grp) 23 | World$HPI2 = World$HPI / 2 24 | World$HPI3 = round(World$HPI) 25 | 26 | World$HPI_class = cut(World$HPI, breaks = seq(10, 50, by = 10)) 27 | World$well_being_class = cut(World$well_being, breaks = seq(2, 8, by = 2)) 28 | World$footprint_class = cut(World$footprint, breaks = seq(0, 16, by = 4)) 29 | 30 | 31 | metro$alpha_class = factor(floor(seq(1, 5, length.out = nrow(metro) + 1)[1:nrow(metro)]), labels = LETTERS[1:4]) 32 | -------------------------------------------------------------------------------- /sandbox/test_grid.R: -------------------------------------------------------------------------------- 1 | library(grid) 2 | 3 | 4 | vpA = viewport(w=0.8, h=0.8) 5 | vpB = viewport(w=0.8, h=0.8, x = .3, y = .3) 6 | 7 | 8 | vpS = vpStack(vpA, vpB) 9 | 10 | g = rectGrob(gp=gpar(fill="red"), vp = vpS) 11 | 12 | grobTree 13 | 14 | 15 | library(gtable) 16 | 17 | 18 | 19 | grid.newpage() 20 | grid.draw(g) 21 | 22 | 23 | 24 | tree <- vpTree(viewport(w=0.8, h=0.8, name="A"), 25 | vpList(vpStack(viewport(x=0.1, y=0.1, w=0.5, h=0.5, 26 | just=c("left", "bottom"), name="B"), 27 | viewport(x=0.1, y=0.1, w=0.5, h=0.5, 28 | just=c("left", "bottom"), name="C"), 29 | viewport(x=0.1, y=0.1, w=0.5, h=0.5, 30 | just=c("left", "bottom"), name="D")), 31 | viewport(x=0.5, w=0.4, h=0.9, 32 | just="left", name="E"))) 33 | pushViewport(tree) 34 | 35 | 36 | 37 | 38 | gLsts = lapply(LETTERS[1:5], function(i) { 39 | seekViewport(i) 40 | gList(grid::rectGrob(), 41 | grid::textGrob(current.vpTree(FALSE), 42 | x=unit(1, "mm"), y=unit(1, "npc") - unit(1, "mm"), 43 | just=c("left", "top"), 44 | gp=gpar(fontsize=8))) 45 | 46 | }) 47 | 48 | 49 | g = do.call(grid::gList, gLsts) 50 | 51 | 52 | grid.draw(g) 53 | -------------------------------------------------------------------------------- /sandbox/tests.R: -------------------------------------------------------------------------------- 1 | source("sandbox/test_data.R") 2 | source("../tmap_v4/tmap/sandbox/test_data.R") 3 | 4 | 5 | # SHAPES 6 | # one polygon shape 7 | tm_shape(World) + 8 | tm_polygons("HPI") 9 | 10 | # one polygon shape, two aes values 11 | tm_shape(World) + 12 | tm_polygons(c("HPI", "income_grp")) 13 | 14 | # split polygon shape (by) 15 | tm_shape(World) + 16 | tm_polygons("HPI") + 17 | tm_facets(by = "continent") 18 | 19 | 20 | # split polygon shape (by), with fixed coords 21 | tm_shape(World) + 22 | tm_polygons("HPI") + 23 | tm_facets(by = "continent", free.coords = FALSE) 24 | 25 | # 26 | 27 | 28 | # SCALING 29 | tm = tm_shape(World) + 30 | tm_polygons("HPI") + 31 | tm_symbols(size = "pop_est") 32 | 33 | # one panel 34 | tm + tm_layout(panel.labels = "Test") 35 | 36 | tm + tm_facets(by = "continent") 37 | tm + tm_facets(by = "income_grp") 38 | 39 | tm + tm_facets_grid(rows = "income_grp", columns = "economy") 40 | tm + tm_facets(by = c("income_grp", "economy")) 41 | 42 | 43 | 44 | 45 | 46 | 47 | # PANELS 48 | 49 | tm_shape(World) + 50 | tm_polygons("HPI") + 51 | tm_symbols(size = "pop_est") + 52 | tm_facets(by = "continent", free.coords = FALSE) + 53 | tm_options(scale = .5) 54 | 55 | tm_shape(World) + 56 | tm_polygons("HPI") + 57 | tm_symbols(size = "pop_est") + 58 | tm_layout(panel.show = TRUE, panel.labels = "Test") 59 | #tm_facets(by = "continent", free.coords = FALSE, scale.factor = 2) 60 | 61 | 62 | 63 | tm_shape(World) + 64 | tm_polygons("HPI") + 65 | tm_layout(panel.show = TRUE, panel.labels = "Test") 66 | 67 | 68 | # 69 | 70 | 71 | 72 | 73 | 74 | 75 | # facet wrao 76 | tm_shape(World) + 77 | tm_polygons("HPI") + 78 | tm_facets(by = "continent") #default: free.coords = TRUE 79 | 80 | 81 | # facet wrao (same coords) 82 | tm_shape(World) + 83 | tm_polygons("HPI") + 84 | tm_facets(by = "continent", free.coords = FALSE) #default: free.coords = TRUE 85 | 86 | # for rasters: 87 | # v3 88 | tm_shape(land) + 89 | tm_raster("trees", palette = "viridis") + 90 | tm_facets(by = "cover_cls") 91 | 92 | tm_shape(land) + 93 | tm_raster("trees", palette = "viridis") + 94 | tm_facets(by = "cover_cls", free.coords = FALSE) 95 | 96 | # v4 97 | tm_shape(land) + 98 | tm_raster("trees", col.scale = tm_scale_intervals(values = "viridis")) + 99 | tm_facets(by = "cover_cls") 100 | 101 | tm_shape(land) + 102 | tm_raster("trees", col.scale = tm_scale_intervals(values = "viridis")) + 103 | tm_facets(by = "cover_cls", free.coords = FALSE) 104 | 105 | 106 | 107 | tm_shape(land) + 108 | tm_raster("trees") 109 | 110 | 111 | 112 | tm_shape(land) + 113 | tm_raster("trees", colorNA = "black") + 114 | tm_facets(by = "cover_cls") 115 | 116 | 117 | 118 | # panel labels 119 | tm_shape(World) + 120 | tm_polygons("HPI") + 121 | tm_ 122 | 123 | -------------------------------------------------------------------------------- /sandbox/todo-list.txt: -------------------------------------------------------------------------------- 1 | to do list: 2 | 3 | * reverse palettes with "-" 4 | * scale_down marginal legends 5 | * (filter + colorNULL) + drop.units 6 | 7 | -------------------------------------------------------------------------------- /tests/helper_functions/facet_test_functions.R: -------------------------------------------------------------------------------- 1 | testname <- function(test) paste0(test$layer, "_", unname(unlist(test$args))[1]) 2 | 3 | run_facet_test <- function(test) { 4 | library(sf) 5 | library(grid) 6 | library(raster) 7 | 8 | data(NLD_prov) 9 | 10 | NLD_prov <- st_sf(name = as.character(NLD_prov$name), geometry=NLD_prov$geometry, stringsAsFactors = FALSE) 11 | NLD_prov$by <- factor(rep(c(NA,2,3, 4), each = 3), levels=1:4, labels = letters[1:4]) 12 | NLD_prov$v1 <- c(9, 8, 3, 7, 8, NA, NA, NA, NA, 3, 5, NA) 13 | NLD_prov$v2 <- c("x", "y", NA, NA, NA, NA, "x", "y", "x", "y", NA, NA) 14 | NLD_prov$name2 <- NLD_prov$name 15 | NLD_prov$name[c(5, 7, 8, 9)] <- NA 16 | 17 | filter <- c(TRUE, TRUE) # extra option: if c(T, F) units 1, 3, ... are selected 18 | 19 | #test <- tests[[16]] 20 | 21 | 22 | shp <- NLD_prov 23 | if (test$layer == "lines") { 24 | shp$geometry <- sf::st_cast(shp$geometry, "MULTILINESTRING", group_or_split = FALSE) 25 | } 26 | 27 | dir.create("output", showWarnings = FALSE) 28 | filename <- paste0("output/test_", test$layer, "_", unname(unlist(test$args))[1], ".pdf") 29 | fun <- paste0("tm_", test$layer) 30 | 31 | pdf(filename, width = 7, height = 7) 32 | 33 | settings <- list(drop.units = c(TRUE, FALSE), 34 | free.coords = c(TRUE, FALSE), 35 | free.scales = c(TRUE, FALSE), 36 | drop.empty.facets = c(TRUE, FALSE), 37 | showNA = c(TRUE, FALSE), 38 | drop.NA.facets = c(TRUE, FALSE)) 39 | shortcuts <- c("du", "fc", "fs", "de", "dn", "sn") 40 | comb <- do.call(expand.grid, c(settings, list(KEEP.OUT.ATTRS = FALSE))) 41 | 42 | 43 | # comb[c(44,60), ] 44 | 45 | cat("\ntest:", testname(test), "\n") 46 | pb <- txtProgressBar(min = 1, max = nrow(comb), initial = 1) 47 | errs <- data.frame(i = 1:nrow(comb), 48 | err = character(nrow(comb)), 49 | stringsAsFactors = FALSE) 50 | for (i in 1:nrow(comb)) { 51 | setTxtProgressBar(pb, i) 52 | cb <- as.list(comb[i,]) 53 | name <- paste(mapply(paste0, shortcuts, c("F", "T")[as.numeric(unlist(cb)) + 1]), collapse = "_") 54 | 55 | errs[i, 2] <- tryCatch({ 56 | tm <- tm_shape(shp, filter = filter) 57 | if (fun == "tm_symbols") tm <- tm + tm_borders() 58 | print(tm + 59 | do.call(fun, test$args) + 60 | do.call(tm_facets, c(list(by="by"), cb)) + 61 | tm_layout(title=name) 62 | ) 63 | "" 64 | }, error=function(e) { 65 | # grid.newpage() 66 | grid::upViewport(0) 67 | grid.text(y = .8, label = name) 68 | grid.text(y = .2, label = e) 69 | as.character(e) 70 | }, warning = function(w) { 71 | as.character(w) 72 | }) 73 | } 74 | dev.off() 75 | errs <- errs[errs$err != "", ] 76 | 77 | name <- testname(test) 78 | 79 | filename <- paste0("output/results_", name, ".rds") 80 | saveRDS(errs, file = filename) 81 | 82 | nr <- nrow(errs) 83 | 84 | if (nr!=0) { 85 | cat(name, paste(errs$i, collapse =", "), "\n") 86 | } 87 | 88 | nr 89 | } 90 | -------------------------------------------------------------------------------- /tests/helper_functions/manual_traceback.R: -------------------------------------------------------------------------------- 1 | get_test <- function(tnr, i) { 2 | test <- tests[[tnr]] 3 | fun <- paste0("tm_", test$layer) 4 | 5 | settings <- list(drop.units = c(TRUE, FALSE), 6 | free.coords = c(TRUE, FALSE), 7 | free.scales = c(TRUE, FALSE), 8 | drop.empty.facets = c(TRUE, FALSE), 9 | showNA = c(TRUE, FALSE), 10 | drop.NA.facets = c(TRUE, FALSE)) 11 | shortcuts <- c("du", "fc", "fs", "de", "dn", "sn") 12 | comb <- do.call(expand.grid, c(settings, list(KEEP.OUT.ATTRS = FALSE))) 13 | 14 | cb <- as.list(comb[i,]) 15 | name <- paste(mapply(paste0, shortcuts, c("F", "T")[as.numeric(unlist(cb)) + 1]), collapse = "_") 16 | 17 | cat("shp <- NLD_prov\n") 18 | if (test$layer == "lines") { 19 | cat("shp$geometry <- sf::st_cast(shp$geometry, \"MULTILINESTRING\", group_or_split = FALSE)\n") 20 | } 21 | if (fun == "tm_symbols") { 22 | cat("tm_shape(shp) + tm_borders() +\n") 23 | } else { 24 | cat("tm_shape(shp) + \n") 25 | } 26 | 27 | anames <- names(test$args) 28 | aclass <- sapply(test$args, class) 29 | avalues <- unname(unlist(test$args)) 30 | 31 | if (any(aclass=="character")) { 32 | avalues[aclass == "character"] <- paste0("\"", avalues[aclass == "character"], "\"") 33 | } 34 | 35 | cat(paste0(fun, "(", paste(unlist(mapply(paste, anames, avalues, MoreArgs = list(sep = " = "), SIMPLIFY = FALSE)), collapse=", "), ")"), "+\n") 36 | cbnames <- names(cb) 37 | cbvalues <- unname(unlist(cb)) 38 | cat(paste0("tm_facets(by = \"by\", ", paste(unlist(mapply(paste, cbnames, cbvalues, MoreArgs = list(sep = " = "), SIMPLIFY = FALSE)), collapse=", "), ")"), "\n") 39 | } 40 | 41 | trace_test <- function(ids, rev = FALSE) { 42 | settings <- list(drop.units = c(TRUE, FALSE), 43 | free.coords = c(TRUE, FALSE), 44 | free.scales = c(TRUE, FALSE), 45 | drop.empty.facets = c(TRUE, FALSE), 46 | showNA = c(TRUE, FALSE), 47 | drop.NA.facets = c(TRUE, FALSE)) 48 | shortcuts <- c("du", "fc", "fs", "de", "dn", "sn") 49 | comb <- do.call(expand.grid, c(settings, list(KEEP.OUT.ATTRS = FALSE))) 50 | 51 | if (rev) ids <- setdiff(1L:nrow(comb), ids) 52 | comb[ids, ] 53 | } 54 | -------------------------------------------------------------------------------- /tests/testing_panels.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Testing - Panel labels" 3 | author: "Martijn Tennekes" 4 | date: "`r Sys.Date()`" 5 | output: html_document 6 | editor_options: 7 | chunk_output_type: console 8 | --- 9 | 10 | ```{r setup, include=FALSE} 11 | knitr::opts_chunk$set(echo = TRUE, fig.width = 9) 12 | library(tmap) 13 | ``` 14 | 15 | 16 | 17 | ### Single map 18 | 19 | ```{r} 20 | # default: no panels 21 | tm_shape(World) + 22 | tm_polygons("HPI") 23 | ``` 24 | 25 | ```{r} 26 | # with 27 | tm_shape(World) + 28 | tm_polygons("HPI") + 29 | tm_layout(panel.show = TRUE) 30 | ``` 31 | 32 | ### Facets defined with multiple variables 33 | 34 | ```{r} 35 | # default: with panels 36 | tm_shape(World) + 37 | tm_polygons(c("HPI", "footprint")) 38 | ``` 39 | 40 | ```{r} 41 | # without 42 | tm_shape(World) + 43 | tm_polygons(c("HPI", "footprint")) + 44 | tm_layout(panel.show = FALSE) 45 | ``` 46 | 47 | 48 | ```{r} 49 | # default: with panels 50 | tm_shape(World) + 51 | tm_polygons("HPI") + 52 | tm_facets("continent") 53 | 54 | 55 | ### Facets defined with multiple variables, single pages 56 | 57 | 58 | ```{r} 59 | # default: without 60 | tm_shape(World) + 61 | tm_polygons(c("HPI", "footprint")) + 62 | tm_facets_pagewise() 63 | 64 | ```{r} 65 | # with 66 | tm_shape(World) + 67 | tm_polygons(c("HPI", "footprint")) + 68 | tm_facets_pagewise() + 69 | tm_layout(panel.show = TRUE) 70 | ``` 71 | 72 | ### Facets defined with 'by' variable 73 | 74 | ```{r} 75 | # default: with 76 | tm_shape(World) + 77 | tm_polygons("HPI") + 78 | tm_facets("continent") 79 | ``` 80 | 81 | ```{r} 82 | # without 83 | tm_shape(World) + 84 | tm_polygons("HPI") + 85 | tm_facets("continent") + 86 | tm_layout(panel.show = FALSE) 87 | ``` 88 | 89 | ### Facet grid 90 | 91 | ```{r} 92 | # default: with panels 93 | tm_shape(World) + 94 | tm_polygons("HPI") + 95 | tm_facets_grid("continent", "economy") 96 | ``` 97 | 98 | ```{r} 99 | # without 100 | tm_shape(World) + 101 | tm_polygons("HPI") + 102 | tm_facets_grid("continent", "economy") + 103 | tm_layout(panel.show = FALSE) 104 | ``` 105 | 106 | -------------------------------------------------------------------------------- /tests/testing_scales.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Testing - Scales" 3 | author: "Martijn Tennekes" 4 | date: "`r Sys.Date()`" 5 | output: html_document 6 | --- 7 | 8 | ```{r setup, include=FALSE} 9 | knitr::opts_chunk$set(echo = TRUE, fig.width = 9) 10 | ``` 11 | 12 | # Instructions 13 | 14 | Open the tmap repository as RStudio project. 15 | Set Knit Directory (via drop-down menu of the Knit button in RStudio) to Project Directory. 16 | 17 | ```{r echo=FALSE,message=FALSE,fig.height = 2} 18 | library(devtools) 19 | load_all() 20 | data(World,metro,land) 21 | 22 | World$pop_class = cut(World$pop_est, breaks = c(0, 10, 100, 1000, Inf) * 1e6, labels = c("Small", "Medium", "Large", "Extra Large")) 23 | World$HPI_class = cut(World$HPI, breaks = seq(10, 50, by = 10)) 24 | World$well_being_class = cut(World$well_being, breaks = seq(2, 8, by = 2)) 25 | World$footprint_class = cut(World$footprint, breaks = seq(0, 16, by = 4)) 26 | 27 | metro$pop2020_class = cut(metro$pop2020, breaks = c(.5, 1.5, 2.5, 5, 15, 40) * 1e6) 28 | 29 | 30 | 31 | Africa = World[World$continent == "Africa", ] 32 | tmapV = ifelse(packageVersion("tmap") >= "3.4", "4", "3") 33 | txt = function(x) print(grid::grid.text(x, gp = gpar(cex = 3))) 34 | v3 = function(e) { 35 | if (tmapV == "3") { 36 | print(e) 37 | } else { 38 | txt("Only for tmap 3") 39 | } 40 | invisible(NULL) 41 | } 42 | v4 = function(e) { 43 | if (tmapV == "4") { 44 | print(e) 45 | } else { 46 | txt("Only for tmap 4") 47 | } 48 | invisible(NULL) 49 | } 50 | txt(paste("Loaded tmap version", tmapV)) 51 | ``` 52 | 53 | # Continuous scales 54 | 55 | ```{r} 56 | tm_shape(Africa) + 57 | tm_symbols(size = "gdp_cap_est", size.scale = tm_scale_continuous(limits = c(0, 20000), ticks = c(5000,7500, 15000, 20000))) 58 | ``` 59 | 60 | 61 | ```{r} 62 | Africa$x = runif(nrow(Africa), min = 1, max = 3) 63 | tm_shape(Africa) + 64 | tm_symbols(size = "x", size.scale = tm_scale_continuous_log()) 65 | ``` 66 | 67 | 68 | ```{r} 69 | tm_shape(Africa) + 70 | tm_symbols(size = "x", size.scale = tm_scale_continuous_log2()) 71 | ``` 72 | 73 | 74 | ```{r} 75 | tm_shape(Africa) + 76 | tm_symbols(fill = "x", fill.scale = tm_scale_continuous_log()) 77 | ``` 78 | 79 | ```{r} 80 | tm_shape(Africa) + 81 | tm_symbols(fill = "gdp_cap_est", fill.scale = tm_scale_continuous_log()) 82 | ``` 83 | 84 | 85 | ```{r} 86 | Africa$y = seq(1, 10000, length.out = nrow(Africa)) 87 | tm_shape(Africa) + 88 | tm_symbols(fill = "y", fill.scale = tm_scale_continuous_log()) 89 | ``` 90 | 91 | 92 | 93 | 94 | 95 | 96 | ```{r} 97 | tm_shape(Africa) + 98 | tm_symbols(fill = "gdp_cap_est", fill.scale = tm_scale_continuous_log1p()) 99 | ``` 100 | 101 | 102 | ```{r} 103 | tm_shape(Africa) + 104 | tm_symbols(fill = "gdp_cap_est", fill.scale = tm_scale_continuous_log()) 105 | ``` 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | # This file is part of the standard setup for testthat. 2 | # It is recommended that you do not modify it. 3 | # 4 | # Where should you do additional test configuration? 5 | # Learn more about the roles of various files in: 6 | # * https://r-pkgs.org/testing-design.html#sec-tests-files-overview 7 | # * https://testthat.r-lib.org/articles/special-files.html 8 | 9 | library(testthat) 10 | library(tmap) 11 | 12 | test_check("tmap") 13 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/terra-stars.md: -------------------------------------------------------------------------------- 1 | # terra works 2 | 3 | Code 4 | tm_shape(land_terra) + tm_raster("treess") 5 | Condition 6 | Error in `tm_raster()`: 7 | ! Visual values used for the variable "col" are incorrect. 8 | i Variable should a data variable name or a single color. 9 | 10 | -------------------------------------------------------------------------------- /tests/testthat/test-tm_components.R: -------------------------------------------------------------------------------- 1 | test_that("tm_title works (#796)", { 2 | skip_on_cran() 3 | a_line <- matrix(c(0, 0, 1, 1), ncol = 2, byrow = TRUE) %>% 4 | sf::st_linestring() %>% 5 | sf::st_sfc() %>% 6 | sf::st_sf(crs = 4326) 7 | 8 | expect_no_warning({ 9 | tm_shape(a_line) + 10 | tm_lines() + 11 | tm_title(text = "A line") 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /tests/testthat/test-tm_layers_polygons.R: -------------------------------------------------------------------------------- 1 | test_that("tm_borders work", { 2 | # Borders only 3 | map <- tm_shape(World) + tm_borders() 4 | map 5 | expect_equal(map[[1]]$shp_name, "World") 6 | }) 7 | -------------------------------------------------------------------------------- /tests/testthat/test-tm_lines.R: -------------------------------------------------------------------------------- 1 | test_that("It is possible to combine two visual elements into single legend", { 2 | break_values <- c(-Inf, 2, 4, 6, 8, Inf) 3 | color_values <- c("#B4D79E", "#98E600", "#FFAA00", "#FF5500", "#A80000") 4 | size_values <- c(0.5, 1, 2, 3, 5) 5 | expect_no_error({ 6 | tm_shape(World_rivers) + 7 | tm_lines( 8 | col = "strokelwd", 9 | col.scale = tm_scale_intervals(values = color_values, breaks = break_values), 10 | lwd = "strokelwd", 11 | lwd.scale = tm_scale_intervals(values = size_values, breaks = break_values), 12 | lwd.legend = tm_legend_combine("col"), 13 | plot.order = tm_plot_order("lwd", reverse = FALSE, na.order = "bottom") 14 | ) + 15 | tm_layout(legend.show = TRUE) 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /tests/testthat/test-tm_scale.R: -------------------------------------------------------------------------------- 1 | test_that("tm_scale() works", { 2 | skip_on_cran() 3 | expect_no_error( 4 | tm_world <- World |> 5 | tm_shape() + 6 | tm_fill( 7 | fill = "area", 8 | fill.scale = tm_scale_continuous_pseudo_log() 9 | ) 10 | ) 11 | expect_no_error(tm_world) 12 | expect_no_error(tmap_leaflet(tm_world) |> 13 | addLayersControl( 14 | baseGroups = "area", 15 | options = layersControlOptions( 16 | collapsed = FALSE 17 | ) 18 | ) 19 | ) 20 | 21 | }) 22 | 23 | test_that("tm_scale_continuous_pseudo_log() works with special words", { 24 | skip_on_cran() 25 | expect_no_error( 26 | tm_world <- World |> 27 | tm_shape() + 28 | tm_fill( 29 | fill = "MAP_COLORS", 30 | fill.scale = tm_scale_continuous_pseudo_log() 31 | ) 32 | ) 33 | expect_no_error(tm_world) 34 | mod <- tmap_mode("view") 35 | expect_no_error(tm_world) 36 | tmap_mode(mod) 37 | }) 38 | -------------------------------------------------------------------------------- /tests/testthat/test-tmap_mode.R: -------------------------------------------------------------------------------- 1 | test_that("tmap_mode is plot by default.", { 2 | skip_on_cran() 3 | expect_message(tmap_mode(), "Current tmap mode is \"plot\"") 4 | }) 5 | -------------------------------------------------------------------------------- /tmap.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | ProjectId: f568fa6e-4863-4e59-97f3-38c6f60bdd0c 3 | 4 | RestoreWorkspace: Default 5 | SaveWorkspace: Default 6 | AlwaysSaveHistory: Default 7 | 8 | EnableCodeIndexing: Yes 9 | UseSpacesForTab: No 10 | NumSpacesForTab: 4 11 | Encoding: UTF-8 12 | 13 | RnwWeave: knitr 14 | LaTeX: pdfLaTeX 15 | 16 | AutoAppendNewline: Yes 17 | StripTrailingWhitespace: Yes 18 | 19 | BuildType: Package 20 | PackageUseDevtools: Yes 21 | PackageInstallArgs: --no-multiarch 22 | PackageRoxygenize: rd,collate,namespace 23 | 24 | SpellingDictionary: en_US 25 | -------------------------------------------------------------------------------- /vignettes/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.R 3 | -------------------------------------------------------------------------------- /vignettes/examples_gridmaps.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "tmap example: gridmaps" 3 | output: 4 | bookdown::html_vignette2: 5 | pkgdown: 6 | as_is: true 7 | template: 8 | math-rendering: mathjax 9 | bibliography: '`r system.file("tmap.bib", package="tmap")`' 10 | csl: "`r system.file('ieee.csl', package = 'tmap')`" 11 | editor_options: 12 | chunk_output_type: console 13 | --- 14 | 15 | ```{r, include = FALSE} 16 | knitr::opts_chunk$set( 17 | collapse = TRUE, 18 | out.width = "100%", 19 | dpi = 300, 20 | fig.width = 7.2916667, 21 | comment = "#>" 22 | ) 23 | hook_output <- knitr::knit_hooks$get("output") 24 | knitr::knit_hooks$set(output = function(x, options) { 25 | lines <- options$output.lines 26 | if (is.null(lines)) { 27 | return(hook_output(x, options)) # pass to default hook 28 | } 29 | x <- unlist(strsplit(x, "\n")) 30 | more <- "..." 31 | if (length(lines)==1) { # first n lines 32 | if (length(x) > lines) { 33 | # truncate the output, but add .... 34 | x <- c(head(x, lines), more) 35 | } 36 | } else { 37 | x <- c(more, x[lines], more) 38 | } 39 | # paste these lines together 40 | x <- paste(c(x, ""), collapse = "\n") 41 | hook_output(x, options) 42 | }) 43 | 44 | ``` 45 | 46 | ```{r, message = FALSE} 47 | library(tmap) 48 | library(geofacet) 49 | library(dplyr) 50 | library(sf) 51 | tmap_options(scale = 0.75) 52 | ``` 53 | 54 | 55 | ## Get grid layout of Dutch provinces 56 | 57 | ```{r} 58 | nl_prov_grid1 = geofacet::nl_prov_grid1 59 | class(nl_prov_grid1) = "data.frame" 60 | 61 | nl_prov_grid1 = nl_prov_grid1 |> 62 | mutate(name = ifelse(name == "Friesland", "Fryslan", name)) |> 63 | select(-code) 64 | ``` 65 | 66 | 67 | ## Join with NLD datasets in tmap 68 | 69 | ```{r} 70 | NLD_prov2 = NLD_prov |> 71 | left_join(nl_prov_grid1, 72 | by = "name") 73 | 74 | NLD_muni2 = NLD_muni |> 75 | left_join(NLD_prov2 |> 76 | st_drop_geometry() |> 77 | select(name, row, col), by = c("province" = "name")) 78 | 79 | NLD_dist2 = NLD_dist |> 80 | left_join(NLD_prov2 |> 81 | st_drop_geometry() |> 82 | select(name, row, col), by = c("province" = "name")) 83 | ``` 84 | 85 | ## The map 86 | 87 | ```{r, fig.height = 9} 88 | tm_shape(NLD_dist2) + 89 | tm_fill("dwelling_value", 90 | fill.scale = tm_scale_intervals(breaks = c(50, 250, 350, 500, 750, 1600), as.count = FALSE), 91 | fill.legend = tm_legend("", position = tm_pos_on_top("left", "top"), frame = FALSE)) + 92 | tm_facets_grid(rows = "row", columns = "col") + 93 | tm_shape(NLD_muni2) + 94 | tm_borders(lwd = 1) + 95 | tm_facets_grid(rows = "row", columns = "col") + 96 | tm_shape(NLD_prov2) + 97 | tm_borders(lwd = 2) + 98 | tm_facets_grid(rows = "row", columns = "col") + 99 | tm_layout(panel.show = FALSE) + 100 | tm_title("Average dwelling value (in thousand Euros)") 101 | ``` 102 | 103 | -------------------------------------------------------------------------------- /vignettes/examples_terrain.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "tmap example: terrain map" 3 | output: 4 | bookdown::html_vignette2: 5 | pkgdown: 6 | as_is: true 7 | template: 8 | math-rendering: mathjax 9 | bibliography: '`r system.file("tmap.bib", package="tmap")`' 10 | csl: "`r system.file('ieee.csl', package = 'tmap')`" 11 | editor_options: 12 | chunk_output_type: console 13 | --- 14 | 15 | ```{r, include = FALSE} 16 | knitr::opts_chunk$set( 17 | collapse = TRUE, 18 | out.width = "100%", 19 | dpi = 300, 20 | fig.width = 7.2916667, 21 | comment = "#>" 22 | ) 23 | hook_output <- knitr::knit_hooks$get("output") 24 | knitr::knit_hooks$set(output = function(x, options) { 25 | lines <- options$output.lines 26 | if (is.null(lines)) { 27 | return(hook_output(x, options)) # pass to default hook 28 | } 29 | x <- unlist(strsplit(x, "\n")) 30 | more <- "..." 31 | if (length(lines)==1) { # first n lines 32 | if (length(x) > lines) { 33 | # truncate the output, but add .... 34 | x <- c(head(x, lines), more) 35 | } 36 | } else { 37 | x <- c(more, x[lines], more) 38 | } 39 | # paste these lines together 40 | x <- paste(c(x, ""), collapse = "\n") 41 | hook_output(x, options) 42 | }) 43 | 44 | ``` 45 | 46 | ```{r, message = FALSE} 47 | library(tmap) 48 | library(dplyr) 49 | library(sf) 50 | tmap_options(scale = 0.75) 51 | ``` 52 | 53 | 54 | ## About the data 55 | 56 | We use a couple of spatial data objects contained in tmap: `World_rivers`, `land` and `metro`. 57 | 58 | ## Terrain map 59 | 60 | ```{r, fig.height = 4} 61 | tm_shape(land) + 62 | tm_raster(col = "cover") + 63 | #tm_shape(World) + 64 | # tm_borders() + 65 | tm_shape(World_rivers) + 66 | tm_lines(lwd = "strokelwd", 67 | lwd.scale = tm_scale_asis(values.scale = 0.2)) + 68 | tm_shape(metro) + 69 | tm_symbols(shape = 20, size = 0.6, fill = "white") + 70 | tm_symbols(shape = 20, size = 0.5, fill = "red") + 71 | tm_crs("+proj=eck4") + 72 | tm_layout(earth_boundary = TRUE, 73 | earth_boundary.lwd = 2, 74 | legend.show = FALSE, # option to disable all legends 75 | frame = FALSE, 76 | space.color = "white") + 77 | tm_title("Map of the World", 78 | position = tm_pos_out(cell.h = "center", cell.v = "top", pos.h = "center")) + 79 | tm_credits("Eckert IV projection", position = c("RIGHT", "BOTTOM")) 80 | ``` 81 | 82 | Note: upper case position spefications (last line) means tight to the right bottom corner 83 | 84 | ## Classic style 85 | 86 | ```{r, fig.height = 4} 87 | tmap_style("classic") 88 | tmap_last() 89 | ``` 90 | -------------------------------------------------------------------------------- /vignettes/ext_networks.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "tmap extensions: tmap.networks" 3 | output: 4 | bookdown::html_vignette2: 5 | bibliography: '`r system.file("tmap.bib", package="tmap")`' 6 | csl: "`r system.file('ieee.csl', package = 'tmap')`" 7 | editor_options: 8 | chunk_output_type: console 9 | --- 10 | 11 | ```{r, include = FALSE} 12 | knitr::opts_chunk$set( 13 | collapse = TRUE, 14 | fig.width = 8, 15 | comment = "#>" 16 | ) 17 | hook_output <- knitr::knit_hooks$get("output") 18 | knitr::knit_hooks$set(output = function(x, options) { 19 | lines <- options$output.lines 20 | if (is.null(lines)) { 21 | return(hook_output(x, options)) # pass to default hook 22 | } 23 | x <- unlist(strsplit(x, "\n")) 24 | more <- "..." 25 | if (length(lines)==1) { # first n lines 26 | if (length(x) > lines) { 27 | # truncate the output, but add .... 28 | x <- c(head(x, lines), more) 29 | } 30 | } else { 31 | x <- c(more, x[lines], more) 32 | } 33 | # paste these lines together 34 | x <- paste(c(x, ""), collapse = "\n") 35 | hook_output(x, options) 36 | }) 37 | 38 | ``` 39 | 40 | 41 | ```{r, echo = FALSE, message = FALSE} 42 | library(tmap) 43 | library(tmap.networks) 44 | tmap_options(scale = 0.75) 45 | ``` 46 | 47 | With [**tmap.networks**](https://r-tmap.github.io/tmap.networks/) network visualizations can be made. It will handle `sfnetwork` objects (from the package [sfnetworks](https://luukvdmeer.github.io/sfnetworks/index.html)) natively. 48 | 49 | ```{r} 50 | library(sfnetworks) 51 | library(tmap.networks) 52 | 53 | (sfn = as_sfnetwork(roxel)) 54 | ``` 55 | 56 | Besides this new spatial data class `"sfnetwork"`, this package also features new map layers, albeit very basic so far: 57 | 58 | ```{r, fig.height = 8, out.width = "100%", dpi = 300, fig.width = 7.2916667} 59 | tm_shape(sfn) + 60 | tm_network() 61 | ``` 62 | 63 | ```{r, fig.height = 8, out.width = "100%", dpi = 300, fig.width = 7.2916667} 64 | tm_shape(sfn) + 65 | tm_edges(col = "type", lwd = 4) + 66 | tm_nodes() 67 | ``` 68 | -------------------------------------------------------------------------------- /vignettes/figures/shiny_plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/vignettes/figures/shiny_plot.png -------------------------------------------------------------------------------- /vignettes/figures/shiny_view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-tmap/tmap/e87194a50e8744364387bd1c8d49585a4f91583f/vignettes/figures/shiny_view.png -------------------------------------------------------------------------------- /vignettes/versus_mapview.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "tmap versus: mapview" 3 | output: 4 | bookdown::html_vignette2: 5 | bibliography: '`r system.file("tmap.bib", package="tmap")`' 6 | csl: "`r system.file('ieee.csl', package = 'tmap')`" 7 | editor_options: 8 | chunk_output_type: console 9 | --- 10 | 11 | ```{r, include = FALSE} 12 | knitr::opts_chunk$set( 13 | collapse = TRUE, 14 | fig.width = 8, 15 | comment = "#>" 16 | ) 17 | ``` 18 | 19 | 20 | ```{r, echo = FALSE, message = FALSE} 21 | library(tmap) 22 | ``` 23 | 24 | ## Mapview 25 | 26 | Mapview is an excellent R package for interactive maps. Although the packages have a lot in common, the focus is different: 27 | 28 | * tmap focusses on thematic mapping with a syntax that is based on the [grammar of graphics](11_foundations_gg) and is therefore popular for education purposes; 29 | * mapview focuses on fast exploration of spatial data and has more interactive features. 30 | 31 | ## Modes / platforms 32 | 33 | * tmap offers two modes: "plot" and "view" (but is extendable, see https://github.com/r-tmap/tmap.deckgl). 34 | * mapview supports three modes, which they call *platforms*: "leaflet", "leafgl", and "mapdeck". 35 | 36 | tmap "view" (with `tm_view(use_WebGL = FALSE)`) is similar to mapview "leaflet" 37 | tmap "view" (with `tm_view(use_WebGL = TRUE)`) is similar to mapview "leafgl" 38 | 39 | tmap does not offer a mode using Mapbox yet. 40 | 41 | ## Default maps 42 | 43 | This is the default output of `mapview`: 44 | 45 | ```{r} 46 | library(mapview) 47 | mapview(World) 48 | ``` 49 | 50 | 51 | This is the default output of `tmap`: 52 | 53 | ```{r} 54 | tmap_mode("view") 55 | qtm(World) # qtm stands for 'quick thematic map' 56 | ``` 57 | 58 | 59 | ## Choropleth 60 | 61 | ```{r} 62 | mapview(World, zcol = "HPI") 63 | ``` 64 | 65 | ```{r} 66 | tm_shape(World) + 67 | tm_polygons(fill = "HPI") 68 | ``` 69 | 70 | ## Mimicking mapview layout 71 | 72 | We can use `tmap` to match the style of `mapview`: 73 | 74 | ```{r} 75 | tm_shape(World) + 76 | tm_polygons( 77 | fill = "HPI", 78 | fill_alpha = 0.6, 79 | col_alpha = 0.9, 80 | fill.legend = tm_legend( 81 | title = "World - HPI", 82 | position = c("right", "top"), 83 | fill_alpha = 1), 84 | fill.scale = tm_scale_continuous(values = "viridis", n = 7, value.na = "#BEBEBE") 85 | ) + 86 | tm_basemap(c("CartoDB.Positron", "CartoDB.DarkMatter", 87 | "OpenStreetMap", "Esri.WorldImagery", "OpenTopoMap")) 88 | ``` 89 | --------------------------------------------------------------------------------