diff --git a/NEWS.md b/NEWS.md index e64db791..10cef774 100644 --- a/NEWS.md +++ b/NEWS.md @@ -12,8 +12,10 @@ * New family of functions `tm_chart_*()` to do charting (See `?tm_chart`) (#581) +* New [vignettes](https://r-tmap.github.io/tmap/articles/) available to explain how to upgrade your code to tmap v4 + # tmap 3.3-4 -- (!) last version of tmap 3.x. Next CRAN version will be tmap 4.x (release planned at the end of 2023) +- (!) last version of tmap 3.x. Next CRAN version will be tmap 4.x - fixed bug (some stars appeared upside down in plot mode) - fixed newly introduced shiny bug (#767) @@ -48,7 +50,7 @@ - interactive maps in origin CRS working: `tmap_options(projection = 0, basemaps = NULL)` - added `tm_mouse_coordinates()` to show mouse coordinates in view mode - added `tmap_design_mode()` to toggle the design mode. -- made backgrond symbol grob shapes transparent +- made background symbol grob shapes transparent - added in.iframe and `selfcontained` to `tmap_save()` - improved `tm_add_legend()`: added `type = "title"` for title only legend elements - added `ttmp()` which shows the last map in the other mode. diff --git a/R/messages.R b/R/messages.R index cea0806a..8aeef30a 100644 --- a/R/messages.R +++ b/R/messages.R @@ -14,8 +14,12 @@ message_reg = function(id) { message_comp_scale = function() { if (!message_thrown("comp_scale")) { - cli::cli_inform("{.field [plot mode]} fit legend/component: Some legend items or map compoments do not fit well, and are therefore rescaled. Set the tmap option 'component.autoscale' to FALSE to disable rescaling.", - .frequency_id = "comp_scale") + cli::cli_inform(c( + "{.field [plot mode]} fit legend/component: Some legend items or map compoments do not fit well, and are therefore rescaled.", + i = "Set the tmap option {.code component.autoscale = FALSE} to disable rescaling." + ), + .frequency_id = "comp_scale" + ) message_reg("comp_scale") } NULL @@ -23,8 +27,12 @@ message_comp_scale = function() { message_comp_high_wide = function(stack) { if (!message_thrown("comp_scale")) { - cli::cli_inform("{.field [plot mode]} legend/component: Some components or legends are too {.val ifelse(stack == 'vertical', 'high', 'wide')} and are therefore rescaled. Set the tmap option {.code component.autoscale} to {.code FALSE} to disable rescaling.", - .frequency_id = "comp_scale") + cli::cli_inform(c( + "{.field [plot mode]} legend/component: Some components or legends are too {.val {ifelse(stack == 'vertical', 'high', 'wide')}} and are therefore rescaled.", + "i" = "Set the tmap option {.code component.autoscale = FALSE} to disable rescaling." + ), + .frequency_id = "comp_scale" + ) message_reg("comp_scale") } NULL @@ -54,7 +62,7 @@ message_c4a = function(old_palette_name, info, fullname = FALSE) { message_nothing_to_show = function(any_groups) { if (any_groups) { - cli::cli_inform("{.field [nothing to show]} no data layers defined after {.code tm_shape}", + cli::cli_inform("{.field [nothing to show]} no data layers defined after {.fn tm_shape}", .frequency_id = "nothing") } else { cli::cli_inform("{.field [nothing to show]} no data layers defined", @@ -65,9 +73,9 @@ message_nothing_to_show = function(any_groups) { message_wrapstack = function(horizontal = TRUE) { if (horizontal) { - cli::cli_inform("{.field [facets]} use {.code tm_facets_hstack()} instead of {.code tm_facets_wrap()} to put the legends next to and aligned with the facets") + cli::cli_inform("{.field [facets]} use {.fn tm_facets_hstack} instead of {.fn tm_facets_wrap} to put the legends next to and aligned with the facets.") } else { - cli::cli_inform("{.field [facets]} use {.code tm_facets_vstack()} instead of {.code tm_facets_wrap()} to put the legends next to and aligned with the facets") + cli::cli_inform("{.field [facets]} use {.fn tm_facets_vstack} instead of {.fn tm_facets_wrap} to put the legends next to and aligned with the facets.") } NULL } @@ -76,13 +84,16 @@ message_pos_auto = function(type) { if (!message_thrown("pos_auto")) { fun = if (type == "autoout") "tm_pos_auto_out()" else "tm_pos_auto_in()" fun2 = if (type == "autoout") "tm_pos_out()" else "tm_pos_in()" - cli::cli_inform("{.field [position]} use {.val fun2} instead of {.val fun}. The latter should be used with {.code tmap_options()}.") + cli::cli_inform("{.field [position]} use {.val {fun2}} instead of {.val {fun}}. The latter should be used with {.fn tmap_options}.") message_reg("pos_auto") } NULL } error_dimvalues = function() { - stop("tm_vars(): \"dimvalues\" has been used, but the shape object does not contain any dimensions; please use \"x\" to specify variables", call. = FALSE) + cli::cli_abort( + "{.val dimvalues} has been used, but the shape object does not contain any dimensions; please use {.arg x} to specify variables", + call = call("tm_vars") + ) } diff --git a/R/messages_v4_v3.R b/R/messages_v4_v3.R index 323fd7be..48bcbf71 100644 --- a/R/messages_v4_v3.R +++ b/R/messages_v4_v3.R @@ -168,7 +168,7 @@ v3_list_get = function() { v3_impute = function(args, name, value, new_name = name) { if (name %in% names(args)) { res = args[[name]] - if (is.list(res) && length(grep("format", name, fixed =TRUE)) == 0 && !is.list(res[[1]])) { + if (is.list(res) && !grepl("format", name, fixed = TRUE) && !is.list(res[[1]])) { res = res[[1]] mult = TRUE } else if (new_name %in% c("title", "na.show", "orientation", "reverse", "interval.closure", "drop.levels", "midpoint", "as.count", "values.repeat", "values.scale", "value.na", "value.null", "value.neutral", "label.na", "label.null")) { diff --git a/R/misc_other.R b/R/misc_other.R index 2f18eecb..1c656ffc 100644 --- a/R/misc_other.R +++ b/R/misc_other.R @@ -164,7 +164,7 @@ get_asp_ratio = function (x, width = 700, height = 700, res = 100) { # get aspect ratios of a list of bounding boxes get_asp = function(bbxl) { vapply(bbxl, function(bbxi) { - if (is.na(bbxi)) as.numeric(NA) else get_asp_ratio(bbxi) + if (is.na(bbxi)) NA_real_ else get_asp_ratio(bbxi) }, FUN.VALUE = numeric(1)) } diff --git a/R/process_meta.R b/R/process_meta.R index 0b588062..a9f1228c 100644 --- a/R/process_meta.R +++ b/R/process_meta.R @@ -578,12 +578,12 @@ process_meta = function(o, d, cdt, aux) { legend.position = NA - if (!is.logical(set.bounds)) if (!length(set.bounds)==4 || !is.numeric(set.bounds)) stop("Incorrect set_bounds argument", call.=FALSE) + if (!is.logical(set.bounds)) if (length(set.bounds) !=4 || !is.numeric(set.bounds)) stop("Incorrect set_bounds argument", call.=FALSE) if (!is.na(set.view[1])) { if (!is.numeric(set.view)) stop("set.view is not numeric") - if (!length(set.view) %in% c(1,3)) stop("set.view does not have length 1 or 3") + if (!length(set.view) %in% c(1, 3)) stop("set.view does not have length 1 or 3") } if (!is.na(set.zoom.limits[1])) { if (!is.numeric(set.zoom.limits)) stop("set.zoom.limits is not numeric") diff --git a/R/shapeTM.R b/R/shapeTM.R index cb73942f..0bfa1f4a 100644 --- a/R/shapeTM.R +++ b/R/shapeTM.R @@ -45,7 +45,7 @@ stm_bbox = function(shpTM, tmapID, crs) { shp = shpTM$shp shpID = shpTM$tmapID - if (length(tmapID) ==0 ) return(sf::st_bbox(as.numeric(NA))) + if (length(tmapID) == 0) return(sf::st_bbox(NA_real_)) # filter the shape? do_filter = (length(tmapID) != length(shpID)) || (!all(tmapID == shpID)) @@ -119,5 +119,3 @@ bb_ll_valid = function(bbx) { bbx[4] = min(bbx[4], 90) bbx } - - diff --git a/R/step1_helper_facets.R b/R/step1_helper_facets.R index ee0ba712..e19db584 100644 --- a/R/step1_helper_facets.R +++ b/R/step1_helper_facets.R @@ -155,7 +155,9 @@ step1_rearrange_facets = function(tmo, o) { vars = shpvars[value$x] } } else if (!is.na(value$n)) { - if (length(shpvars) < value$n) stop("tm_vars defined for n = ", value$n, " while there are only ", length(shpvars), " variables", call. = FALSE) + if (length(shpvars) < value$n) { + stop("tm_vars defined for n = ", value$n, " while there are only ", length(shpvars), " variables", call. = FALSE) + } vars = shpvars[1L:value$n] } else { vars = shpvars diff --git a/R/step4_plot.R b/R/step4_plot.R index bee98368..93fd1094 100644 --- a/R/step4_plot.R +++ b/R/step4_plot.R @@ -19,7 +19,7 @@ process_components = function(cdt, o) { cdt$cell.v = sapply(cdt$comp, function(l) {x = l$position$cell.v; if (is.null(x)) NA else x}) cdt$pos.h = sapply(cdt$comp, function(l) {x = l$position$pos.h; if (is.null(x)) NA else x}) cdt$pos.v = sapply(cdt$comp, function(l) {x = l$position$pos.v; if (is.null(x)) NA else x}) - cdt$z = sapply(cdt$comp, function(l) {x = l$z; if (is.null(x)) as.integer(NA) else x}) + cdt$z = sapply(cdt$comp, function(l) {x = l$z; if (is.null(x)) NA_integer_ else x}) # to make sure legends positions are based on one-facet-per-page if (o$type == "page") { @@ -115,7 +115,7 @@ process_components = function(cdt, o) { # # } - #cdt[, page := as.integer(NA)] + #cdt[, page := NA_integer_] cdt @@ -261,9 +261,9 @@ step4_plot = function(tm, vp, return.asp, show, in.shiny, knit, args) { cdt_cmp = if (length(cmp) && !o$legend.only) { data.table::rbindlist(lapply(cmp, function(cp) { - data.table::data.table(by1__ = as.integer(NA), - by2__ = as.integer(NA), - by3__ = as.integer(NA), + data.table::data.table(by1__ = NA_integer_, + by2__ = NA_integer_, + by3__ = NA_integer_, comp = list(cp)) })) } else { @@ -474,8 +474,8 @@ step4_plot = function(tm, vp, return.asp, show, in.shiny, knit, args) { if (o$panel.type != "none") { cdt = rbindlist(c(list(cdt), mapply(function(lab, i) { data.table::data.table(by1__ = i, - by2__ = as.integer(NA), - by3__ = as.integer(NA), + by2__ = NA_integer_, + by3__ = NA_integer_, comp = list(impute_comp(tm_title(lab)[[1]], o)), class= "in", cell.h = NA, @@ -483,8 +483,8 @@ step4_plot = function(tm, vp, return.asp, show, in.shiny, knit, args) { pos.h = "left", pos.v = "top", z = 1, - facet_row = as.character(NA), - facet_col = as.character(NA), + facet_row = NA_character_, + facet_col = NA_character_, stack_auto = TRUE, stack = "vertical", legW = 0, @@ -765,7 +765,7 @@ step4_plot = function(tm, vp, return.asp, show, in.shiny, knit, args) { } legs_out = copy(cdt[!is_in]) - legs_out[, page:=as.integer(NA)] + legs_out[, page:=NA_integer_] # legs_out[, bbox:=list()] # legs_out[, units:=list()] diff --git a/R/tm_add_legend.R b/R/tm_add_legend.R index 1819dd98..50799ebf 100644 --- a/R/tm_add_legend.R +++ b/R/tm_add_legend.R @@ -31,8 +31,8 @@ tm_add_legend = function(..., group = NA, group.control = "check", resize.as.group = FALSE, - z = as.integer(NA)) { - if (missing(labels)) stop("tm_add_legend: labels required", call. = FALSE) + z = NA_integer_) { + rlang::check_required(labels) args = lapply(as.list(rlang::call_match(defaults = TRUE)[-1]), eval, envir = parent.frame()) diff --git a/R/tm_chart.R b/R/tm_chart.R index fc7c9dfb..0db36384 100644 --- a/R/tm_chart.R +++ b/R/tm_chart.R @@ -31,7 +31,7 @@ tm_chart_histogram = function(breaks, args = lapply(as.list(rlang::call_match()[-1]), eval, envir = parent.frame()) - if (!("z" %in% (names(args)))) args$z = as.integer(NA) + if (!("z" %in% (names(args)))) args$z = NA_integer_ args$show = TRUE args$type = "histogram" args$summary = "binned" @@ -40,19 +40,19 @@ tm_chart_histogram = function(breaks, #' @rdname tm_chart #' @export -tm_chart_bar = function( plot.axis.x, - plot.axis.y, - extra.ggplot2, - position, - width, - height, - stack, - z, - group.frame, - resize.as.group) { +tm_chart_bar = function(plot.axis.x, + plot.axis.y, + extra.ggplot2, + position, + width, + height, + stack, + z, + group.frame, + resize.as.group) { args = lapply(as.list(rlang::call_match()[-1]), eval, envir = parent.frame()) - if (!("z" %in% (names(args)))) args$z = as.integer(NA) + if (!("z" %in% (names(args)))) args$z = NA_integer_ args$show = TRUE args$type = "bar" args$summary = "binned" @@ -63,15 +63,15 @@ tm_chart_bar = function( plot.axis.x, #' @rdname tm_chart #' @export tm_chart_donut = function(position, - width, - height, - stack, - z, - group.frame, - resize.as.group) { + width, + height, + stack, + z, + group.frame, + resize.as.group) { args = lapply(as.list(rlang::call_match()[-1]), eval, envir = parent.frame()) - if (!("z" %in% (names(args)))) args$z = as.integer(NA) + if (!("z" %in% (names(args)))) args$z = NA_integer_ args$show = TRUE args$type = "donut" args$summary = "binned" @@ -89,7 +89,7 @@ tm_chart_violin = function(position, resize.as.group) { args = lapply(as.list(rlang::call_match()[-1]), eval, envir = parent.frame()) - if (!("z" %in% (names(args)))) args$z = as.integer(NA) + if (!("z" %in% (names(args)))) args$z = NA_integer_ args$show = TRUE args$type = "violin" args$summary = "raw_nna" @@ -99,15 +99,15 @@ tm_chart_violin = function(position, #' @rdname tm_chart #' @export tm_chart_box = function(position, - width, - height, - stack, - z, - group.frame, - resize.as.group) { + width, + height, + stack, + z, + group.frame, + resize.as.group) { args = lapply(as.list(rlang::call_match()[-1]), eval, envir = parent.frame()) - if (!("z" %in% (names(args)))) args$z = as.integer(NA) + if (!("z" %in% (names(args)))) args$z = NA_integer_ args$show = TRUE args$type = "box" args$summary = "raw_nna" @@ -125,15 +125,15 @@ tm_chart_none = function() { #' @rdname tm_chart #' @export tm_chart_heatmap = function(position, - width, - height, - stack, - z, - group.frame, - resize.as.group) { + width, + height, + stack, + z, + group.frame, + resize.as.group) { args = lapply(as.list(rlang::call_match()[-1]), eval, envir = parent.frame()) - if (!("z" %in% (names(args)))) args$z = as.integer(NA) + if (!("z" %in% (names(args)))) args$z = NA_integer_ args$show = TRUE args$type = "heatmap" args$summary = "binned2D" diff --git a/R/tm_components.R b/R/tm_components.R index f2b299d7..24985906 100644 --- a/R/tm_components.R +++ b/R/tm_components.R @@ -23,7 +23,7 @@ #' @export tm_title = function(text, size, color, padding, fontface, fontfamily, stack, just, frame, frame.lwd, frame.r, bg.color, bg.alpha, position, width, height, group.frame, resize.as.group, z) { args = lapply(as.list(rlang::call_match()[-1]), eval, envir = parent.frame()) - if (!("z" %in% names(args))) args$z = as.integer(NA) + if (!("z" %in% names(args))) args$z = NA_integer_ tm_element_list(do.call(tm_element, c(args, list(subclass = c("tm_title", "tm_component"))))) } @@ -32,7 +32,7 @@ tm_title = function(text, size, color, padding, fontface, fontfamily, stack, jus #' @rdname tm_title tm_title_in = function(text, ..., position = tm_pos_in("left", "top")) { args = lapply(as.list(rlang::call_match()[-1]), eval, envir = parent.frame()) - if (!("z" %in% names(args))) args$z = as.integer(NA) + if (!("z" %in% names(args))) args$z = NA_integer_ args$position = position tm_element_list(do.call(tm_element, c(args, list(subclass = c("tm_title", "tm_component" ))))) @@ -43,7 +43,7 @@ tm_title_in = function(text, ..., position = tm_pos_in("left", "top")) { #' @name tm_title_in tm_title_out = function(text, ..., position = tm_pos_out("center", "top")) { args = lapply(as.list(rlang::call_match()[-1]), eval, envir = parent.frame()) - if (!("z" %in% names(args))) args$z = as.integer(NA) + if (!("z" %in% names(args))) args$z = NA_integer_ args$position = position tm_element_list(do.call(tm_element, c(args, list(subclass = c("tm_title", "tm_component" ))))) @@ -81,7 +81,7 @@ tm_title_out = function(text, ..., position = tm_pos_out("center", "top")) { #' @export tm_credits = function(text, size, color, padding, fontface, fontfamily, stack, just, frame, frame.lwd, frame.r, bg.color, bg.alpha, position, width, height, group.frame, resize.as.group, z) { args = lapply(as.list(rlang::call_match()[-1]), eval, envir = parent.frame()) - if (!("z" %in% names(args))) args$z = as.integer(NA) + if (!("z" %in% names(args))) args$z = NA_integer_ tm_element_list(do.call(tm_element, c(args, list(subclass = c("tm_credits", "tm_component"))))) } @@ -132,7 +132,7 @@ tm_compass <- function(north, margins, z) { args = lapply(as.list(rlang::call_match()[-1]), eval, envir = parent.frame()) - if (!("z" %in% names(args))) args$z = as.integer(NA) + if (!("z" %in% names(args))) args$z = NA_integer_ tm_element_list(do.call(tm_element, c(args, list(subclass = c("tm_compass", "tm_component"))))) } @@ -185,7 +185,7 @@ tm_scalebar = function(breaks, } args = lapply(as.list(rlang::call_match()[-1]), eval, envir = parent.frame()) - if (!("z" %in% names(args))) args$z = as.integer(NA) + if (!("z" %in% names(args))) args$z = NA_integer_ tm_element_list(do.call(tm_element, c(args, list(subclass = c("tm_scalebar", "tm_component"))))) } @@ -195,10 +195,10 @@ tm_scalebar = function(breaks, #' @inheritDotParams tm_scalebar #' @export tm_scale_bar = function(...) { - message("As of version 4.0, 'tm_scale_bar()' is deprecated. Please use 'tm_scalebar()' instead.", call. = FALSE) + cli::cli_inform(c( + "{.fn tm_scale_bar} is deprecated. Please use {.fn tm_scalebar()} instead." + )) tm_scalebar(...) - # can also be - # stop("As of version 4.0, tm_scale_bar has been renamed to tm_scalebar and is therefore deprecated. tm_scalebar also has new argument names.", call. = FALSE) } #' Map component: mouse coordinates @@ -213,7 +213,7 @@ tm_mouse_coordinates <- function(stack, position, z) { args = lapply(as.list(rlang::call_match()[-1]), eval, envir = parent.frame()) - if (!("z" %in% names(args))) args$z = as.integer(NA) + if (!("z" %in% names(args))) args$z = NA_integer_ tm_element_list(do.call(tm_element, c(args, list(subclass = c("tm_mouse_coordinates", "tm_component"))))) } @@ -237,7 +237,7 @@ tm_minimap <- function(server, z, ...) { args = lapply(as.list(rlang::call_match()[-1]), eval, envir = parent.frame()) - if (!("z" %in% names(args))) args$z = as.integer(NA) + if (!("z" %in% names(args))) args$z = NA_integer_ tm_element_list(do.call(tm_element, c(args, list(subclass = c("tm_minimap", "tm_component"))))) } @@ -248,8 +248,10 @@ tm_minimap <- function(server, #' used instead of `tm_scale_bar()` (now deprecated), because of the potential #' confusion with the `tm_scale_*()` scaling functions (like [tm_scale_continuous()]). #' -#' @param file either a filename or url of a png image. If multiple files/urls are provided with a character vector, the logos are placed near each other. To specify logos for small multiples use a list of character values/vectors. In order to stack logos vertically, multiple \code{tm_logo} elements can be stacked. -#' @param height height of the logo in number of text line heights. The width is scaled based the height and the aspect ratio of the logo. If multiple logos are specified by a vector or list, the heights can be specified accordingly. +#' @param file either a filename or url of a png image. If multiple files/urls are provided with a character vector, the logos are placed near each other. +#' To specify logos for small multiples use a list of character values/vectors. In order to stack logos vertically, multiple \code{tm_logo} elements can be stacked. +#' @param height height of the logo in number of text line heights. The width is scaled based the height and the aspect ratio of the logo. +#' If multiple logos are specified by a vector or list, the heights can be specified accordingly. #' @param margins margins #' @param between.margin between.margin #' @param stack stack @@ -275,6 +277,6 @@ tm_logo = function(file, resize.as.group, z) { args = lapply(as.list(rlang::call_match()[-1]), eval, envir = parent.frame()) - if (!("z" %in% names(args))) args$z = as.integer(NA) + if (!("z" %in% names(args))) args$z = NA_integer_ tm_element_list(do.call(tm_element, c(args, list(subclass = c("tm_logo", "tm_component"))))) } diff --git a/R/tm_legend.R b/R/tm_legend.R index e4dd2588..24cb9147 100644 --- a/R/tm_legend.R +++ b/R/tm_legend.R @@ -46,8 +46,7 @@ #' @param margin.item.text PARAM_DESCRIPTION #' @param ... passed on (?) #' @param variable visual (or transformation) variable to combine the legend with: e.g. `"fill"` or `"size"` -#' @return OUTPUT_DESCRIPTION -#' @rdname tm_legend +#' @return A tm_legend component #' @export tm_legend = function(title, show, @@ -97,18 +96,16 @@ tm_legend = function(title, if (!("title" %in% (names(args)))) args$title = NA if (!("xlab" %in% (names(args)))) args$xlab = NA if (!("ylab" %in% (names(args)))) args$ylab = NA - if (!("z" %in% (names(args)))) args$z = as.integer(NA) + if (!("z" %in% (names(args)))) args$z = NA_integer_ structure(args, class = c("tm_legend", "tm_component", "list")) } -#' @name tm_legend_hide #' @rdname tm_legend #' @export tm_legend_hide = function() { tm_legend(show = FALSE) } -#' @name tm_legend_combine #' @rdname tm_legend #' @export tm_legend_combine = function(variable) { @@ -135,7 +132,7 @@ tm_legend_bivariate = function(xlab, if (!("title" %in% (names(args)))) args$title = NA if (!("xlab" %in% (names(args)))) args$xlab = NA if (!("ylab" %in% (names(args)))) args$ylab = NA - if (!("z" %in% (names(args)))) args$z = as.integer(NA) + if (!("z" %in% (names(args)))) args$z = NA_integer_ args$orientation = "portrait" structure(args, class = c("tm_legend", "tm_component", "list")) } diff --git a/R/tm_scale_.R b/R/tm_scale_.R index 602064a7..df3fc17d 100644 --- a/R/tm_scale_.R +++ b/R/tm_scale_.R @@ -1,24 +1,24 @@ #' tmap function to define a constant visual value -#' +#' #' tmap function to define a constant visual value -#' +#' #' @export tm_const = function() { tmapOption("value.const") } #' Scales: automatic scale -#' +#' #' Scales in tmap are configured by the family of functions with prefix `tm_scale`. #' Such function should be used for the input of the `.scale` arguments in the #' layer functions (e.g. `fill.scale` in [tm_polygons()]). The function `tm_scale()` #' is a scale that is set automatically given by the data type (factor, numeric, and integer) #' and the visual variable. The tmap option `scales.var` contains information #' which scale is applied when. -#' +#' #' @param ... arguments passed on to the applied scale function `tm_scale_*()` #' @seealso [tm_scale_asis()], [tm_scale_ordinal()], [tm_scale_categorical()], -#' [tm_scale_intervals()], [tm_scale_discrete()], [tm_scale_continuous()], +#' [tm_scale_intervals()], [tm_scale_discrete()], [tm_scale_continuous()], #' [tm_scale_rank()], [tm_scale_continuous_log()], [tm_scale_continuous_log2()], #' [tm_scale_continuous_log10()], [tm_scale_continuous_log1p()], [tm_scale_continuous_sqrt()], #' [tm_scale_continuous_pseudo_log()], [tm_scale_rgb()], [tm_scale_bivariate()] @@ -29,12 +29,12 @@ tm_scale = function(...) { } #' Scales: as is -#' +#' #' Scales in tmap are configured by the family of functions with prefix `tm_scale`. #' Such function should be used for the input of the `.scale` arguments in the #' layer functions (e.g. `fill.scale` in [tm_polygons()]). #' The function [tm_scale_asis()] is used to take data values as they are and use them as such for the visual variable. -#' +#' #' @param values.scale (generic scale argument) Scaling of the values. Only useful for size-related visual variables, such as `size` of [tm_symbols()] and `lwd` of [tm_lines()]. #' @param 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 `fill` and `size` are used for [tm_symbols()] (using filled circles), the size legend items are filled with the `value.neutral` color from the `fill.scale` scale, and fill legend items are bubbles of size `value.neutral` from the `size.scale` scale. #' @param ... Arguments caught (and not used) from the automatic function [tm_scale()] @@ -64,7 +64,7 @@ tm_scale_ordinal = function(n.max = 30, } #' Scales: categorical and ordinal scale -#' +#' #' Scales in tmap are configured by the family of functions with prefix `tm_scale`. #' Such function should be used for the input of the `.scale` arguments in the #' layer functions (e.g. `fill.scale` in [tm_polygons()]). @@ -73,7 +73,7 @@ tm_scale_ordinal = function(n.max = 30, #' former assumes unordered categories whereas the latter assumes ordered categories. #' For colors (the visual variable `fill` or `col`), different default color #' palettes are used (see the tmap option `values.var`). -#' +#' #' @param n.max Maximum number of categories (factor levels). In case there are more, they are grouped into `n.max` groups. #' @param values (generic scale argument) The visual values. For colors (e.g. `fill` or `col` for `tm_polygons()`) this is a palette name from the `cols4all` package (see [cols4all::c4a()]) or vector of colors, for size (e.g. `size` for `tm_symbols()`) these are a set of sizes (if two values are specified they are interpret as range), for symbol shapes (e.g. `shape` for [tm_symbols()]) these are a set of symbols, etc. The tmap option `values.var` contains the default values per visual variable and in some cases also per data type. #' @param values.repeat (generic scale argument) Should the values be repeated in case there are more categories? @@ -108,19 +108,19 @@ tm_scale_categorical = function(n.max = 30, } #' Scales: interval scale -#' +#' #' Scales in tmap are configured by the family of functions with prefix `tm_scale`. #' Such function should be used for the input of the `.scale` arguments in the #' layer functions (e.g. `fill.scale` in [tm_polygons()]). #' The function `tm_scale_intervals()` is used for numerical data. -#' +#' #' @param n Number of intervals. For some styles (see argument `style` below) it is the preferred number rather than the exact number. #' @param style Method to create intervals. Options are `"cat"`, `"fixed"`, `"sd"`, `"equal"`, `"pretty"`, `"quantile"`, `"kmeans"`, `"hclust"`, `"bclust"`, `"fisher"`, `"jenks"`, `"dpih"`, `"headtails"`, and `"log10_pretty"`. See the details in [classInt::classIntervals()] (extra arguments can be passed on via `style.args`). #' @param style.args List of extra arguments passed on to [classInt::classIntervals()]. #' @param breaks Interval breaks (only used and required when `style=="fixed"`) #' @param interval.closure value that determines whether where the intervals are closed: `"left"` or `"right"`. If `as.count = TRUE`, `inverval.closure` is always set to `"left"`. #' @param midpoint The data value that is interpreted as the midpoint. By default it is set to 0 if negative and positive values are present. Useful when values are diverging colors. In that case, the two sides of the color palette are assigned to negative respectively positive values. If all values are positive or all values are negative, then the midpoint is set to `NA`, which means that the value that corresponds to the middle color class (see `style`) is mapped to the middle color. If it is specified for sequential color palettes (e.g. `"Blues"`), then this color palette will be treated as a diverging color palette. -#' @param as.count Should the data variable be processed as a count variable? For instance, if `style = "pretty"`, `n = 2`, and the value range of the variable is 0 to 10, then the column classes for `as.count = TRUE` are 0; 1 to 5; 6 to 10 (note that 0 is regarded as an own category) whereas for `as.count = FALSE` they are 0 to 5; 5 to 10. Only applicable if `style` is `"pretty"`, `"fixed"`, or `"log10_pretty"`. By default, `TRUE` if `style` is one of these, and the variable is an integer. +#' @param as.count Should the data variable be processed as a count variable? For instance, if `style = "pretty"`, `n = 2`, and the value range of the variable is 0 to 10, then the column classes for `as.count = TRUE` are 0; 1 to 5; 6 to 10 (note that 0 is regarded as an own category) whereas for `as.count = FALSE` they are 0 to 5; 5 to 10. Only applicable if `style` is `"pretty"`, `"fixed"`, or `"log10_pretty"`. By default, `TRUE` if `style` is one of these, and the variable is an integer. #' @param values (generic scale argument) The visual values. For colors (e.g. `fill` or `col` for [tm_polygons()]) this is a palette name from the `cols4all` package (see [cols4all::c4a()]) or vector of colors, for size (e.g. `size` for `tm_symbols`) these are a set of sizes (if two values are specified they are interpret as range), for symbol shapes (e.g. `shape` for `tm_symbols`) these are a set of symbols, etc. The tmap option `values.var` contains the default values per visual variable and in some cases also per data type. #' @param values.repeat (generic scale argument) Should the values be repeated in case there are more categories? #' @param values.range (generic scale argument) Range of the values. Vector of two numbers (both between 0 and 1) where the first determines the minimum and the second the maximum. Full range, which means that all values are used, is encoded as `c(0, 1)`. For instance, when a gray scale is used for color (from black to white), `c(0,1)` means that all colors are used, `0.25, 0.75` means that only colors from dark gray to light gray are used (more precisely `"gray25"` to `"gray75"`), and `0, 0.5` means that only colors are used from black to middle grey (`"grey50"`). When only one number is specified, this is interpreted as the second number (where the first is set to 0). Default values can be set via the tmap option `values.range`. @@ -134,7 +134,7 @@ tm_scale_categorical = function(n.max = 30, #' @param label.format (generic scale argument) Label formatting (similar to legend.format in tmap3) #' @seealso [tm_scale()] #' @export -tm_scale_intervals = function(n = 5, +tm_scale_intervals = function(n = 5, style = ifelse(is.null(breaks), "pretty", "fixed"), style.args = list(), breaks = NULL, @@ -156,12 +156,12 @@ tm_scale_intervals = function(n = 5, } #' Scales: discrete scale -#' +#' #' Scales in tmap are configured by the family of functions with prefix `tm_scale`. #' Such function should be used for the input of the `.scale` arguments in the #' layer functions (e.g. `fill.scale` in [tm_polygons()]). #' The function [tm_scale_discrete()] is used for discrete numerical data, such as integers. -#' +#' #' @param ticks Discrete values. If not specified, it is determined automatically: unique values are put on a discrete scale. #' @param midpoint The data value that is interpreted as the midpoint. By default it is set to 0 if negative and positive values are present. Useful when values are diverging colors. In that case, the two sides of the color palette are assigned to negative respectively positive values. If all values are positive or all values are negative, then the midpoint is set to `NA`, which means that the value that corresponds to the middle color class (see `style`) is mapped to the middle color. If it is specified for sequential color palettes (e.g. `"Blues"`), then this color palette will be treated as a diverging color palette. #' @param values (generic scale argument) The visual values. For colors (e.g. `fill` or `col` for [tm_polygons()]) this is a palette name from the `cols4all` package (see [cols4all::c4a()]) or vector of colors, for size (e.g. `size` for `tm_symbols`) these are a set of sizes (if two values are specified they are interpret as range), for symbol shapes (e.g. `shape` for [tm_symbols()]) these are a set of symbols, etc. The tmap option `values.var` contains the default values per visual variable and in some cases also per data type. @@ -195,13 +195,13 @@ tm_scale_discrete = function(ticks = NA, } #' Scales: continuous scale -#' +#' #' Scales in tmap are configured by the family of functions with prefix `tm_scale`. #' Such function should be used for the input of the `.scale` arguments in the layer #' functions (e.g. `fill.scale` in [tm_polygons()]). #' The function [tm_scale_continuous()] is used for continuous data. #' The functions `tm_scale_continuous_()` use transformation functions x. -#' +#' #' @param n Preferred number of tick labels. Only used if `ticks` is not specified #' @param limits Limits of the data values that are mapped to the continuous scale #' @param outliers.trunc Should outliers be truncated? An outlier is a data value that is below or above the respectively lower and upper limit. A logical vector of two values is expected. The first and second value determines whether values lower than the lower limit respectively higher than the upper limit are truncated to the lower respectively upper limit. If `FALSE` (default), they are considered as missing values. @@ -221,7 +221,7 @@ tm_scale_discrete = function(ticks = NA, #' @param label.format (generic scale argument) Label formatting (similar to `legend.format` in tmap3) #' @param trans.args list of additional argument for the transformation (generic transformation arguments) #' @inheritParams scales::transform_pseudo_log -#' @example ./examples/tm_scale_continuous.R +#' @example ./examples/tm_scale_continuous.R #' @seealso [tm_scale()] #' @export #' @rdname tm_scale_continuous @@ -244,18 +244,18 @@ tm_scale_continuous = function(n = NULL, label.null = NA, label.format = list(), trans.args = list()) { - + structure(c(list(FUN = "tmapScaleContinuous"), as.list(environment())), class = c("tm_scale_continuous", "tm_scale", "list")) } #' Scales: rank scale -#' +#' #' Scales in tmap are configured by the family of functions with prefix `tm_scale`. #' Such function should be used for the input of the `.scale` arguments in the layer #' functions (e.g. `fill.scale` in [tm_polygons()]). #' The function [tm_scale_rank()] is used to rank numeric data. -#' +#' #' @param n Preferred number of tick labels. Only used if `ticks` is not specified #' @param ticks Tick values. If not specified, it is determined automatically with `n` #' @param values (generic scale argument) The visual values. For colors (e.g. `fill` or `col` for [tm_polygons()]) this is a palette name from the `cols4all` package (see [cols4all::c4a()]) or vector of colors, for size (e.g. `size` for [tm_symbols()]) these are a set of sizes (if two values are specified they are interpret as range), for symbol shapes (e.g. `shape` for [tm_symbols()]) these are a set of symbols, etc. The tmap option `values.var` contains the default values per visual variable and in some cases also per data type. @@ -341,7 +341,7 @@ tm_scale_continuous_pseudo_log = function(..., base = exp(1), sigma = 1) { tm_scale_continuous(trans = "pseudo_log", trans.args = list(base = base, sigma = sigma), ...) } -# +# # #' @export # #' @rdname tm_scale_continuous # #' @name tm_scale_continuous_logistic @@ -351,19 +351,20 @@ tm_scale_continuous_pseudo_log = function(..., base = exp(1), sigma = 1) { #' Scales: RGB -#' +#' #' Scales in tmap are configured by the family of functions with prefix `tm_scale`. #' Such function should be used for the input of the `.scale` arguments in the layer #' functions (e.g. `fill.scale` in [tm_polygons()]). #' The function [tm_scale_rgb()] is used to transform r, g, b band variables to colors. This function is adopted from (and works similar as) [stars::st_rgb()] #' #' @param value.na value for missing values -#' @param stretch should each (r, g, b) band be stretched? Possible values: `"percent"` (same as `TRUE`) and `"histogram"`. In the first case, the values are stretched to `probs[1]...probs[2]`. In the secodn case, a histogram equalization is performed +#' @param stretch should each (r, g, b) band be stretched? Possible values: `"percent"` (same as `TRUE`) and `"histogram"`. +#' In the first case, the values are stretched to `probs[1]...probs[2]`. In the second case, a histogram equalization is performed #' @param probs probability (quantile) values when `stretch = "percent"` #' @param maxColorValue maximum value #' @seealso [tm_scale()] and [stars::st_rgb()] #' @rdname tm_scale_rgb -#' @example ./examples/tm_scale_rgb.R +#' @example ./examples/tm_scale_rgb.R #' @export tm_scale_rgb = function(value.na = NA, stretch = FALSE, diff --git a/R/tmapShape.R b/R/tmapShape.R index e5e06cc6..e18da48a 100644 --- a/R/tmapShape.R +++ b/R/tmapShape.R @@ -62,7 +62,7 @@ tmapGetShapeMeta1 = function(shp, o) { #' Internal method that extracts meta data from shape objects #' #' @param shp the shape -#' @param smeta meta (from tmapGetShapeMeta1) +#' @param smeta meta (from `tmapGetShapeMeta1()`) #' @param o the list of options #' @export #' @keywords internal diff --git a/R/tmap_tip.R b/R/tmap_tip.R index f90ad691..c021406f 100644 --- a/R/tmap_tip.R +++ b/R/tmap_tip.R @@ -1,10 +1,11 @@ -#' Print a rnadom tip to the console -#' +#' Print a random tip to the console +#' #' @returns A message #' @export tmap_tip <- function() { tips <- c( - "tmap v4 works with visual variables." + "tmap v4 works with {.href [visual variables](https://r-tmap.github.io/tmap/articles/03_tmap_vv.html)}.", + "" ) tip <- sample(tips, size = 1) cli::cli_inform(tip) diff --git a/man/tm_add_legend.Rd b/man/tm_add_legend.Rd index 99da6112..d493d3a3 100644 --- a/man/tm_add_legend.Rd +++ b/man/tm_add_legend.Rd @@ -14,7 +14,7 @@ tm_add_legend( group = NA, group.control = "check", resize.as.group = FALSE, - z = as.integer(NA) + z = NA_integer_ ) } \arguments{ diff --git a/man/tm_legend.Rd b/man/tm_legend.Rd index ee6146ec..a7d393e3 100644 --- a/man/tm_legend.Rd +++ b/man/tm_legend.Rd @@ -146,7 +146,7 @@ tm_legend_combine(variable) \item{variable}{visual (or transformation) variable to combine the legend with: e.g. \code{"fill"} or \code{"size"}} } \value{ -OUTPUT_DESCRIPTION +A tm_legend component } \description{ Legend specification diff --git a/man/tm_logo.Rd b/man/tm_logo.Rd index a8538cca..c6b015b7 100644 --- a/man/tm_logo.Rd +++ b/man/tm_logo.Rd @@ -20,9 +20,11 @@ tm_logo( ) } \arguments{ -\item{file}{either a filename or url of a png image. If multiple files/urls are provided with a character vector, the logos are placed near each other. To specify logos for small multiples use a list of character values/vectors. In order to stack logos vertically, multiple \code{tm_logo} elements can be stacked.} +\item{file}{either a filename or url of a png image. If multiple files/urls are provided with a character vector, the logos are placed near each other. +To specify logos for small multiples use a list of character values/vectors. In order to stack logos vertically, multiple \code{tm_logo} elements can be stacked.} -\item{height}{height of the logo in number of text line heights. The width is scaled based the height and the aspect ratio of the logo. If multiple logos are specified by a vector or list, the heights can be specified accordingly.} +\item{height}{height of the logo in number of text line heights. The width is scaled based the height and the aspect ratio of the logo. +If multiple logos are specified by a vector or list, the heights can be specified accordingly.} \item{margins}{margins} diff --git a/man/tm_scale_rgb.Rd b/man/tm_scale_rgb.Rd index e5cea092..3b32d9ca 100644 --- a/man/tm_scale_rgb.Rd +++ b/man/tm_scale_rgb.Rd @@ -22,7 +22,8 @@ tm_scale_rgba( \arguments{ \item{value.na}{value for missing values} -\item{stretch}{should each (r, g, b) band be stretched? Possible values: \code{"percent"} (same as \code{TRUE}) and \code{"histogram"}. In the first case, the values are stretched to \verb{probs[1]...probs[2]}. In the secodn case, a histogram equalization is performed} +\item{stretch}{should each (r, g, b) band be stretched? Possible values: \code{"percent"} (same as \code{TRUE}) and \code{"histogram"}. +In the first case, the values are stretched to \verb{probs[1]...probs[2]}. In the second case, a histogram equalization is performed} \item{probs}{probability (quantile) values when \code{stretch = "percent"}} diff --git a/man/tmapGetShapeMeta2.Rd b/man/tmapGetShapeMeta2.Rd index 1f08070d..da571685 100644 --- a/man/tmapGetShapeMeta2.Rd +++ b/man/tmapGetShapeMeta2.Rd @@ -9,7 +9,7 @@ tmapGetShapeMeta2(shp, smeta, o) \arguments{ \item{shp}{the shape} -\item{smeta}{meta (from tmapGetShapeMeta1)} +\item{smeta}{meta (from \code{tmapGetShapeMeta1()})} \item{o}{the list of options} } diff --git a/man/tmap_animation.Rd b/man/tmap_animation.Rd index 914f241b..1dccb79a 100644 --- a/man/tmap_animation.Rd +++ b/man/tmap_animation.Rd @@ -60,7 +60,7 @@ the edges of the image.} \item{restart.delay}{not used anymore.} -\item{...}{arguments passed on to \code{\link[av:encoding]{av::av_encode_video()}}} +\item{...}{arguments passed on to \code{\link[av:av_encode_video]{av::av_encode_video()}}} } \description{ Create a gif animation or video from a tmap plot. diff --git a/man/tmap_tip.Rd b/man/tmap_tip.Rd index dbad2b1f..0a6c8717 100644 --- a/man/tmap_tip.Rd +++ b/man/tmap_tip.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/tmap_tip.R \name{tmap_tip} \alias{tmap_tip} -\title{Print a rnadom tip to the console} +\title{Print a random tip to the console} \usage{ tmap_tip() } @@ -10,5 +10,5 @@ tmap_tip() A message } \description{ -Print a rnadom tip to the console +Print a random tip to the console } diff --git a/tests/testthat/test-tm_lines.R b/tests/testthat/test-tm_lines.R new file mode 100644 index 00000000..d1fabeac --- /dev/null +++ b/tests/testthat/test-tm_lines.R @@ -0,0 +1,17 @@ +test_that("It is possible to combine two visual elements into single legend", { + break_values <- c(-Inf, 2, 4, 6, 8, Inf) + color_values <- c("#B4D79E", "#98E600", "#FFAA00", "#FF5500", "#A80000") + size_values <- c(0.5, 1, 2, 3, 5) + expect_no_error({ + tm_shape(rivers) + + tm_lines( + col = "strokelwd", + col.scale = tm_scale_intervals(values = color_values, breaks = break_values), + lwd = "strokelwd", + lwd.scale = tm_scale_intervals(values = size_values, breaks = break_values), + lwd.legend = tm_legend_combine("col"), + plot.order = tm_plot_order("lwd", reverse = FALSE, na.order = "bottom") + ) + + tm_layout(legend.show = TRUE) + }) +}) diff --git a/vignettes/09_tmap_shiny.Rmd b/vignettes/09_tmap_shiny.Rmd index 4854ad0d..36afe71a 100644 --- a/vignettes/09_tmap_shiny.Rmd +++ b/vignettes/09_tmap_shiny.Rmd @@ -1,12 +1,14 @@ --- title: "tmap: shiny integration" +description: > + Include interactive maps in Shiny applications output: bookdown::html_vignette2: pkgdown: as_is: true template: math-rendering: mathjax -bibliography: '`r system.file("tmap.bib", package="tmap")`' +bibliography: '`r system.file("tmap.bib", package = "tmap")`' csl: "`r system.file('ieee.csl', package = 'tmap')`" --- @@ -25,7 +27,7 @@ knitr::knit_hooks$set(output = function(x, options) { } x <- unlist(strsplit(x, "\n")) more <- "..." - if (length(lines)==1) { # first n lines + if (length(lines) == 1) { # first n lines if (length(x) > lines) { # truncate the output, but add .... x <- c(head(x, lines), more) @@ -48,7 +50,7 @@ data(World, metro, rivers, land) #tmap_design_mode() ``` -## Introductiuon +## Introduction Integration of **tmap** with **shiny** is straightforward. The functions `tmapOutput()` and `renderTmap()` are similar to `shiny::plotOutput()` and `shiny::renderPlot()`, respectively.