【问题标题】:two y-axes with different scales for two datasets in ggplot2 [duplicate]ggplot2中两个数据集的两个具有不同比例的y轴[重复]
【发布时间】:2018-08-17 13:01:21
【问题描述】:

我有两个数据集(可以合并为一个),它们共享共同的 x 值,而 y 值不同 - 我想在一个数据集中绘制 y 值并将 y 轴放在左侧绘图,同时在另一个数据集中绘制 y 值,并将 y 轴放在同一绘图的右侧。当然,两个y轴值的相对比例是不同的(实际上应该根据第一个数据集中的y值“调整”。两个数据集中的点会用不同的颜色来区分两个比例.

一个例子如下所示:

d1 = data.frame(x=c(100, 200, 300, 400), y=seq(0.1, 0.4, by=0.1)) # 1st dataset
d2 = data.frame(x=c(100, 200, 300, 400), y=seq(0.8, 0.5, by=-0.1)) # 2nd dataset
p1 = ggplot(data = d1, aes(x=x, y=y)) + geom_point()
p2 = ggplot(data = d2, aes(x=x, y=y)) + geom_point() +
  scale_y_continuous(position = "right")
p1
p2

ggplot2 中,我不能执行p1+p2,因为它会显示错误消息Error: Don't know how to add o to a plot。请帮忙。谢谢!

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    首先,这种类型的图表很好地说明了为什么要花这么长时间才能将第二个轴放入ggplot2:它很容易令人困惑,导致误解。因此,我将在这里竭尽全力提供多种指标来说明什么是去向。

    首先,sec_axis的使用需要在原轴上进行变换。这通常以截距/斜率公式的形式完成,例如~ 2*. + 10,其中句点表示要缩放的值。在这种情况下,我认为我们可以简单地使用~ 2*.

    但是,这意味着您需要在原始轴上绘制所有数据,这意味着您需要将 d2$y 预缩放到 d1$y 的限制。很简单,您只需要像sec_axis 中使用的那样进行反向转换。

    不过,为了使用 ggplot2 的分组,我将把数据合并到一个 data.frame 中。

    d1 = data.frame(x=c(100, 200, 300, 400), y=seq(0.1, 0.4, by=0.1)) # 1st dataset
    d2 = data.frame(x=c(100, 200, 300, 400), y=seq(0.8, 0.5, by=-0.1)) # 2nd dataset
    d1$z <- "data1"
    d2$z <- "data2"
    d3 <- within(d2, { y = y/2 })
    d4 <- rbind(d1, d3)
    d4
    #     x    y     z
    # 1 100 0.10 data1
    # 2 200 0.20 data1
    # 3 300 0.30 data1
    # 4 400 0.40 data1
    # 5 100 0.40 data2
    # 6 200 0.35 data2
    # 7 300 0.30 data2
    # 8 400 0.25 data2
    

    为了控制所有组件的颜色,我会手动设置:

    mycolors <- c("data1"="blue", "data2"="red")
    

    最后,剧情:

    library(ggplot2)
    ggplot(d4, aes(x=x, y=y, group=z, color=z)) +
      geom_path() +
      geom_point() +
      scale_y_continuous(name="data1", sec.axis = sec_axis(~ 2*., name="data2")) +
      scale_color_manual(name="z", values = mycolors) +
      theme(
        axis.title.y = element_text(color = mycolors["data1"]),
        axis.text.y = element_text(color = mycolors["data1"]),
        axis.title.y.right = element_text(color = mycolors["data2"]),
        axis.text.y.right = element_text(color = mycolors["data2"])
      )
    

    不过,坦率地说,我不喜欢不同的斜坡。也就是说,蓝轴上的两个块是 0.1,而红轴上的两个块是 0.2。如果您谈论的是两个截然不同的“事物”,那么这可能没问题。但是,如果两条线的斜率可以直接比较,那么您可能更愿意保持每个块的大小相同。为此,我们将使用仅截距的变换,斜率没有变化。这意味着 in-data.frame 转换可以是 y = y - 0.4,而绘图补充 ~ . + 0.4,产生:

    PS:来自https://stackoverflow.com/a/45683665/3358272https://stackoverflow.com/a/6920045/3358272的提示

    【讨论】:

    • 这实际上是一个很好的例子,说明为什么双轴图如此具有误导性。在同一轴上绘图,您会看到线条甚至没有交叉……大脑不禁将向上交叉解释为一组变得“大于”,即使轴上显示了值。
    • 同意。我真的希望这个例子真的适用于第二个轴有意义的真实数据集。但归根结底,我同意,这些情节很容易误导。
    猜你喜欢
    • 2018-12-05
    • 1970-01-01
    • 2019-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-20
    • 2021-11-26
    • 1970-01-01
    相关资源
    最近更新 更多