Reputation: 704
I am plotting small multiples, one for each competitor, with tmap. I am getting multiple choropleth maps of Poland divided into counties, colored by sales values, like ggplot facet_wrap).
First I appended data to a shp file and had each competitor values (for each small map of a country) as separate column. Each row is a province.
county_marketshare<-df_monthly_val %>%
filter(win_name %in% best6) %>%
select(win_name,value,inv_province) %>%
group_by(win_name,inv_province)%>%
summarise(value=round(sum(value)),0)%>%
spread(key="win_name", value=value)
It all works well. Then I plot my shapes. My "best6" is a list of the names of columns, names of competitors and for each name a map is printed, six maps in total.
tm_shape(pl_geo) +
tm_polygons(best6,
id = "province",
palette = colfunc(20),
style="quantile", #("pretty", "fixed" (describe breaks))
legend.show = FALSE,
free.scales.fill=FALSE
)+
tm_text(text =c(best6), legend.size.show = FALSE,ymod = -0.7, size = .8 )
The plots are OK but I am not satisfied with numeric labels and would like to format them in a more readable way.
The tm_text prints value on each province's shape. Note that as argument text it takes the vector names of columns with values per province for each competitor.
How do I add formatting to numeric labels in tmap? For instance, how I can add the following line to my tm_text command?
format(x, scientific = FALSE, big.mark=" ", big.interval=3)})
Edit: I tried the solution by Jindra Lacko and legend labels are formatted as specified but still not labels in the map.
tm_shape(pl_geo) +
tm_polygons(best6,
id = "province",
palette = colfunc(20),
style="quantile", #("pretty", "fixed" (describe breaks))
legend.show = TRUE,
free.scales.fill=FALSE)+
tm_text(c(best6) , legend.size.show = FALSE,ymod = -0.7, size = 1,
legend.format = list(fun = function(x) formatC(x, digits = 0, big.mark = " ", format = "f")))
EDIT2: I would like to clarify the issue further, because it was not very clear.
For choropleth plotting small ultiples, like facet_wrap in ggplot2, in tmap one needs to append data columns in "wide form" to shp data. (at least so I understood from various tutorials)
Each small plot gets a data from the column.
it means that unlike for one plot, tm_texts gets names of columns so that tmap can print small multiples. It means I cannot simply reformat, change values to text because I have no values there but names of columns in shp data.
Edit final: Following the answer by Jindra Lacko I created 6 columns, as many as source data and formatted them so that I could pass them separately to tm_text:
county_marketshare<-df_monthly_val %>%
filter(win_name %in% best6) %>%
select(win_name,value,inv_province) %>%
group_by(win_name,inv_province)%>%
summarise(value=round(sum(value),0))%>%
spread(key="win_name", value=value, fill=0) %>% # teraz muszę stworzyc kolumny sformatowane "finansowo"
mutate(!!as.symbol(paste0(best6[1],"_lbl")):= formatC(!!as.symbol(best6[1]),digits = 0, big.mark = " ", format = "f",zero.print = ""),
!!as.symbol(paste0(best6[2],"_lbl")):= formatC(!!as.symbol(best6[2]),digits = 0, big.mark = " ", format = "f",zero.print = ""),
!!as.symbol(paste0(best6[3],"_lbl")):= formatC(!!as.symbol(best6[3]),digits = 0, big.mark = " ", format = "f",zero.print = ""),
!!as.symbol(paste0(best6[4],"_lbl")):= formatC(!!as.symbol(best6[4]),digits = 0, big.mark = " ", format = "f",zero.print = ""),
!!as.symbol(paste0(best6[5],"_lbl")):= formatC(!!as.symbol(best6[5]),digits = 0, big.mark = " ", format = "f",zero.print = ""),
!!as.symbol(paste0(best6[6],"_lbl")):= formatC(!!as.symbol(best6[6]),digits = 0, big.mark = " ", format = "f",zero.print = "")
)
county_marketshare$inv_province <- iconv(county_marketshare$inv_province,from = "utf-8", to = "ascii//TRANSLIT")
pl_geo <-
append_data(
shp = pl_geo,
data = county_marketshare,
key.shp = "jpt_nazwa_",
key.data = "inv_province",
ignore.na = T
)
Then I could pass separately numeric series columns' names for coloring the shapes and separately text formated series columns' names for tm_text.
colfunc <- colorRampPalette(c("white","green"))
mytext <- paste0(pl_geo$jpt_nazwa_)
best6lab<-paste0(best6,"_lbl")
pl_best6suppl_prov<-
tm_shape(pl_geo) +
tm_polygons(best6,
id = "province",
palette = colfunc(40),
style="kmeans", #("pretty", "fixed" (describe breaks))
legend.show = FALSE)+
tm_facets(free.scales.fill = FALSE)+
tm_text("jpt_nazwa_", size = .7, legend.size.show = FALSE,col="darkgreen")+
tm_shape(pl_geo) +
tm_text(c(best6lab) , legend.size.show = FALSE,ymod = -0.7, size = 1) +
tm_layout(panel.labels = best6)
Upvotes: 0
Views: 2471
Reputation: 8719
To change the formatting you need to pass a function defining the format to the legend.format
part of your tm_*
call.
I believe legend.format = list(fun = function(x) formatC(x, digits = 0, big.mark = " ", format = "f"))
should do the trick. Big interval = 3 is by default, you should be OK omitting it.
A while back I wrote a blog post on tmap legend formatting, among other things on using the C style format and adding currency / percentage symbols to the numbers.
Feel free to check https://www.jla-data.net/eng/tmap-legend/
Edit: Now I get it! Not the legend, but the labels on the map! My bad...
You need to convert the labels to text just before plotting them. I could not reproduce your code, so I am including an example on the Europe dataset, included with tmap.
library(tmap)
library(tidyverse)
data(Europe)
Europe$pop_est_adj <- as.character(formatC(Europe$pop_est,
big.mark = " ",
format = "f",
digits = 0))
tm_shape(Europe) + tm_borders() +
tm_shape(Europe) + tm_text(text = "pop_est_adj", size = .7)
Upvotes: 2
Reputation: 41
m1 <- tm_shape(World) +
tm_polygons("pop_est", palette="RdYlGn", n=8,
title="Población estimada", id="name",
legend.show = FALSE)
m2 <- tm_shape(World) +
tm_polygons("pop_est", palette="RdYlGn", n=8,
title="Población estimada", id="name") +
tm_layout(legend.only = TRUE,
legend.format = list(text.separator = 'a',
fun = function(x) formatC(x, digits = 0, big.mark = ".", format = "f")))
tmap_arrange(m1, m2)
Upvotes: 1