R更新后ggplot用trans_new()实现x轴立方根缩放报错求助
ggplot2 X轴立方根缩放报错的原因及解决办法
报错原因
- 自定义变换函数的缺陷:原代码中直接用
x^(1/3)计算立方根,在R中负数的1/3次方会返回复数(例如(-1)^(1/3)结果为复数),而非实数,这会导致变换后产生NA或非有限值,触发zero_range函数的判断错误(需要TRUE/FALSE值却得到缺失值)。 - 分面自由缩放的影响:
facet_wrap(~site + SYear, scales = "free")会让每个面板独立计算x轴范围,若某面板的x值范围经过错误变换后出现异常,会进一步触发该报错。
解决方案:修复自定义立方根变换函数
修改变换函数,确保对负数返回实数立方根,同时避免复数生成:
# 修复后的立方根变换函数 transform_cuberoot = function(){ trans_new('cuberoot', transform = function(x) sign(x) * abs(x)^(1/3), # 处理负数,返回实数 inverse = function(x) x^3, breaks = c(0, 0.01, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0), domain = c(-Inf, Inf)) }
使用原代码的scale_x_continuous调用这个修复后的函数即可,无需更换为coord_trans。这样既保留所有绘图元素(包括y=0的虚线、坐标轴),也不会产生无穷值警告。
关于coord_trans的问题说明
使用coord_trans(x = transform_cuberoot())出现元素丢失和警告,是因为该函数会对整个坐标系进行变换,包括geom_hline等元素的坐标。当变换产生无穷值时,这些元素会被挤出可视区域,同时触发"Transformation introduced infinite values"警告。因此优先使用scale_x_continuous的trans参数,仅对轴刻度和数据映射进行变换,而非整个坐标系。
完整可运行代码示例
结合你的数据和修复后的变换函数,完整代码如下:
library(ggplot2) library(scales) # 修复后的立方根变换 transform_cuberoot = function(){ trans_new('cuberoot', transform = function(x) sign(x) * abs(x)^(1/3), inverse = function(x) x^3, breaks = c(0, 0.01, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0), domain = c(-Inf, Inf)) } # 示例数据 df <- structure(list(site = c("US", "US", "US", "US", "US", "US"), Transect = c(1L, 1L, 1L, 1L, 1L, 1L), Plot = c(100L, 103L, 106L, 109L, 112L, 115L), Year = c(2020L, 2020L, 2020L, 2020L, 2020L, 2020L), SYear = c("2020-2021", "2020-2021", "2020-2021", "2020-2021", "2020-2021", "2020-2021"), E.Delta = c(-0.0380000000000109, -0.0930000000000746, -0.0950000000000273, -0.0709999999999127, -0.104000000000042, -0.0989999999999327), I = c(1, 1, 1, 1, 1, 1), AllRtedPctCov = c(0, 0, 0, 0, 0, 0), NoRtedVeg = c(1, 1, 1, 1, 1, 1), PerCov.15 = structure(c(1L, 1L, 1L, 1L, 1L, 1L), levels = c("0", "1"), class = "factor")), row.names = c(NA, 6L), class = "data.frame") # 绘图代码 ggplot(df, aes(x = I, y = E.Delta, color = PerCov.15)) + geom_point(size = 1.5) + facet_wrap(~site + SYear, scales = "free") + theme_classic() + geom_hline(yintercept = 0, linetype = "dashed", color = "red") + labs(x = "Inundation-Duration", y = "Change in Elevation", color =" Percent Rooted Cover") + scale_colour_brewer(labels= c("<15%", ">15%"), type = "qual", palette = 3) + theme(axis.title.x = element_text(size = 16, vjust = -2), axis.title.y = element_text(size = 16, vjust = 5), legend.title = element_text(size = 16), legend.text = element_text(size = 16), strip.background = element_blank(), strip.text = element_text(size = 18), axis.text = element_text(size = 14), plot.margin = unit(c(2,2,2,2), "cm"), panel.spacing = unit(3, "lines"))+ scale_x_continuous(trans = transform_cuberoot(), breaks = c(0, 0.01, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0), labels=c(0, 0.01, 0.1, " ", 0.3, " ", " ", 0.6, " ", " ", " ", 1.0))
内容的提问来源于stack exchange,提问作者Cat
相关产品推荐
相关产品推荐

