[R] How to plot error bars

ben@zoo.ufl.edu ben at zoo.ufl.edu
Wed Nov 8 20:07:34 CET 2000

  I'm going to take the liberty of reposting this function, which is based
on one that Bill Venables posted a while back.  I've tweaked with it a bit
to add functionality.  It will do horizontal bars or vertical bars, but
not (yet) both simultaneously (the hardest thing about that is deciding on
what format you want the data supplied in).

  There's also a help file supplied below.

  Should this (after appropriate tweaking/polishing/testing/revision) go
into the main R code base?  It seems like a pretty basic function to me

plotCI <- function (x, y = NULL, uiw, liw = uiw, aui=NULL, ali=aui,
                    err="y", ylim=NULL, xlim=NULL, sfrac = 0.01, gap=0, add=FALSE,
                    col=par("col"), lwd=par("lwd"), slty=par("lty"), xlab=NULL,
                    ylab=NULL, main="", pt.bg = NA, scol=col,
                    axes=TRUE, ...)  {
# from Bill Venables, R-list
  if (is.list(x)) {
    y <- x$y
    x <- x$x
  if (is.null(y)) {
    if (is.null(x)) 
      stop("both x and y NULL")
    y <- as.numeric(x)
    x <- seq(along = x)
  if (missing(xlab)) xlab <- deparse(substitute(x))
  if (missing(ylab)) ylab <- deparse(substitute(y))
  if (missing(uiw)) {  ## absolute limits
    ui <- aui
    li <- ali
  else {  ## relative limits
    if (err=="y") z <- y else z <- x
    ui <- z + uiw
    li <- z - liw
  if (err=="y" & is.null(ylim))
    ylim <- range(c(y, ui, li), na.rm=TRUE)
    if (err=="x" & is.null(xlim))
      xlim <- range(c(x, ui, li), na.rm=TRUE)
  if (!add)
    plot(x, y, ylim = ylim, xlim = xlim, col=col, lwd=lwd, xlab=xlab, ylab=ylab,
         main=main, type="n", axes=axes, ...)
  if (gap==TRUE) gap <- 0.01  ## default gap size
  ul <- c(li, ui)
  if (err=="y") {
    ## draw vertical segments
    gap <- rep(gap,length(x))*diff(par("usr")[3:4])
    segments(x , li, x, pmax(y-gap,li), col=scol, lwd=lwd, lty=slty)
    segments(x , ui, x, pmin(y+gap,ui), col=scol, lwd=lwd, lty=slty)
    ## horizontal segments
    x2 <- c(x, x)
    smidge <- diff(par("usr")[1:2]) * sfrac
    segments(x2 - smidge, ul, x2 + smidge, ul, col=scol, lwd=lwd)
  else if (err=="x") {
    ## draw horizontal segments
    gap <- rep(gap,length(x))*diff(par("usr")[1:2])
    segments(li, y, pmax(x-gap,li), y, col=scol, lwd=lwd, lty=slty)
    segments(ui, y, pmin(x+gap,ui), y, col=scol, lwd=lwd, lty=slty)
    ## vertical segments
    y2 <- c(y, y)
    smidge <- diff(par("usr")[3:4]) * sfrac
    segments(ul, y2 - smidge, ul, y2 + smidge, col=scol, lwd=lwd)
  ## _now_ draw the points (in case we want to have "bg" set for points)
  points(x, y, col=col, lwd=lwd, bg=pt.bg, ...)
  invisible(list(x = x, y = y))

\title{Plot confidence intervals/error bars}
  Given a set of x and y values and upper and lower bounds,
  this function plots the points with error bars.
plotCI(x, y=NULL, uiw, liw=uiw, ylim=NULL, sfrac=0.01, add=FALSE, col=par("col"), lwd=par("lwd"), slty=par("lty"), xlab=NULL, ylab=NULL, ...)
%- maybe also `usage' for other objects documented here.
  \item{x}{The x coordinates of points in the plot}
  \item{y}{The y coordinates of points in the plot}
  \item{uiw}{The width of the upper portion of the confidence region,
    or (if \code{liw} is missing) the width of both halves of
    the confidence region}
  \item{liw}{The width of the lower portion of the confidence region (if
    missing, the function assumes symmetric confidence bounds)}
  \item{aui}{The absolute upper limit of the confidence region}
  \item{ali}{The absolute lower limit of the confidence region}
  \item{err}{The direction of error bars: "x" for horizontal, "y"
for vertical ("xy" would be nice but is not implemented yet)}
  \item{xlim}{x limits of the plot}
  \item{ylim}{y limits of the plot}
  \item{gap}{Size of gap in error bars around points (default 0)}
  \item{sfrac}{Scaling factor for the size of the "serifs" (end bars) on
    the confidence bars, in x-axis units}
  \item{add}{If FALSE (default), create a new plot; if TRUE, add error
    bars to an existing plot.}
  \item{col}{Color of points}
  \item{pt.bg}{Background color of points (use pch=21, pt.bg=par("bg")
to get open points superimposed on error bars)} 
  \item{lwd}{Line width of error bars}
  \item{slty}{Line type of error bars}
  \item{scol}{Color of error bars}
  \item{xlab}{Horizontal axis label}
  \item{ylab}{Vertical axis label}
  \item{\dots}{Any other parameters to be passed through to \code{plot}}
\author{Ben Bolker (documentation and tweaking of a function provided by
  Bill Venables)}
\section{TO DO}{Fixes for logarithmic axes; simultaneous horizontal and vertical error bars.
The main problem is figuring how parameters should be specified.}
  y <- runif(10)
  err <- runif(10)
  err.x <- runif(10)
  err.y <- runif(10)


On Wed, 8 Nov 2000, Mike Beddo wrote:

> I'm a newcomer to R. I can't seem to find any documentation how to add
> error bars to points in scatter plots. I guess I could plot the points,
> then compute and plot line segments in the X and/or Y directions to
> represent the errors?
> - Mike
> -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
> r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
> Send "info", "help", or "[un]subscribe"
> (in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
> _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._

318 Carr Hall                                bolker at zoo.ufl.edu
Zoology Department, University of Florida    http://www.zoo.ufl.edu/bolker
Box 118525                                   (ph)  352-392-5697
Gainesville, FL 32611-8525                   (fax) 352-392-3704

r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch

More information about the R-help mailing list