r - R/ggplot2 : Collapse or remove segment of y-axis from scatter-plot

标签 r ggplot2 scatter-plot

我正在尝试使用ggplot2在R中绘制散点图,其中y轴的中心被折叠或移除,因为那里没有数据。我是在下面的photoshop中完成的,但是有没有办法用ggplot创建类似的图呢?
这是具有连续范围的数据:enter image description here

但是我正在尝试做这样的事情:
enter image description here

这是代码:

ggplot(data=distance_data) +
    geom_point(
        aes(
            x = mdistance,
            y = maxZ,
            shape = factor(subj),
            color = factor(side),
            size = (cSA)
        )
    ) +
    scale_size_continuous(range = c(4, 10)) +
    theme(
        axis.text.x = element_text(colour = "black", size = 15),
        axis.text.y = element_text(colour = "black", size = 15),
        axis.title.x = element_text(colour = "black", size= 20, vjust = 0),
        axis.title.y = element_text(colour = "black", size= 20),
        legend.position = "none"
    ) +
    ylab("Z-score") +
    xlab("Distance")

最佳答案

您可以通过定义坐标变换来做到这一点。一个标准示例是对数坐标,可以使用ggplotscale_y_log10()中实现。
但是,您还可以通过将trans参数提供给scale_y_continuous()(以及类似地scale_x_continuous())来定义自定义转换函数。为此,您可以使用trans_new()包中的函数scales。它以变换函数及其逆为参数。
我首先讨论用于OP的示例的特殊解决方案,然后还说明如何将其推广。
OP的例子
OP希望缩小-2和2之间的间隔。下面定义了一个函数(及其逆函数),该函数将该间隔缩小4倍:

library(scales)
trans <- function(x) {
  ifelse(x > 2, x - 1.5, ifelse(x < -2, x + 1.5, x/4))
}
inv <- function(x) {
  ifelse(x > 0.5, x + 1.5, ifelse(x < -0.5, x - 1.5, x*4))
}
my_trans <- trans_new("my_trans", trans, inv)
这定义了转换。为了查看实际效果,我定义了一些样本数据:
x_val <- 0:250
y_val <- c(-6:-2, 2:6)
set.seed(1234)
data <- data.frame(x = sample(x_val, 30, replace = TRUE),
                   y = sample(y_val, 30, replace = TRUE))
我首先将其绘制而无需进行转换:
p <- ggplot(data, aes(x, y)) + geom_point()
p + scale_y_continuous(breaks = seq(-6, 6, by = 2))
enter image description here
现在,我将scale_y_continuous()与转换一起使用:
p + scale_y_continuous(trans = my_trans,
                       breaks = seq(-6, 6, by = 2))
enter image description here
如果要进行其他转换,则必须更改trans()inv()的定义,然后再次运行trans_new()。您必须确保inv()确实是inv()的反函数。我检查如下:
x <- runif(100, -100, 100)
identical(x, trans(inv(x)))
## [1] TRUE
通用解决方案
下面的函数定义了一个转换,您可以在其中选择要压缩的区域的上下两端以及要使用的系数。它直接返回可以在trans内部使用的scale_y_continuous对象:
library(scales)
squish_trans <- function(from, to, factor) {
  
  trans <- function(x) {
    
    if (any(is.na(x))) return(x)

    # get indices for the relevant regions
    isq <- x > from & x < to
    ito <- x >= to
    
    # apply transformation
    x[isq] <- from + (x[isq] - from)/factor
    x[ito] <- from + (to - from)/factor + (x[ito] - to)
    
    return(x)
  }

  inv <- function(x) {
    
    if (any(is.na(x))) return(x)

    # get indices for the relevant regions
    isq <- x > from & x < from + (to - from)/factor
    ito <- x >= from + (to - from)/factor
    
    # apply transformation
    x[isq] <- from + (x[isq] - from) * factor
    x[ito] <- to + (x[ito] - (from + (to - from)/factor))
    
    return(x)
  }
  
  # return the transformation
  return(trans_new("squished", trans, inv))
}
trans()inv()的第一行处理使用x = c(NA, NA)调用转换的情况。 (当我最初编写此问题时,似乎ggplot2的版本没有发生这种情况。不幸的是,我不知道此startet使用哪个版本。)
现在可以使用此功能方便地从第一部分重做绘图:
p + scale_y_continuous(trans = squish_trans(-2, 2, 4),
                       breaks = seq(-6, 6, by = 2))
以下示例显示您可以在任意位置挤压比例尺,这对于除点以外的其他几何图形也适用:
df <- data.frame(class = LETTERS[1:4],
                 val = c(1, 2, 101, 102))
ggplot(df, aes(x = class, y = val)) + geom_bar(stat = "identity") +
  scale_y_continuous(trans = squish_trans(3, 100, 50),
                     breaks = c(0, 1, 2, 3, 50, 100, 101, 102))
enter image description here
最后,我要强调评论中已经提到的其他内容:这种情节可能会产生误导,应谨慎使用!

关于r - R/ggplot2 : Collapse or remove segment of y-axis from scatter-plot,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35511951/

相关文章:

r - 如何在每两列值之间制作合并热图

R:使用函数将新列添加到数据框

r - 从 ggvoronoi 中提取多边形的面积

Python - 当行索引和列都是类别时数据帧值的散点图

javascript - nvd3 散点图的自定义 x 轴工具提示

python - 同一轴上的多个散点图

R编程,使用变量命名输出文件

ggplot2 - 使用 facet_grid 以公共(public)多边形作为叠加层绘制多个空间多边形

R ggplot2 : Points, 图中的线条和误差线重叠不一致

r - 将 save_kable() 保存为白色背景的 png,而不是默认的灰色