如何在同一X轴上的同一面板上绘制具有两个不同y轴范围的点?

时间:2015-02-26 05:34:23

标签: r ggplot2 axes multiple-axes

我正在尝试使用共享X轴但具有两个不同比例的Y轴的ggplot创建散点图。

Y轴的底部有三个刻度,从0%到0.1%,然后是0.1%到1%,最后是规则间隔10%。

来自here的示例:

enter image description here

有没有办法在R中使用ggplot生成这样的东西? 我会修改轴吗?在同一个面板上覆盖几个地块?或者是其他东西?

1 个答案:

答案 0 :(得分:3)

由于this question中探讨的原因,不建议在ggplot2中使用不连续的轴。 Hadley Wickham(ggplot2的创建者)解释了here

  

我不是这种显示器的忠实粉丝   因为我认为它在视觉上是扭曲的。我认为还有更多   适合显示两个图 - 一个是所有数据,另一个是   小的价值观。那样你就可以看到大值了多少   支配较小的那些。

然而,确实有可能!你必须创建一个自定义轴转换,这不适合胆小的人。

这是一个例子。假设我们有y在对数正态范围内的数据。

set.seed(20)
dat <- data.frame(x = c(0, rnorm(50)), y = c(0, exp(rnorm(50, -2, 1.5))))
ggplot(dat, aes(x, y)) + geom_point()

original

许多点在底部附近拥挤:假设我想将所有值置于对数刻度下的1以下,并且将线性刻度上的值置于1以上。因此,我创建了一个名为combine_trans的自定义转换,它将对数比例与线性比例(不是完全上面的示例图表组合在一起,因为它看似去到0,但它可能足够接近了。

combine_trans <- function(breakpoint, tr1, tr2,
                          br1 = tr1$breaks,
                          br2 = tr2$breaks) {
    # combine two transformations.
    # can also be given functions to determine tick marks
    trans_breakpoint <- tr1$transform(breakpoint)
    trans <- function(x) {
        # choose which transformation to apply
        ifelse(x < breakpoint,
               tr1$transform(x),
               tr2$transform(x - breakpoint) - trans_breakpoint)
    }
    inv <- function(x) {
        # inverse of both transformations
        ifelse(x < trans_breakpoint,
               tr1$inverse(x),
               breakpoint + tr2$inverse(x + trans_breakpoint))
    }
    br <- function(x) {
        # combine break choices from both scales
        br1 <- br1(c(x[x < breakpoint], breakpoint))
        br2 <- br2(c(breakpoint, max(x[x > breakpoint])))
        br <- c(br1, br2)
        br[br > 0]
    }
    # combine domains
    dom <- c(max(tr1$domain[1], tr2$domain[1]), min(tr1$domain[2], tr2$domain[2]))
    trans_new("combined", trans, inv, breaks = br, domain = dom)
}

# combine log10 transformation and identity transformation
combined <- combine_trans(1, log10_trans(), identity_trans())

ggplot(dat, aes(x, y)) +
    geom_point() +
    scale_y_continuous(trans = combined) +
    geom_hline(yintercept = 1, lty = 2)

enter image description here

注意我手动添加了geom_hline的水平虚线,这至少有助于引起对不连续性的注意。

你可以看到另一个不连续变换的例子here,它在轴上引入了一个简单的断点。

请注意,此代码很复杂,可能需要自定义。更重要的是,它仍然有些误导:一般来说,您应该将数据划分为单独的图表,或者将所有内容放在日志范围内。尽管如此,值得一提的是ggplot2可让您访问这些工具,即使您在脚下拍摄自己也是如此。和他们在一起!