ggplot2-如何将带有箭头图标的geom_text分配给第二个yaxis比例尺

时间:2018-12-10 22:30:09

标签: r ggplot2

我有20组以下数据集,并希望将两个图与两个y轴合为一个,以正确反映变量值。

hour=c(0:23)
conc=c(20.7, 19.4, 15.6, 11.7, 10.3, 9.1, 9.7, 10.6, 12.7, 12.6, 11, 9.8,
       9.3, 9.3, 10.3, 12.9, 17.1, 22.5, 22, 22.3, 23, 24.8, 24, 26.8)
ws=c(0.75, 0.7, 0.68, 0.64, 0.61, 0.64, 0.57, 0.58, .62, .65, .85, 1.12, 
     1.21, 1.29, 1.2, 1.18, 1.0, 0.84, .87, .75, .69, .69, .77, .74)
wd=c(295, 299, 288, 290, 292, 296, 306, 303, 300, 293, 259, 231, 94, 119, 
     95, 47, 75, 306, 302, 304, 319, 309, 290, 298)
mydf=data.frame(hour, conc, ws, wd)

我可以使用以下代码将它们分别绘制为1-by-2图:

conchrly <- ggplot(mydf, aes(x=hour,y=conc)) +
  geom_line() + 
  xlab("Hour") +
  ylab("Concentration") +
  theme(legend.position="bottom")     

windhrly <- ggplot(data = mydf, aes(x=hour, y=ws)) + 
  geom_text(aes(angle=-wd+90), label="←") +
  xlab("Hour") +
  ylab("Wind Speed") +
  theme(legend.position="bottom") 

conchrly + windhrly + plot_layout(ncol=1)

显示以下图表:

Two separate plots using plot_layout

我想将它们与两个y轴组合为一个图形。我在这里找到的大多数示例都与第二轴有关,它们是第一y值的重复项或函数。我的第二个y变量是“ ws”,它不是我的第一个y变量的函数(即“ conc”)。

以下是我尝试将它们一起绘制的图。但是,未使用第二个y轴绘制第二个图的y值(geom_text应该代表我的ws)。

ggplot(data=mydf, aes(x = hour, y = conc)) + 
  geom_line(color = "black") + 
  geom_text(data=mydf, aes(x=hour, y=ws,angle=-wd+90), label="←", colour = "blue") +
  scale_x_continuous(breaks = seq(0, 24, by=6), limits=c(0,24), name="Hour") + 
  scale_y_continuous( breaks = seq(0,30,10), name= "Concentration", 
     sec.axis = sec_axis(~./20, name = "Wind Speed (m/s)")) + 
              theme(axis.title.y = element_text(color = "black"),
                    axis.title.y.right = element_text(color = "black"))

Combined graph with two y-axes

如何使代表我的“ ws”的蓝色箭头正确缩放(即使用第二个y轴)?这只是一组,我还有19个其他组要做,这就是为什么我更愿意在可能的情况下将它们组合成每个数据集的一张图。

提前谢谢! :)

1 个答案:

答案 0 :(得分:4)

如果我们缩放ws的值,使它们使用与conc相同的范围,然后在sec_axis内应用逆变换,就可以实现您的期望。我们正在应用的转换采用y = a + b * x的形式,其中yconc,而xws度量。然后,通过求解两个线性方程组来获得两个缩放系数ab

# Calculate scaling coefficients a and b
y1 <- min(mydf$conc)
y2 <- max(mydf$conc)
x1 <- min(mydf$ws)
x2 <- max(mydf$ws)
b <- (y2 - y1) / (x2 - x1)
a <- y1 - b * x1

然后我们计算ws.scaled并在x = (y - a) / b内应用逆变换sec_axis

library(tidyverse)
mydf %>%
    mutate(ws.scaled = a + b * ws) %>%
    ggplot(aes(x = hour, y = conc)) +
        geom_line(color = "black") +
        geom_text(aes(x = hour, y = ws.scaled, angle = -wd + 90), label = "←", colour = "blue") +
        scale_x_continuous(breaks = seq(0, 24, by=6), limits=c(0,24), name="Hour") +
        scale_y_continuous(
            breaks = seq(0,30,10),
            name=  "Concentration",
            sec.axis = sec_axis(~ (. - a) / b, name = "Wind Speed (m/s)")) +
            theme(
                axis.title.y = element_text(color = "black"),
                axis.title.y.right = element_text(color = "black"))

enter image description here

PS。 y轴通常不是一个好主意。我个人更喜欢显示两个情节。