Re: [R] ylim for graphic

From: Marc Schwartz (via MN) <>
Date: Tue 30 Aug 2005 - 03:35:38 EST

On Mon, 2005-08-29 at 12:58 -0400, Doran, Harold wrote:
> Dear list:
> I have some data for which I am generating a series of barplots for
> percentages. One issue that I am dealing with is that I am trying to get
> the legend to print in a fixed location for each chart generated by the
> data. Because these charts are being created in a loop, with different
> data, my code searches the data to identify the maximum value in the
> data and then print the data values 5 points above the tallest bar.
> Now, in situations where the largest value is 100, I needed to create
> the y-axis high enough to accommodate the legend w/o crowding up the
> data or the bars. So, I have ylim =c(0,200) and then place the legend at
> c(2,150). Visually, this places things exactly where I want them. But,
> it seems silly to have a y-axis labeled as high as 200%. I'm certain
> there is a smarter technique. Is it possible to place the legend at a
> location higher than 100 to avoid the crowding of the bars and the data
> and then also have the labels for the y-axis not print after the value
> 100%?
> In looking at ?legend I didn't see an option that would address this.
> Below is some code that you can use to create a similar chart.
> Thanks,
> Harold
> <- c(53,31,55,28,55,100)
> apmxpmeet <- c(47, 50, 49, 50, 49, 46)
> par(ps=10)
> <- rbind(, apmxpmeet)
> math.barplot <- barplot(, beside=T, col=c('blue','orange'),
> names=c('Grade \n 3','Grade \n 4','Grade \n 5','Grade \n 6','Grade \n
> 7','Grade \n 8'),
> ylim=c(0,200), ylab="Percentage", xlab="Grade Level")
> tot <- round(,digits=0)
> graph.max <- max(, apmxpmeet, na.rm=T)
> text(math.barplot, graph.max+5, tot, xpd = TRUE, col = c("blue",
> "orange") )
> legend(2,150,legend=(c("Label A", "Average")), fill=c("blue","orange"))


A few thoughts:

  1. Instead of fixing the y axis max value at 200, simply set ylim to c(0, max( * 1.2)) or a similar constant. In this case, you get an extra 20% above the max(y) value for the legend placement.
  2. In the legend call, use:

  legend("topleft", legend=(c("Label A", "Average")),

          fill = c("blue","orange"))

This will place the legend at the topleft of the plot region, rather than you having to calculate the x and y coords. If you want it moved in from the upper left hand corner, you can use the 'inset' argument as well, which moves the legend by a proportion of the plot region limits (0 - 1):

    legend("topleft", legend=(c("Label A", "Average")),

          fill = c("blue","orange"), inset = .1)

3. You can use barplot(..., yaxt = "n") to have the y axis not drawn and then use axis() to place the labels at locations of your choosing, which do not need to run the full length of the axis range:

 barplot(1:5, yaxt = "n", ylim = c(0, 10))  axis(2, at = 0:5)

4. You can place the legend outside the plot region, enabling you to keep the y axis range to <=100. This would need some tweaking, but the idea is the same:

 # Increase the size of the top margin
 par(mar = c(5, 4, 8, 2) + 0.1)

 # Draw a barplot

 # Disable clipping outside the plot region  par(xpd = TRUE)

 # Now draw the legend, but move it up by 30% from the top left  legend("topleft", legend = LETTERS[1:5], inset = c(0, -.3))

You could also place the legend to the right or left of the plot region if you prefer, adjusting the above accordingly.

HTH, Marc Schwartz mailing list PLEASE do read the posting guide! Received on Tue Aug 30 03:43:30 2005

This archive was generated by hypermail 2.1.8 : Sun 23 Oct 2005 - 16:02:16 EST