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
相关产品推荐
相关产品推荐

