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

如何使用colorspace包的scale_fill_continuous_divergingx实现一端线性一端对数的不平衡发散色阶?

Absolutely! You can achieve this custom diverging scale with colorspace::scale_fill_continuous_divergingx by building a piecewise transformation—using a log scale for p-values below 0.05 and a linear scale for values above it. This keeps both ranges readable while clearly anchoring the 0.05 midpoint. Here's how to implement it:


Step 1: Define a Custom Piecewise Transformation

We need a transformation that treats values below and above 0.05 differently, while ensuring the 0.05 midpoint aligns perfectly with the diverging color scale's center. We'll use scales::trans_new() to create this:

library(scales)
library(dplyr)

# Create a custom transformation for p-values
p_piecewise_trans <- trans_new(
  name = "p_piecewise",
  transform = function(x) {
    case_when(
      # Log-transform values below 0.05 (relative to midpoint to center at 0)
      x < 0.05 ~ log10(x / 0.05),
      # Linear-transform values above 0.05 (scaled to span [0,1] relative to midpoint)
      x >= 0.05 ~ (x - 0.05) / (1 - 0.05)
    )
  },
  inverse = function(y) {
    case_when(
      # Reverse log transform for negative values
      y < 0 ~ 0.05 * 10^y,
      # Reverse linear transform for positive values
      y >= 0 ~ 0.05 + y * (1 - 0.05)
    )
  },
  # Generate readable breaks: log breaks for small p-values, linear for large
  breaks = function(x) {
    log_breaks <- log_breaks()(x[x < 0.05])
    linear_breaks <- seq(0.05, max(x[x >= 0.05]), by = 0.2)
    unique(c(log_breaks, linear_breaks))
  },
  # Format labels for readability: scientific notation for small p-values
  format = function(x) {
    ifelse(x < 0.05, format(x, scientific = TRUE, digits = 2), format(x, digits = 2))
  }
)

Step 2: Apply the Transformation to Your Plot

Now plug this custom transformation into scale_fill_continuous_divergingx, setting mid = 0.05 to anchor the color scale's center exactly at your threshold:

library(ggplot2)
library(colorspace)

ggplot(df, aes(x = factor(group), y = factor(name), fill = p_adjusted)) + 
  geom_tile(color = "white", size = 0.5) +  # Add white borders to distinguish tiles
  scale_fill_continuous_divergingx(
    name = "Adjusted p-value",
    mid = 0.05,
    palette = "RdYlBu",
    trans = p_piecewise_trans,
    guide = guide_colorbar(title.position = "top", title.hjust = 0.5)
  ) +
  theme_classic() +
  labs(x = "Group", y = "Feature") +
  theme(
    legend.position = "bottom",
    legend.key.width = unit(3, "cm")  # Widen color bar to improve readability of breaks
  )

Why This Fixes Your Previous Issues

  • Default linear scale: Compresses tiny p-values into an indistinguishable range—this log/linear split pulls apart small values while keeping larger ones distinct.
  • Tweaking p1/p2/p3/p4: These parameters adjust global scale steepness, but can't create a true piecewise split between log and linear behavior.
  • Global log transform: Squashes all values above 0.05 into a tiny sliver of the color bar—our piecewise approach preserves linearity for larger p-values so they remain readable.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 12:52:32