如何用ggplot2和treemapify自动为树形图添加自定义图标?
解决方案
要在树形图中自动嵌入图标,有两种可行的实现方式,以下是具体代码示例:
方法一:结合grid包手动添加图标Grob
先通过treemapify()获取每个树形区域的坐标,再将图标转为grid对象后逐个添加到图中:
# 加载所需包 library(treemapify) library(ggplot2) library(magick) library(grid) # 创建数据框 df <- data.frame(category = c("forest", "greenland", "crops"), area = c(20, 10, 70) ) df$label = paste0(df$area,"%") # 加载并调整图标尺寸(可根据需求修改尺寸) icon_crops2 <- image_read("https://upload.wikimedia.org/wikipedia/commons/thumb/7/79/Agriculture_-_The_Noun_Project.svg/512px-Agriculture_-_The_Noun_Project.svg.png") %>% image_resize("120x120") icon_forest2 <- image_read("https://upload.wikimedia.org/wikipedia/commons/thumb/d/da/BSicon_FOREST.svg/500px-BSicon_FOREST.svg.png") %>% image_resize("120x120") icon_greenland2 <- image_read("https://upload.wikimedia.org/wikipedia/commons/thumb/2/2b/Wikidata_Morse_code_logo_grassroots.svg/600px-Wikidata_Morse_code_logo_grassroots.svg.png") %>% image_resize("120x120") # 计算每个树形区域的坐标并合并到数据框 tm_coords <- treemapify(df, area = "area") df <- cbind(df, tm_coords) # 将图标转为grid的grob对象 df$icon_grob <- list(rasterGrob(icon_crops2), rasterGrob(icon_forest2), rasterGrob(icon_greenland2)) # 绘制基础树形图 p <- ggplot(df, aes(area = area, fill = category)) + geom_treemap() + geom_treemap_text(aes(label = paste(category, label, sep = "\n")), colour = "black", place = "center", size = 5) + theme(legend.position = "none") # 逐个添加图标到对应区域 for(i in 1:nrow(df)) { p <- p + annotation_custom( grob = df$icon_grob[[i]], xmin = df$xmin[i], xmax = df$xmax[i], ymin = df$ymin[i], ymax = df$ymax[i] ) } # 展示图形 print(p)
方法二:使用ggimage包简化操作
ggimage包可以直接在ggplot中添加图片,无需手动处理Grob对象,步骤更简洁:
# 加载所需包 library(treemapify) library(ggplot2) library(ggimage) # 创建数据框 df <- data.frame(category = c("forest", "greenland", "crops"), area = c(20, 10, 70), # 直接存储图标URL icon_url = c( "https://upload.wikimedia.org/wikipedia/commons/thumb/7/79/Agriculture_-_The_Noun_Project.svg/512px-Agriculture_-_The_Noun_Project.svg.png", "https://upload.wikimedia.org/wikipedia/commons/thumb/d/da/BSicon_FOREST.svg/500px-BSicon_FOREST.svg.png", "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2b/Wikidata_Morse_code_logo_grassroots.svg/600px-Wikidata_Morse_code_logo_grassroots.svg.png" ) ) df$label = paste0(df$area,"%") # 计算树形区域坐标 tm_coords <- treemapify(df, area = "area") df <- cbind(df, tm_coords) # 绘制带图标的树形图 ggplot(df, aes(area = area, fill = category)) + geom_treemap() + geom_treemap_text(aes(label = paste(category, label, sep = "\n")), colour = "black", place = "center", size = 5) + # 在每个区域中心添加图标,size参数控制图标大小 geom_image(aes(x = (xmin + xmax)/2, y = (ymin + ymax)/2, image = icon_url), size = 0.15) + theme(legend.position = "none")
注意事项
- 图标尺寸可通过
image_resize()(方法一)或size参数(方法二)调整,以匹配树形区域的大小; - 如果使用本地图标文件,只需将URL替换为本地文件路径即可。
内容的提问来源于stack exchange,提问作者Julian
相关产品推荐
相关产品推荐

