【问题标题】:How to add more lines to a plot done with ggplot2 that has double y-axis如何向使用具有双 y 轴的 ggplot2 完成的绘图添加更多线条
【发布时间】:2019-08-06 13:39:42
【问题描述】:

数据框df1 总结了一条鱼在一段时间内的平均每日深度(meanDepth),以及不同深度的每日平均水温(T5mT15mT25mT35m)以及整个水柱的日平均温度(meanT)(不考虑不同深度)。举个例子:

df1<- data.frame(Date=c("2016-08-05","2016-08-06","2016-08-07","2016-08-08","2016-08-09","2016-08-10"),
                 meanDepth=c(15,22,18,25,27,21),
                 T5m=c(17,18,21,23,21,18),
                 T15m=c(16,17,18,19,18,17),
                 T25m=c(16,17,17,18,18,17),
                 T35m=c(15,16,17,17,17,16),
                 meanT=c(16,17.2,17.8,18.3,17.8,17.4))
df1$Date<-as.Date(df1$Date)

df1

        Date meanDepth T5m T15m T25m T35m meanT
1 2016-08-05        15  17   16   16   15  16.0
2 2016-08-06        22  18   17   17   16  17.2
3 2016-08-07        18  21   18   17   17  17.8
4 2016-08-08        25  23   19   18   17  18.3
5 2016-08-09        27  21   18   18   17  17.8
6 2016-08-10        21  18   17   17   16  17.4

我想在一张图中绘制鱼的深度剖面和不同深度的日平均温度。

到目前为止,我在一个 Y 轴上绘制 meanDepth,在另一个 Y 轴上绘制 meanT。但我不知道如何添加更多与右 y 轴(=温度)相关的线,这些线代表不同深度的日平均温度。这里有我迄今为止能够构建的代码。

p <- ggplot(df1, aes(x = Date))
p <- p + geom_line(aes(y = meanDepth, colour = "Overall daily mean depth"))
p <- p + geom_line(aes(y = meanT/(max(range(df1$meanT,na.rm=TRUE)/max(range(df1$meanDepth,na.rm=TRUE)))), colour = "Mean Water T"))
p <- p + scale_y_continuous(sec.axis = sec_axis(~.*(max(range(df1$meanT,na.rm=TRUE)/max(range(df1$meanDepth,na.rm=TRUE)))), name = "Mean daily Temp"))
p <- p + scale_colour_manual(values = c("blue", "red"))
p <- p + labs(title="Mean daily depth and water temperature through time",
              y = "Mean daily depth",
              x = "Date",
              colour = "Parameter")
p <- p + theme(legend.position = c(0.8, 0.9), plot.title = element_text(hjust=0.5, face="bold",margin = margin(0,0,12,0) ),axis.title.y =element_text(margin = margin(t = 0, r = 12, b = 0, l = 0)),axis.title.x =element_text(margin = margin(t = 12, r = 0, b = 0, l = 0)),axis.text.x=element_text(angle=60, hjust=1))
p <- p + scale_x_date(date_breaks = "1 days", labels = date_format("%Y-%m-%d"))
p

这就是我得到的情节:

有没有人如何添加与 5、15、25 和 35 米的温度有关的线?

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    辅助轴几乎从来都不是一个好主意,但你可以这样做:

    library(ggplot2)
    library(tidyr)
    library(dplyr)
    df1 %>% 
      mutate(meanDepthNormalized = meanDepth * max(meanT) / max(meanDepth)) %>% #1
      select(-meanDepth) %>% 
      # could have changed meanDepth before directly, but wanted to be more verbose
      gather(type, value, -Date) %>% #2
      ggplot(aes(x = Date, y = value, color = type, linetype = type == "meanT")) + #3
        geom_line(size = 1.5) +
        scale_y_continuous(sec.axis = sec_axis(~ . * max(df1$meanDepth) / max(df1$meanT))) +
        scale_color_manual("", values = c("#E41A1C", "#984EA3", "#BDD7E7",
                                          "#6BAED6", "#3182BD", "#08519C")) +
        theme_minimal() + 
        guides(linetype = FALSE) +
        theme(legend.position = "top")
    

    说明

    1. 您首先将 Depth 转换为与温度测量值相同的比例
    2. 然后通过gather 将数据从宽格式转换为长格式
    3. 然后,您可以将颜色映射到类型变量,该变量基本上包含以前的列名。

    【讨论】:

      【解决方案2】:

      如果我正确理解了您的问题,则为每个温度/列添加 geom_line 就足够了。这是T5mT35m 的示例。

      df1<- data.frame(Date=c("2016-08-05","2016-08-06","2016-08-07",
                              "2016-08-08","2016-08-09","2016-08-10"),
                       meanDepth=c(15,22,18,25,27,21),
                       T5m=c(17,18,21,23,21,18),
                       T15m=c(16,17,18,19,18,17),
                       T25m=c(16,17,17,18,18,17),
                       T35m=c(15,16,17,17,17,16),
                       meanT=c(16,17.2,17.8,18.3,17.8,17.4))
      df1$Date<-as.Date(df1$Date)
      norm <- max(df1$meanT,na.rm=TRUE)/max(df1$meanDepth,na.rm=TRUE)
      p <- ggplot(df1, aes(x = Date)) +
        geom_line(aes(y = meanDepth, colour = "Overall daily mean depth")) +
        geom_line(aes(y = meanT/norm, colour = "Mean Water T")) +
        geom_line(aes(y = T5m/norm, colour = "T5m")) +
        geom_line(aes(y = T35m/norm, colour = "T35m")) +
        scale_x_date(date_breaks = "1 days", labels = date_format("%Y-%m-%d")) +
        scale_y_continuous(sec.axis = sec_axis(~.*norm, name = "Mean daily Temp")) +
        scale_colour_manual(values = c("blue", "red", "orange", "black")) +
        labs(title="Mean daily depth and water temperature through time",
             y = "Mean daily depth",
             x = "Date",
             colour = "Parameter") +
        theme(legend.position = c(0.8, 0.9),
              plot.title = element_text(hjust=0.5, face="bold", margin = margin(0,0,12,0)),
              axis.title.y = element_text(margin = margin(t = 0, r = 12, b = 0, l = 0)),
              axis.title.x = element_text(margin = margin(t = 12, r = 0, b = 0, l = 0)),
              axis.text.x=element_text(angle=60, hjust=1)) 
      p
      

      【讨论】:

      • 谢谢@Arienrhod,我现在去看看。你知道如何为线条选择特定的颜色吗?在此先感谢!
      • 您在scale_color_manual 中设置颜色。如果您的意思是如何想出不同的颜色,请查看 colorbrewer2.org。
      • 最后一个问题,我添加了geom_line(aes(y = T15m/norm, colour = "T15m"))geom_line(aes(y = T25m/norm, colour = "T25m")) 以包含所有行,我收到了Error: Insufficient values in manual scale. 6 needed but only 4 provided 的消息。这个问题能解决吗?我所做的只是在T5m 的geom_line 和T35m 的linge 中添加这些行。
      • 你需要为scale_color_manual的每一行添加自定义颜色。
      【解决方案3】:

      也许与 facet_grid(y ~., scales = "free")

      这里是一个例子

      ggplot(mtcars, aes(factor(cyl), mpg)) + 
         geom_boxplot() + 
         facet_grid(cyl ~., scales = "free")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-07-31
        • 1970-01-01
        • 2019-01-02
        • 2015-05-18
        • 1970-01-01
        • 2014-03-25
        • 1970-01-01
        相关资源
        最近更新 更多