tmap:如何将格式应用于小倍数等值线的数字标签
tmap: how to apply formatting to numeric labels on small multiples choropleths
我正在用 tmap 绘制小倍数,每个竞争对手一个。我得到了波兰的多个分区统计图,分为多个县,按销售额着色,如 ggplot facet_wrap).
首先,我将数据附加到一个 shp 文件,并将每个竞争对手的值(对于一个国家/地区的每个小地图)作为单独的列。每行是一个省。
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)
一切正常。然后我绘制我的形状。
我的 "best6" 是一个列名列表,竞争对手的名字,每个名字打印一张地图,总共六张地图。
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 )
绘图还可以,但我对数字标签不满意,希望以更易读的方式设置它们的格式。
tm_text 在每个省的形状上打印值。请注意,作为参数文本,它采用列的矢量名称,其中包含每个竞争对手的每个省份的值。
如何为 tmap 中的数字标签添加格式?例如,如何将以下行添加到我的 tm_text 命令中?
format(x, scientific = FALSE, big.mark=" ", big.interval=3)})
编辑:
我尝试了 Jindra Lacko 的解决方案,图例标签按照指定的格式进行了格式化,但仍然不是地图中的标签。
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:我想进一步澄清这个问题,因为它不是很清楚。
对于绘制小倍数的等值线图,如 ggplot2 中的 facet_wrap,在 tmap 中需要将 "wide form" 中的数据列附加到 shp 数据。 (至少我从各种教程中了解到)
每个小图从列中获取数据。
这意味着与一个图不同,tm_texts 获取列名称,以便 tmap 可以打印小的倍数。这意味着我不能简单地重新格式化,将值更改为文本,因为我在那里 没有值,但 shp 数据中的列名称 。
最终编辑:按照 Jindra Lacko 的回答,我创建了 6 列,与源数据一样多,并对其进行格式化,以便我可以将它们分别传递给 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
)
然后我可以分别传递数字系列 列名称 为形状着色,并单独传递文本格式系列 列名称 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)
要更改格式,您需要将定义格式的函数传递给 tm_*
调用的 legend.format
部分。
我相信 legend.format = list(fun = function(x) formatC(x, digits = 0, big.mark = " ", format = "f"))
应该可以解决问题。 Big interval = 3 是默认的,你应该可以忽略它。
不久前我写了一篇关于 tmap 图例格式的博客 post,其中包括使用 C 样式格式和向数字添加货币/百分比符号。
欢迎查看 https://www.jla-data.net/eng/tmap-legend/
编辑:现在我明白了!不是图例,而是地图上的标签!我的坏...
您需要在绘制标签之前将标签转换为文本。我无法重现您的代码,因此我在欧洲数据集上包含了一个示例,包含在 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)
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)
我正在用 tmap 绘制小倍数,每个竞争对手一个。我得到了波兰的多个分区统计图,分为多个县,按销售额着色,如 ggplot facet_wrap).
首先,我将数据附加到一个 shp 文件,并将每个竞争对手的值(对于一个国家/地区的每个小地图)作为单独的列。每行是一个省。
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)
一切正常。然后我绘制我的形状。 我的 "best6" 是一个列名列表,竞争对手的名字,每个名字打印一张地图,总共六张地图。
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 )
绘图还可以,但我对数字标签不满意,希望以更易读的方式设置它们的格式。
tm_text 在每个省的形状上打印值。请注意,作为参数文本,它采用列的矢量名称,其中包含每个竞争对手的每个省份的值。
如何为 tmap 中的数字标签添加格式?例如,如何将以下行添加到我的 tm_text 命令中?
format(x, scientific = FALSE, big.mark=" ", big.interval=3)})
编辑: 我尝试了 Jindra Lacko 的解决方案,图例标签按照指定的格式进行了格式化,但仍然不是地图中的标签。
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:我想进一步澄清这个问题,因为它不是很清楚。
对于绘制小倍数的等值线图,如 ggplot2 中的 facet_wrap,在 tmap 中需要将 "wide form" 中的数据列附加到 shp 数据。 (至少我从各种教程中了解到)
每个小图从列中获取数据。
这意味着与一个图不同,tm_texts 获取列名称,以便 tmap 可以打印小的倍数。这意味着我不能简单地重新格式化,将值更改为文本,因为我在那里 没有值,但 shp 数据中的列名称 。
最终编辑:按照 Jindra Lacko 的回答,我创建了 6 列,与源数据一样多,并对其进行格式化,以便我可以将它们分别传递给 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
)
然后我可以分别传递数字系列 列名称 为形状着色,并单独传递文本格式系列 列名称 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)
要更改格式,您需要将定义格式的函数传递给 tm_*
调用的 legend.format
部分。
我相信 legend.format = list(fun = function(x) formatC(x, digits = 0, big.mark = " ", format = "f"))
应该可以解决问题。 Big interval = 3 是默认的,你应该可以忽略它。
不久前我写了一篇关于 tmap 图例格式的博客 post,其中包括使用 C 样式格式和向数字添加货币/百分比符号。
欢迎查看 https://www.jla-data.net/eng/tmap-legend/
编辑:现在我明白了!不是图例,而是地图上的标签!我的坏...
您需要在绘制标签之前将标签转换为文本。我无法重现您的代码,因此我在欧洲数据集上包含了一个示例,包含在 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)
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)