You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

geom_scatterpie_legend()的labeller参数未生成预期标签问题

问题描述

我正在绘制一张展示采样情况的世界散点饼图。饼图半径由Plot3.dat$lradius设置,该值是log(Plot3.dat$radius + 1)的计算结果。我希望图例标签使用原尺度而非对数尺度,因此尝试通过geom_scatterpie_legend()的labeller参数对标签进行反变换,但生成的标签不符合预期:预期为1、30、150、750,实际得到0、6、54、402。在另一台机器运行代码结果一致。

原代码

ggplot() +
  geom_polygon(data = countries, 
               aes(x = long, y = lat, group = group), 
               colour = "black", fill = NA) +
  geom_scatterpie(data = Plot3.dat, 
                  aes(x = long, y = lat, r = lradius), 
                  sorted_by_radius = T, 
                  cols = c("Prop.carn", "Prop.herb", "Prop.om")) +
  geom_scatterpie_legend(c(log(2), log(31), log(151), log(751)), 
                         x = -150.54, y = -50, n = 4, 
                         labeller = function(x) round(exp(x) - 1, digits = 0))

问题现象

生成的图例标签显示为0、6、54、402,与预期的1、30、150、750不符。

数据

Plot3.dat <- structure(list(Country = structure(1:28, levels = c("Australia", 
"Belgium", "Cambodia", "Canada", "Ecuador", "England", "Ethiopia", 
"France", "French Polynesia", "Germany", "India", "Indonesia", 
"Iran", "Israel", "Japan", "Malaysia", "Mexico", "Mongolia", 
"Morocco", "New Zealand", "Pakistan", "Philipines", "Spain", 
"Switzerland", "Thailand", "United Kingdom", "United States of America", 
"Wales"), class = "factor"), Carnivore = c(566L, 0L, 0L, 0L, 
2L, 0L, 3L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 147L, 
0L, 0L, 0L, 1L, 0L, 0L, 88L, 0L), Herbivore = c(242L, 0L, 0L, 
34L, 0L, 0L, 0L, 5L, 0L, 0L, 0L, 0L, 0L, 3L, 0L, 0L, 0L, 0L, 
0L, 46L, 0L, 0L, 0L, 0L, 0L, 0L, 79L, 0L), Omnivore = c(130L, 
1L, 24L, 2L, 0L, 161L, 0L, 5L, 1L, 17L, 409L, 5L, 6L, 0L, 4L, 
11L, 4L, 2L, 1L, 728L, 278L, 4L, 6L, 0L, 27L, 10L, 282L, 1L), 
    lat = c(-25.2744, 50.5039, 12.5657, 56.1304, -1.8312, 52.3555, 
    9.145, 46.2276, -17.6797, 51.1657, 20.5937, -0.7893, 32.4279, 
    31.0461, 36.2048, 4.2105, 23.6345, 46.8625, 31.7917, -40.9006, 
    30.3753, 12.8797, 40.4637, 46.8182, 15.87, 55.3781, 37.0902, 
    52.1307), long = c(133.7751, 4.4699, 104.991, -106.3468, 
    -78.1834, -1.1743, 40.4897, 2.2137, -149.4068, 10.4515, 78.9629, 
    113.9213, 53.688, 34.8516, 138.2529, 101.9758, -102.5528, 
    103.8467, -7.0926, 174.886, 69.3451, 121.774, -3.7492, 8.2275, 
    100.9925, -3.436, -95.7129, -3.7837), Prop.carn = c(0.603411513859275, 
    0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.159609120521173, 
    0, 0, 0, 1, 0, 0, 0.195991091314031, 0), Prop.herb = c(0.257995735607676, 
    0, 0, 0.944444444444444, 0, 0, 0, 0.5, 0, 0, 0, 0, 0, 1, 
    0, 0, 0, 0, 0, 0.0499457111834962, 0, 0, 0, 0, 0, 0, 0.175946547884187, 
    0), Prop.om = c(0.138592750533049, 1, 1, 0.0555555555555556, 
    0, 1, 0, 0.5, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0.790445168295331, 
    1, 1, 1, 0, 1, 1, 0.628062360801782, 1), radius = c(938, 
    1, 24, 36, 2, 161, 3, 10, 1, 17, 409, 5, 6, 3, 4, 11, 4, 
    2, 1, 921, 278, 4, 6, 1, 27, 10, 449, 1), lradius = c(6.84481547920826, 
    0.693147180559945, 3.2188758248682, 3.61091791264422, 1.09861228866811, 
    5.08759633523238, 1.38629436111989, 2.39789527279837, 0.693147180559945, 
    2.89037175789616, 6.01615715969835, 1.79175946922805, 1.94591014905531, 
    1.38629436111989, 1.6094379124341, 2.484906649788, 1.6094379124341, 
    1.09861228866811, 0.693147180559945, 6.82654522355659, 5.63121178182137, 
    1.6094379124341, 1.94591014905531, 0.693147180559945, 3.3322045101752, 
    2.39789527279837, 6.10924758276437, 0.693147180559945)), row.names = c(NA, 
-28L), class = "data.frame")
解决方案

问题核心是对geom_scatterpie_legend()的参数逻辑理解偏差:你传入的对数尺度值不会直接传给labeller,labeller处理的是函数自动生成的等分刻度,而非你指定的点。

正确的修改方式是直接传入原尺度的目标标签值,通过r_scale参数完成对数转换,匹配饼图的半径逻辑:

ggplot() +
  geom_polygon(data = countries, 
               aes(x = long, y = lat, group = group), 
               colour = "black", fill = NA) +
  geom_scatterpie(data = Plot3.dat, 
                  aes(x = long, y = lat, r = lradius), 
                  sorted_by_radius = T, 
                  cols = c("Prop.carn", "Prop.herb", "Prop.om")) +
  geom_scatterpie_legend(c(1, 30, 150, 750), 
                         x = -150.54, y = -50, 
                         r_scale = function(x) log(x + 1))

关键说明

  • r_scale负责将原尺度的标签值转换为绘图用的对数半径,和你计算lradius的逻辑完全一致;
  • 传入的c(1,30,150,750)会直接作为图例标签,无需额外反变换;
  • 移除n=4参数,因为已经明确指定了四个刻度值,不需要自动生成。

内容的提问来源于stack exchange,提问作者Pat Taggart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 01:19:56