【问题标题】:Secondary y-axis in ggplot in R?R中ggplot中的次要y轴?
【发布时间】:2020-08-22 17:06:20
【问题描述】:

浏览了这里提出的一些secondary axis 解决方案,但没有做对。我正在尝试在左侧y-axis 上绘制Elevation 和在右侧y-axis 上绘制FlowA & Flowb。我的示例代码将执行Elevation plotting 但是,努力在secondary axis 上获取FlowA & FlowB 变量。任何帮助将不胜感激。

library(lubridate)
library(tidyverse)

set.seed(123)

FakeData <- data.frame(Date = seq(as.Date("2001-01-01"), to= as.Date("2001-12-31"), by="day"),
                 Elevation = runif(365, 806.8,807.8),
                 FlowA = runif(365,8,15),
                 FlowB = runif(365,1,3))
ggplot(FakeData, aes(x = Date, y = Elevation))+
  geom_line()

【问题讨论】:

    标签: r ggplot2 plot tidyverse yaxis


    【解决方案1】:

    我会建议下一个方法。还要提到输出将取决于您的数据。这里所有Elevation 的值都接近800。对于第二个轴,您必须围绕所有变量定义一个比例因子,以便正确显示它们。接下来是代码:

    library(lubridate)
    library(tidyverse)
    
    set.seed(123)
    #Data
    FakeData <- data.frame(Date = seq(as.Date("2001-01-01"), to= as.Date("2001-12-31"), by="day"),
                           Elevation = runif(365, 806.8,807.8),
                           FlowA = runif(365,8,15),
                           FlowB = runif(365,1,3))
    #Scale factor
    scalefactor <- max(FakeData$Elevation)/max(max(FakeData$FlowA),max(FakeData$FlowB))
    #Plot
    ggplot(FakeData, aes(x = Date))+
      geom_line(aes(y = Elevation,group=1,color='Elevation'),show.legend = T)+
      geom_line(aes(y = FlowA*scalefactor, color = 'FlowA'))+
      geom_line(aes(y = FlowB*scalefactor, color = 'FlowB'))+
      scale_y_continuous(sec.axis = sec_axis(~./scalefactor, name = 'Flow A and Flow B'))
    

    输出:

    【讨论】:

    • 真的很喜欢你的解决方案——非常感谢。只有一个问题。在我的实际数据中,我有一个 variable 有一些缺失数据 (i.e. NA)- 在使用 scale_y_continuous(sec.axis = sec_axis(~./scalefactor, name = 'Flow A and Flow B')) 时。具有NAvariable 不会得到re-scale。有没有办法解决这个问题?
    • @Hydro 根据您有多少NA,您可以对缺失的数据进行插补以填充这些值,或者使用样条方法来完成这些值。我希望这可以帮助你:)
    • @Hydro 另外,如果您有NA,请将其用作比例因子scalefactor &lt;- max(FakeData$Elevation,na.rm=T)/max(max(FakeData$FlowA,na.rm=T),max(FakeData$FlowB,na.rm=T)) 从技术上讲,NA 不会绘制在您的图表中,但不会在您的代码中返回错误。跨度>
    【解决方案2】:

    here 中的解决方案对我来说效果很好。但我想添加一些调整,因为您的数据的代码会略有不同。根据解决方案,我们将使用 3 个几何对象来表示高程、FlowA 和 FlowB。我们还将为 FlowA 和 FlowB 制作辅助轴。

    ggplot(FakeData, aes(x = Date))+
      geom_line(aes(y = Elevation)) +
      geom_col(aes(y = FlowA), fill="blue") +
      geom_col(aes(y = FlowB), fill='red')+
      scale_y_log10(sec.axis = sec_axis(~ .*1, labels = scales::number_format(scale=1/10),name="Flow"))
    

    在上面的代码中,我将高程显示为线图,流向显示为条形图。为什么我在这里使用对数刻度?因为海拔的取值范围(806.8到807.8之间)和流量取值范围的距离很远。如果您继续使用常规 y 轴 (scale_y_continuous()),您将在下面看到此图: 看到情节没有那么有意义。您无法清楚地看到流量如何随时间变化。这是它在对数刻度中的样子: 我在左侧 y 轴上使用对数刻度,在右侧 y 轴上使用常规刻度。现在我们可以清楚地看到流量随时间的变化。高程肯定是一条直线,因为您将其设置为随机均匀分布。

    但是,就个人而言,我不建议您使用双 y 轴,因为它会使绘图用户感到困惑。我建议你把情节分成两个不同的情节。

    【讨论】:

    • 非常感谢@Mathew,您的解决方案有一些优点 - 不是我想要的。
    • 以这种方式使用geom_col() 也有危险,因为它默认为position = "stack",这会使数据以对数比例失真。
    猜你喜欢
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 2016-04-16
    • 2022-07-29
    • 1970-01-01
    • 1970-01-01
    • 2015-03-27
    相关资源
    最近更新 更多