R ggplot结合fontawesome绘制饼图时特定图例图标不显示
问题原因
图标渲染失败核心是三个配置错误,和饼图绘制逻辑无关:
- 码点和加载的FontAwesome版本不匹配:
emojifont::load.fontawesome()默认加载的是FontAwesome 4.7版本webfont,你代码里写的\UF390(桌面)、\UE527(手机)、\UF3FC(平板)都是FontAwesome 5及以上版本才新增的码点,4.7版本字体文件里没有对应字形,替换成旧版已有的电视图标能正常显示就是这个原因。 - 自定义图例函数参数传错:
grid::textGrob调用时把x、y位置和尺寸参数全部填成0.33,就算图标存在也会偏移出图例区域、大小异常,看起来和没显示一样。 - 符号匹配逻辑冗余:原来写的
match.arg匹配方式在色板顺序调整时很容易出现图标和类别错配的问题。
修复步骤
- 替换为FontAwesome免费版通用的三个设备图标码点,兼容4.7版本字体:
- 桌面(Desktop):
\UF108 - 移动端(Mobile):
\UF10B - 平板(Tablet):
\UF10A
- 修正
draw_key_symbol函数的参数,把图标放在图例键居中位置,设置合适大小,用正确的字体族名 - 简化图标匹配逻辑,直接根据当前图层的fill值取对应图标,避免错配
修复后完整可运行代码
library(tidyverse) library(grid) library(emojifont) library(scales) library(fontawesome) load.emojifont("OpenSansEmoji.ttf") load.fontawesome() device <- data.frame( Device = c("Desktop","Mobile", "Tablet"), Proportion = c(45.7,50,4.3), symbols = c("\UF108","\UF10B","\UF10A") ) # 定义色板 pal <- scales::hue_pal()(3) names(pal) <- c("Desktop", "Mobile", "Tablet") # 定义图标映射 symbols <- c("\UF108", "\UF10B","\UF10A") names(symbols) <- c("Desktop", "Mobile", "Tablet") # 修正自定义图例符号绘制逻辑 draw_key_symbol <- function(data, params, size) { label <- symbols[data$fill] grid::textGrob( label = label, x = 0.5, y = 0.5, gp = grid::gpar( col = data$fill, fontfamily = "FontAwesome", fontsize = 14 ) ) } ggplot(device, aes(x = "", Proportion, fill = Device)) + geom_bar(width = 1, stat = "identity", key_glyph = "symbol") + scale_fill_manual(values = pal) + coord_polar("y") + labs(x = NULL, y = NULL)+ theme( axis.text = element_blank(), axis.ticks = element_blank(), panel.grid = element_blank() )+ geom_text( aes(label = paste0(Proportion,"%")), position = position_stack(vjust = 0.5) )
可选优化
如果需要用新版FontAwesome的样式,不需要手动处理Unicode码点和字体加载,可以直接调用fontawesome包自带的fa()函数生成图标grob,从根源避免码点和版本不匹配的问题。
内容的提问来源于stack exchange,提问作者awz1
相关产品推荐
相关产品推荐

