在ggplot 2中还原次级y缩放

时间:2018-08-06 14:36:18

标签: r ggplot2

我有以下数据框:

observed <- c("1000","2000","3000","4000")
simulated <- c("1100","2100","3100","4100")
error <- c("-1","-2","-0.5","-4")
Date <- c("2013-01-01","2013-01-02","2013-01-03","2013-01-04")
y <- data.frame(Date,observed,simulated,error)
y[-1] <- sapply(y[-1], as.character)
y[-1] <- sapply(y[-1], as.numeric)
y$Date <- as.Date(y$Date, format="%Y-%m-%d")

在左y轴上将其与模拟的每日河水流量进行观察比较,并在右y轴上显示百分比的相关差异(请注意,此处的百分比只是示例,未正确计算)。

我想将所有三个绘制在一张图中,百分比误差绘制在次要y轴上。我使用了以下代码:

p<-ggplot(y, aes(x=Date))
p<-p + geom_line(aes(y=observed, colour = "observed"), size=1.5)
p<-p + geom_line(aes(y=simulated, colour = "simulated"), size=1.5)
p<-p + geom_line(aes(y=error*-500, colour="red"), size=1.5)

p<-p + scale_colour_manual(name="Discharge [m3/sec]", labels=c("observed","simulated","error"), values = c("blue", "black","red"))
p <- p + scale_y_continuous(sec.axis = sec_axis(~./-500,name = "Error [%]"))
p <- p + labs(y=expression(paste('Q [',m^3~s^-1,']'),
                       colour = "Parameter"))
p <- p + theme(legend.position = c(0.2, 0.87), legend.title=element_blank(),axis.title.x=element_blank())

我的问题是次要y轴从-8开始,从上到下下降到0。我想拥有的是次要y轴的零在顶部,而-8是在底部,而第一个y轴(左)的零是。

1 个答案:

答案 0 :(得分:3)

您的辅助轴看起来像这样的原因是,这就是您转换数据的方式。由于您在第三个error中将-500乘以geom_line,所以随着误差变小(即更接近-8),该行将上升。因此,为了使辅助轴正确地映射到您拥有的数据,它必须 颠倒(-8在顶部)。

如果您希望0位于顶部,只需将error中的transsec_axis公式除以肯定的500

ggplot(y, aes(x=Date)) +
    geom_line(aes(y=observed, colour = "observed"), size=1.5) +
    geom_line(aes(y=simulated, colour = "simulated"), size=1.5) +
    geom_line(aes(y=error*500, colour = "error"), size=1.5) +
    scale_colour_manual(name="Discharge [m3/sec]",
                        values = c('observed' = "blue",
                                   'simulated' = "black",
                                   'error' = "red")) +
    scale_y_continuous(sec.axis = sec_axis(~./500, name = "Error [%]",
                                           breaks = c(0, -2, -4, -6, -8))) +
    labs(y=expression(paste('Q [',m^3~s^-1,']'),
                      colour = "Parameter")) +
    theme(legend.position = c(0.2, 0.87),
          legend.title=element_blank(), 
          axis.title.x=element_blank())

enter image description here

如果您想使两个图重叠,则可以手动向您添加error中的8以将其向上移动,然后从sec_axis中减去它以保持数字正确:

ggplot(y, aes(x=Date)) +
    geom_line(aes(y=observed, colour = "observed"), size=1.5) +
    geom_line(aes(y=simulated, colour = "simulated"), size=1.5) +
    geom_line(aes(y=(8 + error) * 500, colour = "error"), size=1.5) +
    scale_colour_manual(name="Discharge [m3/sec]",
                        values = c('observed' = "blue",
                                   'simulated' = "black",
                                   'error' = "red")) +
    scale_y_continuous(sec.axis = sec_axis(~(. / 500) - 8, name = "Error [%]",
                                           breaks = c(0, -2, -4, -6, -8))) +
    labs(y=expression(paste('Q [',m^3~s^-1,']'),
                      colour = "Parameter")) +
    theme(legend.position = c(0.2, 0.87),
          legend.title=element_blank(), 
          axis.title.x=element_blank())

enter image description here

其他提示:

  1. 您可以像上面的操作一样,通过ggplot运算符链接多个+函数,而不是像您在示例中那样,每次都将中间结果保存到变量中
  2. 使用scale_color_manual的正确方法是将命名向量传递给values。这样可以确保给定的颜色值(即observed)始终与正确的颜色(即blue)关联。
  3. 如果要使误差线更小且不那么占主导地位,只需减小变换因子即可。如果乘以geom_line,然后除以sec_axis,再除以100,而不是500,则会得到一条更加平坦的线。您必须尝试使用​​该数字才能使其看起来像您想要的。在ggplot2中,辅助轴必须是主轴的变换,因此您不能仅传递其自己的limits=参数。