如何在第二个 y 轴上添加第二条平滑线并使用 ggplot2 相对于第一个 y 轴缩放它?

How to add a second smooth line in a second y-axis and scale it with regard the first y-axis with ggplot2?

我有一个数据框 df,它总结了一种鱼类的 activity Activity 以及与之相关的水流强度 C.I 和水流方向 C.D这个activity在水柱。作为数据框的示例:

df<- data.frame(C.D=c(5,5,5,10,10,10,20,20,20,40,40,40,80,80,80,100,100,100,130,130,130,160,160,160,190,190,190,220,220,220,250,250,250,280,280,280,310,310,310,340,340,340,359,359,359),
                Activity=c(1.1,1.6,0.6,1.2,1.8,1.3,1.3,1.4,1.88,0.99,1.8,2.1,1.75,1.5,2.4,1.55,0.9,2.4,1.4,1.5,3.2,1.7,2.1,3.8,2.8,3.9,2.1,3.4,2.6,4.1,2.3,3.6,4.3,3.0,2.4,1.8,2.5,1.6,1.1,0.5,1.4,2.3,0.8,2.1,1.5),
                C.I=c(0.05,0.21,0.11,0.2,0.15,0.28,0.24,0.18,0.33,0.11,0.22,0.13,0.16,0.31,0.23,0.15,0.28,0.36,0.25,0.31,0.58,0.42,0.36,0.52,0.58,0.82,0.71,0.64,0.51,0.4,0.54,0.55,0.68,0.32,0.21,0.23,0.37,0.22,0.15,0.21,0.24,0.18,0.04,0.6,0.12))

df

   C.D Activity  C.I
1    5     1.10 0.05
2    5     1.60 0.21
3    5     0.60 0.11
4   10     1.20 0.20
.    .       .    .
.    .       .    .
.    .       .    . 

我想了解水流方向 C.D 是否会影响我的鱼种 activity。例如,如果某些 C.D 的 activity 高于其他 C.D。然而,由于 C.DC.I 可能非常相关(对于某些 C.D 电流强度 C.I 可能比其他人高),我需要添加我的绘制有关 C.I 的信息以解释我所看到的是由于变量 C.D 的影响还是由于第三个变量 C.I.

作为第一个近似值,我绘制了 C.DActivity 之间的关系点,并添加了一条平滑线以查看总体趋势。我还根据 C.I 对点进行着色,以查看颜色是否遵循某种模式(例如,如果特定颜色集中在特定 C.D 中,这意味着某些 C.I 仅出现在特定C.D)。在这个例子中,高 C.I ara 与 C.D 在 140 到 250 之间的等级相关联。代码和图片如下:

P<- ggplot(df, aes(C.D, Activity)) +
  geom_point(aes(C.D, Activity, color = C.I)) + scale_colour_gradientn(colours=c("green","black")) + theme_bw()
P<- P +  geom_smooth()  +
  ggtitle("Mean activity as a function of C.D.20m for winter from hourly data") +
  theme(plot.title = element_text(hjust = 0.5)) 

当我必须绘制数千个点时,我的问题就出现了,从那时起,使用点的颜色来显示与 C.D 关联的任何 C.I 模式是不合适的。在这里,我展示了我的数据的真实图:

我的问题是如何添加第二条关于第一个 y 轴缩放的平滑线,显示 C.DC.I 之间的关系。到目前为止我已经知道了:

P<- P + geom_smooth(aes(C.D, C.I), color="red", se=FALSE)
P

是否可以缩放第二个 y 轴以改进解释?。

首先,我想指出在其他地方 this answer 中表达的次轴的常见警告。

简单地变换你的数据并反向变换次轴不合适吗?

请注意,为了使数据看起来合理,6 是转换的任意数字。

ggplot(df, aes(C.D, Activity)) +
  geom_point(aes(C.D, Activity, color = C.I)) + 
  scale_colour_gradientn(colours=c("green","black")) + 
  theme_bw() + 
  geom_smooth()  +
  ggtitle("Mean activity as a function of C.D.20m for winter from hourly data") +
  theme(plot.title = element_text(hjust = 0.5)) +
  geom_smooth(aes(C.D, C.I * 6), se=FALSE, colour = "red", show.legend = TRUE) +
  scale_y_continuous(sec.axis = sec_axis(trans = ~ . / 6, name = "CI"))

编辑:对于线条的正确图例,恐怕您需要做一些手动规范(除非其他人有更优雅的解决方案):

ggplot(df, aes(C.D, Activity)) +
  geom_point(aes(C.D, Activity, color = C.I)) + 
  scale_colour_gradientn(colours=c("green","black")) + 
  theme_bw() + 
  geom_smooth(aes(linetype = "Activity"))  +
  ggtitle("Mean activity as a function of C.D.20m for winter from hourly data") +
  theme(plot.title = element_text(hjust = 0.5)) +
  geom_smooth(aes(C.D, C.I * 6, linetype = "C.I."), se=FALSE, colour = "red", show.legend = TRUE) +
  scale_y_continuous(sec.axis = sec_axis(trans = ~ . / 6, name = "CI")) +
  scale_linetype_manual(
    values = c(1,1), 
    guide = guide_legend(override.aes = list(colour = c("blue", "red")))
  )