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

Document tm_legend() + add examples #930

Open
olivroy opened this issue Sep 2, 2024 · 6 comments
Open

Document tm_legend() + add examples #930

olivroy opened this issue Sep 2, 2024 · 6 comments
Labels

Comments

@olivroy
Copy link
Contributor

olivroy commented Sep 2, 2024

I am trying to upgrade some code to v4, and I noticed that tm_legend() lacks documentation.

World |> 
  tm_shape() +
  tm_polygons(
    fill = "HPI",
    legend.format = list(
      fun = function(x) scales::dollar(x)
    )
  )

image

Furthermore, upgrading the previous code to v4 syntax is the following.

World |> 
  tm_shape() +
  tm_polygons(
    fill = "HPI",
    fill.scale = tm_scale(
      label.format = list(
      fun = function(x) scales::dollar(x)
    )
  ))

Is there a simpler way to do it?

I didn't get it on the first try as I attempted to do this first, but it didn't work (and didn't warn either)

World |> 
  tm_shape() +
  tm_polygons(
    fill = "HPI",
    fill.legend = tm_legend(
      format = list(
        fun = function(x) scales::dollar(x)
      )
    )
  )
@olivroy olivroy added the tmap_v4 label Sep 2, 2024
@mtennekes
Copy link
Member

Good question. I'm open to make things more intuitive.

Firstly, these formatting options are part of tm_scale functions and not the tm_legend functions, because they are not only used in the legend, but also in hover text and popup windows. At least, that is the aim: in view mode it doesn't show the dollar notation yet.

What do you propose from a users perspective?

@olivroy
Copy link
Contributor Author

olivroy commented Sep 3, 2024

I wonder if all format aarguments could just take a function...

World |> 
  tm_shape() +
  tm_polygons(
    fill = "HPI",
    fill.scale = tm_scale(
      label.format = scales::label_percent()
    ),
   popup.format = list(
      area = \(x) format(x, digits = 1)
  )
  ))

instead of being list of list. I don't know if it is possible, or if v3 code translations would work with that or not?

mtennekes added a commit that referenced this issue Sep 3, 2024
@mtennekes
Copy link
Member

I like this suggestion with direct function specification. This one is working now:

World |> 
	tm_shape() +
	tm_polygons(
		popup.vars = TRUE,
		popup.format = list(
			HPI = scales::label_dollar(),
			life_exp = \(x) round(x, 1)
			)
		)
	

The .format arguments (popup.format and label.format) are still defined as a list, with fun being just one (but the most flexible) option. Two things I changed:

  1. For popup.format this list is made for each popup variable. If one list is provided, it is applied to all popup variables.
  2. If the format is specified with a function (say f) directly (as in this example), this is internally processed as list(fun = f)

Remaining question: what to do with data variables such as HPI that are also used as visual variables. Should the original value be printed in the popup (e.g. HPI = 36.83), the scaled value (HPI = 35 to 40) or both? In this example, the first option would probably be preferable. However, if I apply a continuous scale with label.format = scales::label_dollar() then it would make more sense to use that (e.g. HP = $36.83) in the popup as well.

@olivroy
Copy link
Contributor Author

olivroy commented Sep 3, 2024

Thanks! I will test this out! Agreed that the vv should cascade to the popup and legend if possible!

The new syntax looks great and is much clearer than nested lists!

mtennekes added a commit that referenced this issue Sep 9, 2024
@mtennekes
Copy link
Member

Just committed to make the cascade work in the following way (which hopefully is intuitive and useful):

World |> 
	tm_shape() +
	tm_polygons(
		fill = "HPI",
		fill.scale = tm_scale_intervals(label.format = scales::label_dollar()),
		popup.vars = TRUE,
		popup.format = list(
			inequality = scales::label_percent()
		)
	)

Result: popup labels HPI are in dollars, and inequality in percentages.

World |> 
	tm_shape() +
	tm_polygons(
		fill = "HPI",
		fill.scale = tm_scale_intervals(label.format = scales::label_dollar()),
		popup.vars = TRUE,
		popup.format = list(
			HPI = scales::label_percent()
		)
	)

Result: popup labels HPI are in percentages. In case of conflict like this, the popup.format gets the priority vote (because it could be deliberately deviating from the legend). However, if popup.format is unnamed, label.format is used:

World |> 
	tm_shape() +
	tm_polygons(
		fill = "HPI",
		fill.scale = tm_scale_intervals(label.format = scales::label_dollar()),
		popup.vars = TRUE,
		popup.format = scales::label_percent()
	)

Result: all popup labels are in percentages (at least, all numeric variables), but HPI are in dollars.

@olivroy
Copy link
Contributor Author

olivroy commented Sep 11, 2024

Looks great! thanks

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

No branches or pull requests

2 participants