Width of error bars in line plot using ggplot2

前端 未结 2 1586
轻奢々
轻奢々 2021-01-11 10:43

I have some data with standard errors associated and would like to display these with error bars. That\'s what I have:

# generate some data
hod <- data.f         


        
相关标签:
2条回答
  • 2021-01-11 11:15

    Below is a reproducible example using random data. The fix to the problem is to multiply the width by the number of classes/factors that you have. In the plot below, since I used three factors, using a width of 3 fixes the problem. ggplot2 seems to calculate the relative width by the number of data points in your dataset, rather than the numeric values on the x-axis. This is (IMO) a bug.

    library(ggplot2)
    library(grid)
    
    #plot with factors
    hod <- data.frame(h = c(1:24,1:24,1:24), mean = 1:(24*3) + runif(24*3, 0, 5),ci = runif(24*3, 0, 2), t = c(rep("a",24),rep("b",24),rep("c",24)))
    pd <- position_dodge(0.3)
      dayplot <- ggplot(hod, aes(x=h, y=mean, colour=as.factor(t),group=as.factor(t))) + 
    
        geom_line(position=pd, size=1) +
        geom_errorbar(aes(ymin=mean-ci, ymax=mean+ci),
                      width=1,
                      size=0.5,
                      position=pd) +
        geom_point(position=pd, shape=21, size=1, fill="white") +
        scale_x_continuous(limits=c(-0.5,23.5),
                           breaks=c(0:8*3),
                           labels=ifelse(
                                  c(0:8*3) < 10,
                                  paste('0',c(0:8*3),':00',sep=''),
                                  paste(c(0:8*3),':00',sep='')
                                  )
                           ) +
        xlab("Hour of day") +
        theme_minimal() + 
        theme(plot.margin = unit(c(1,0,1,1), "cm"), 
              axis.title.x = element_text(vjust=-1),
              axis.title.y = element_text(angle=90, vjust=0),
              legend.margin = unit(c(0), "cm"),
              legend.key.height = unit(c(0.9), "cm"),
              panel.grid.major = element_line(colour=rgb(0.87,0.87,0.87)),
              panel.grid.minor = element_blank(),
              plot.background = element_rect(fill = rgb(0.97,0.97,0.97), linetype=0)
        )
    print(dayplot)
    
    
    #plot without factors
    hod <- data.frame(h = c(1:24,1:24,1:24), mean = 1:(24) + runif(24, 0, 5),ci = runif(24, 0, 2))
    pd <- position_dodge(0.3)
      dayplot <- ggplot(hod, aes(x=h, y=mean)) + 
    
        geom_line(position=pd, size=1) +
        geom_errorbar(aes(ymin=mean-ci, ymax=mean+ci),
                      width=1,
                      size=0.5,
                      position=pd) +
        geom_point(position=pd, shape=21, size=1, fill="white") +
        scale_x_continuous(limits=c(-0.5,23.5),
                           breaks=c(0:8*3),
                           labels=ifelse(
                                  c(0:8*3) < 10,
                                  paste('0',c(0:8*3),':00',sep=''),
                                  paste(c(0:8*3),':00',sep='')
                                  )
                           ) +
        xlab("Hour of day") +
        theme_minimal() + 
        theme(plot.margin = unit(c(1,0,1,1), "cm"), 
              axis.title.x = element_text(vjust=-1),
              axis.title.y = element_text(angle=90, vjust=0),
              legend.margin = unit(c(0), "cm"),
              legend.key.height = unit(c(0.9), "cm"),
              panel.grid.major = element_line(colour=rgb(0.87,0.87,0.87)),
              panel.grid.minor = element_blank(),
              plot.background = element_rect(fill = rgb(0.97,0.97,0.97), linetype=0)
        )
    
    print(dayplot)
    
    0 讨论(0)
  • 2021-01-11 11:18

    I have managed to solve a similar issue. In my case I wanted to set both horizontal and vertical errorbar heads to the same size - regardless of the aspect ratio of the plot.

    Based on the original posted code:

    f <- ggplot_build(dayplot)
    
    f$plot$layers[[5]]$geom_params$width  <- 0.02 * diff(f$layout$panel_params[[1]]$x.range)
    f$plot$layers[[6]]$geom_params$height <- 0.02 * diff(f$layout$panel_params[[1]]$y.range)
    
    dayplot <- f$plot
    

    This will set the errorbar head to 2% of the axis range. Maybe could solve your issue.

    0 讨论(0)
提交回复
热议问题