Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

layer-specific arguments: how to specify them? #848

Closed
mtennekes opened this issue Mar 19, 2024 · 4 comments
Closed

layer-specific arguments: how to specify them? #848

mtennekes opened this issue Mar 19, 2024 · 4 comments

Comments

@mtennekes
Copy link
Member

Quoting myself #840

Another thing: the layer options were contained in mapping.args and trans.args. However, I've migrated them back in to the layer function roots to make them better accessible. (Downside is the organisation of arguments).

Still not happy with that solution, so I'm glad to hear your opinions @afolson-NOAA @Nowosad @olivroy @Robinlovelace

The question is: how should the user specify layer specific arguments?

Background: Each layer is specific with a transformation and a mapping function. E.g. tm_cartogram() has tmapTransCartogram as the transformation function and Polygons as the mapping function id (which directs to tmapPolygons where is the graphics device (mode) currently only "Grid" or "Leaflet"). For those who followed the workshop last year, the transformation is "step 3" and the mapping "step 4" of the tmap pipeline.

In case of the arguments of tm_cartogram: itermax will be passed on to the transformation function. However for some arguments it is unclear whether they belong to the transformation or mapping phase. E.g. automatic text labeling: you can think of it as moving the coordinates in order to prevent overlap (which is essentially a transformation) or you can think of it as that the coordinates remain fixed, but the text is shown elsewhere, and that depends on how other map elements are plotted (which is determined in the mapping phase).

I can think of four options how users could be able to specify layer arguments, which I illustrate with tm_symbols (because it has both transformation and mapping arguments). In this code examples I omit all visual variables except size:

  1. Just list the arguments in the root:
tm_symbols = function(
    size = tm_const(),
    size.scale = tm_scale(),
    size.legend = tm_legend(),
    size.chart = tm_chart_none(),
    size.free = NA,
    plot.order = tm_plot_order("size"),
    zindex = NA,
    group = NA,
    group.control = "check",
    popup.vars = NA,
    popup.format = list(),
    hover = "",
    id = "",					 
    points.only = "ifany",
    icon.scale = 3,
    just = NA,
    grob.dim = c(width=48, height=48, render.width=256, render.height=256),
    ...) {
  1. Put them in two lists: mapping.args and trans.args:
tm_symbols = function(
    size = tm_const(),
    size.scale = tm_scale(),
    size.legend = tm_legend(),
    size.chart = tm_chart_none(),
    size.free = NA,
    plot.order = tm_plot_order("size"),
    zindex = NA,
    group = NA,
    group.control = "check",
    popup.vars = NA,
    popup.format = list(),
    hover = "",
    id = "",					 
    trans.args = list(points.only = "ifany"),
    mapping.args = list(icon.scale = 3, just = NA, grob.dim = c(width=48, height=48, render.width=256, render.height=256)),
    ...) {
  1. Same as 1, but with a "opt" prefix:
tm_symbols = function(
    size = tm_const(),
    size.scale = tm_scale(),
    size.legend = tm_legend(),
    size.chart = tm_chart_none(),
    size.free = NA,
    plot.order = tm_plot_order("size"),
    zindex = NA,
    group = NA,
    group.control = "check",
    popup.vars = NA,
    popup.format = list(),
    hover = "",
    id = "",					 
    opt.points.only = "ifany",
    opt.icon.scale = 3,
    opt.just = NA,
    opt.grob.dim = c(width=48, height=48, render.width=256, render.height=256),
    ...) {
  1. Leaflet style:
tm_symbols = function(
    size = tm_const(),
    size.scale = tm_scale(),
    size.legend = tm_legend(),
    size.chart = tm_chart_none(),
    size.free = NA,
    plot.order = tm_plot_order("size"),
    zindex = NA,
    group = NA,
    group.control = "check",
    popup.vars = NA,
    popup.format = list(),
    hover = "",
    id = "",	
    options = opt_tm_symbols(points.only = "ifany", icon.scale = 3, just = NA, grob.dim = c(width=48, height=48, render.width=256, render.height=256)),
    ...) {
@Robinlovelace
Copy link
Collaborator

This looks like a tricky problem with various trade-offs. From a quick glance I like 2 because it clearly demarcates the purpose of points.only = "ifany" and list(icon.scale = 3, just = NA, grob.dim = c(width=48, height=48, render.width=256, render.height=256)), ...) so a win for clarity. So tentative 👍 for 2. There may be downsides tho...

@olivroy
Copy link
Contributor

olivroy commented Mar 20, 2024

I like 4. because it is easier for autocomplete https://design.tidyverse.org/argument-clutter.html

maybe opt_symbols() as a name.

@Robinlovelace
Copy link
Collaborator

+1 to 4 also.

@mtennekes
Copy link
Member Author

Great! Then we are on the same page. We could also combine 2 and 4 with something like mapping.args = opt_map_polygons()

I'll find out what is most convenient during implantation:-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants