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

ggplot2中围绕1的镜像(居中)对数轴实现方案问询

自定义镜像坐标轴实现方案

要实现围绕1的镜像轴(大于1用log10变换,小于1用反向平方根变换),核心是自定义ggplot2的坐标轴变换函数,不用修改原始数据,直接对坐标轴映射逻辑做调整。

步骤说明

  1. 自定义变换规则:

    • 比值>1的部分:保留log10变换,将x映射为log10(x)
    • 比值<1的部分:用反向平方根变换,将x映射为-sqrt(1/x - 1)(负号用于让小于1的数值在1的左侧对称分布)
    • 比值=1时,映射为0
  2. 用scales::new_transformation创建自定义变换,同时定义逆变换(用于从坐标轴位置还原原始比值)、刻度生成和标签格式化逻辑。

完整可复现代码

library(ggplot2)
library(scales)
library(dplyr)

# 自定义镜像变换
mirror_trans <- function() {
  trans_new(
    name = "mirror_log_sqrt",
    transform = function(x) {
      case_when(
        x > 1 ~ log10(x),
        x < 1 ~ -sqrt(1/x - 1),
        TRUE ~ 0
      )
    },
    inverse = function(x) {
      case_when(
        x > 0 ~ 10^x,
        x < 0 ~ 1/(1 + x^2),
        TRUE ~ 1
      )
    },
    breaks = function(x) {
      # 手动设置合理刻度:1附近的精细刻度 + 极值刻度
      c(0.001, 0.1, 0.75, 0.88, 0.95, 1, 1.15, 1.3, 2, 2.5, 99)
    },
    format = function(x) {
      # 保持原始数值的标签显示
      as.character(x)
    }
  )
}

# 示例数据
SampleData <- data.frame(CaseID = letters[1:10], 
                         Ratio = c(0.1, 0.95, 1.3, 2, 99, 0.88, 0.001, 1.15, 2.5, 0.75))

# 绘图
SampleData %>% 
  ggplot(aes(x = Ratio, y = CaseID)) + 
  geom_point(size = 2) +
  geom_vline(xintercept = 1, linetype = "dashed", color = "red") +
  theme_bw() +
  scale_x_continuous(trans = mirror_trans(), 
                     name = "Ratio (mirror transformed)") +
  # 自定义刻度标签,避免重叠
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

效果说明

  • 大于1的数值(如1.15、1.3、2、99)依然用log10变换,保留了极值间的分辨率
  • 小于1的数值(如0.75、0.88、0.95、0.1、0.001)通过反向平方根变换,放大了0.75-1之间的差异,解决了log10变换下这部分数值挤在一起的问题
  • 所有变换仅作用于坐标轴映射,原始Ratio数据完全未修改

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 06:45:59