为何scales::trans_new实现常量加法变换在ggplot中失效?
关于scales::trans_new常量加法变换失效的问题分析
问题背景
我使用scales::trans_new实现立方根变换时运行正常,但尝试实现一个简单的常量加法变换(变换逻辑为x + 200,逆变换为x - 200)却没有效果。目前我已经通过scale_y_continuous配合自定义断点实现了y轴的逆变换,但想搞清楚trans_new方案失效的原因。
参考的立方根变换代码(正常运行)
trans_cube <- trans_new(name = "cube root", transform = cube_root, inverse = cube) # 测试数据 plot_data <- data.frame(x = 1:10, y = cube(1:10)) # 未应用变换的绘图 ggplot(plot_data, aes(x = x, y = y)) + geom_point() # 应用立方根变换的绘图 ggplot(plot_data, aes(x = x, y = y)) + geom_point() + coord_trans(y = trans_cube)
失效的常量变换代码
trans_add <- trans_new(name = "add", transform = function(x) x + 200, inverse = function(x) x -200) ggplot(plot_data, aes(x = x, y = y)) + geom_point() + coord_trans(y = trans_add )
已实现的逆变换代码(通过scale_y_continuous)
fun_sc_back <- function(x){x*187+266} # 逆变换(用于标签显示) fun_sc <- function(x){(x-266)/187} # 变换(用于计算断点) p_tr + scale_y_continuous(breaks = fun_sc(c(250, 500, 750)), labels = fun_sc_back)
失效原因
核心问题出在coord_trans的作用逻辑上:
coord_trans()是对整个坐标系做变换:先将原始数据通过transform函数转换,再绘图;然后将坐标轴的刻度值通过inverse函数转换回去,作为轴标签显示。- 对于常量加法这种平移变换,数据平移后绘图,坐标轴刻度又会通过逆变换平移回原位置,视觉上所有点和轴的相对位置完全没变,所以看起来像是变换没生效。
- 而立方根变换属于非线性变换,数据变换后绘图的形状会改变,轴标签逆变换后也能体现出刻度的非线性,所以能看到明显效果。
正确的实现方式
如果你的需求是让y轴显示逆变换后的刻度(数据本身位置不变),应该把自定义变换应用到scale_y_continuous()的trans参数上,而不是coord_trans():
trans_add <- trans_new(name = "add", transform = function(x) x + 200, inverse = function(x) x - 200) ggplot(plot_data, aes(x = x, y = y)) + geom_point() + scale_y_continuous(trans = trans_add)
这个逻辑是:数据保持原始位置不变,坐标轴的刻度按照transform函数计算,然后用inverse函数转换为标签显示,正好符合你要的逆变换显示需求。
内容的提问来源于stack exchange,提问作者Lefty
相关产品推荐
相关产品推荐

