【问题标题】:How to set different ranges for dual axes and assign appropriate standard error如何为双轴设置不同的范围并分配适当的标准误差
【发布时间】:2019-11-26 23:37:54
【问题描述】:

我使用双 y 轴绘制条形图和折线图。我想修改单个y轴的范围,例如折线图在条形图上方。在这种情况下,我希望Does 的范围为 1-1.5,Wight 的范围为 0.20-0.5,因此线条会稍微悬停在条形图上。但是,当我在sec.axis 之后设置limits 时,仅适用于辅助y 轴并且条形图消失了。我尝试添加break 来给出一个范围,但它也没有成功。我想知道是否可以单独操纵两个 y 轴?

另外,当应用双轴时,是否可以为每个图(条形图一个,折线图一个)设置标准误差?我应用了两个 stat_summary 以获得 2 个不同的 mean_se(标准误差线),但是,只绘制了一个。任何建议都非常感谢!

# dummy data
burger<- tibble(
  Day = rep(1:4,2),
  Dose = c(0.5,0.6,0.4,0.3,0.5,0.6,0.4,0.3),
  Wight = c(0.95,0.92,0.93,0.98,0.95,0.92,0.93,0.98))


  # plot
  ggplot(data= burger, aes(x = Day, y = Dose),group = 1)+
    geom_bar(data= burger, aes(x = Day, y = Wight* (0.98/0.6)), stat = "identity") +
    stat_summary(fun.data = mean_se,geom= "errorbar",width=0.6,size=1,aes(y= burger$Dose, width=0.05))+
    stat_summary(fun.data = mean_se,geom= "errorbar",width=0.6,size=1,aes(y= burger$Wight, width=0.05))+
    geom_line (size = 2,aes(group=1))+
    geom_point(aes(colour=Day))  +
    scale_y_continuous(name = "Dose", 
                       sec.axis = sec_axis(trans =  ~.*(0.6/0.98) , name = "Wight",limits=c(0.25,1)))

【问题讨论】:

  • 我没有得到关于标准错误的东西。你能解释得更好一点吗?你希望从中得到什么?
  • @Edo 感谢您的回复。我添加了使用fun.data = mean_se 为每个图生成单独和独立的 SE 的尝试。但是,它不起作用。有什么建议吗?
  • 对于每一天,您只有一个观察结果。你怎么可能计算一个标准误差?
  • @Edo 我忘了我在这里使用了非常简单的虚拟 df,我只是将值加倍。您对分离的 SE 有什么建议吗?干杯!
  • 如果您只是将数据翻倍,您的 se 仍然为零。看看我对答案的编辑。我添加了一个新图表来回答您的问题(希望如此)

标签: r ggplot2


【解决方案1】:

ggplot2 中,您控制主要的 y 轴,并转换次要的 y 轴。 plotly 允许您分别控制两个轴。

library(plotly)
plot_ly(data = burger) %>% 
  add_lines(x = ~Day, y = ~Dose,  name = "Dose") %>% 
  add_bars(x = ~Day, y = ~Wight, yaxis = "y2", name = "Wight") %>%
  layout(
    yaxis = list(showline = TRUE, side = "left", 
                 title = "Dose", range = c(0.2, 0.6)), 
    yaxis2 = list(showline = TRUE, side = "right", 
                  overlaying = "y",  title = "Wight", range = c(0.9, 1)), 
    showlegend = FALSE,  
    margin = list(pad = 0, b = 50, l = 50, r = 50))

【讨论】:

    【解决方案2】:

    我添加了一个 +1 和一个 -1 来将条形设置在同一行的高度,同样使用 coord_cartesian 您可以在不裁剪数据的情况下放大图表。 (如果您使用 ylim 代替,条形图会像发生在您身上一样消失)。 我也稍微调整了你的代码。

    require(dplyr)
    require(ggplot2)
    
    # dummy data
    burger <- tibble(Day   = 1:4,
                     Dose  = c(0.5, 0.6, 0.4, 0.3),
                     Wight = c(0.95, 0.92, 0.93, 0.98))
    
    
    # plot
    ggplot(data = burger, aes(x = Day, y = Dose))+
      geom_bar(aes(y = Wight * (0.98/0.6) - 1), stat = "identity") +
      geom_line(size = 2) +
      geom_point(aes(colour = Day))  +
      scale_y_continuous(name = "Dose", 
                         sec.axis = sec_axis(trans =  ~(.+1)*(0.6/0.98),
                                             name = "Wight")) +
      coord_cartesian(ylim = c(0.3, 0.6))
    
    

    编辑:

    此图表回答了您问题的第二部分。

    首先,我创建了一个随机数据样本。

    图表的所有对象都是用stat_summary 创建的。使用stat_summary,我可以将汇总函数应用于我的数据:意味着fun.y,当我需要从我的Y var 和mean_sefun.data 中获取单个结果时,当我需要返回一个可供geom errorbar 使用的向量时。

    我添加了一些颜色来帮助您识别每件作品并将每个值与其错误栏直观地关联起来,但您可以设置最喜欢的颜色。

    require(dplyr)
    require(ggplot2)
    
    set.seed(20)
    
    # dummy data
    burger<- tibble(
      Day   = rep(1:4, each = 10),
      Dose  = rnorm(40, 0.5, 0.1),
      Wight = rnorm(40, 0.9, 0.1))
    
    
    # plot
    ggplot(data = burger, aes(x = Day))+
    
      # bars and error
      stat_summary(aes(y = Wight * (0.98/0.6) - 1), 
                   fun.y = mean, geom = "bar", 
                   fill = "steelblue", alpha = 0.6) +
      stat_summary(aes(y = Wight * (0.98/0.6) - 1), 
                   fun.data = mean_se, geom = "errorbar",
                   colour = "steelblue", size = 1.5, width = 0.5) +
    
      # line/point and error
      stat_summary(aes(y = Dose), fun.data = mean_se, 
                   geom = "errorbar", size = 1.5, width = 0.5,
                   colour = "coral") +
      stat_summary(aes(y = Dose), fun.y = mean, geom = "line", 
                   size = 0.5, colour = "coral") +
      stat_summary(aes(y = Dose, colour = Day), fun.y = mean, geom = "point", size = 3) +
    
      # prettier
      scale_y_continuous(name = "Dose", 
                         sec.axis = sec_axis(trans =  ~(.+1)*(0.6/0.98),
                                             name = "Wight")) +
      coord_cartesian(ylim = c(0.3, 0.6)) +
      theme_light() +
      scale_color_gradient2(mid = "black", high = "#FFBE5A")
    
    

    【讨论】:

    • 条形与汉堡数据中的一样高。第一个是 0.95,它正好触及连接到第二个 y 轴的 0.95 线。以下两个应略低于应有的水平,最后一个是最高的。我觉得很好
    • 解决方案正确吗?你觉得还缺什么吗?
    • 谢谢!请问您为什么将-1 放入(0.98/0.6) - 1 并在sec_axis 中添加(.+1) 作为参数?
    • 只是因为你问“线条 [to] 将条形图悬停一点” :-)
    • 非常感谢!它工作得很好。我想知道(0.98/0.6) 的值是任意决定的还是基于某些计算,例如Doesweight 的最大值。因为在这个图中,我们可以通过(coord_cartesian(ylim = c(0.5, 1)) 来确定@​​987654339@ 的范围,但是当我们比较不同的数据集时,很难标准化weight 的另一个y 轴
    猜你喜欢
    • 1970-01-01
    • 2020-05-05
    • 2011-12-24
    • 1970-01-01
    • 2019-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多