7

I would like to modify the y-axis scale on ggplot2 for a case where I am plotting a value that I know is always positive.

To illustrate this problem, consider the graph that is produced when I plot:

df = data.frame(x=seq(1,10),y=rep(0,10))
ggplot(df,aes(x,y)) + geom_point()

enter image description here

I would like to set the lower limit for the y-axis in this case to 0 without specifying the maximum value for the y-axis. If possible, I would like to do this in one command (since I need to usually call facet_grid with scales = free after I create this plot)

Berk U.
  • 7,018
  • 6
  • 44
  • 69
  • The example given is a bit of an odd one because it is all 0 x values. For clarification, do you have values below 0 and want them excluded from the plot, or are all values greater than 0 and you want to ensure the minimum value of the plot(s) is not greater than 0? – Cotton.Rockwood Oct 25 '14 at 20:37
  • @Cotton.Rockwood Thank you for your help on this! So it's a little tricky. I never have any values less than 0. In some facets, a few of the values are 0 and the rest are greater than 0 (the automatic axis works fine here). In other facets, all of the values are equal to zero 0 (this is where I have issues, so it's why I posted the example with points at zero). – Berk U. Oct 27 '14 at 00:13
  • I see. So where you have all zeros, what do you want the scales to be? In your example, the axes are the way they are because of the default behavior in ggplot to expand the axes. This is true for all graphs. You can adjust this by setting `expand = c(0, 0)`, but that doesn't help in this case. The only solution I can see would be to explicitly set the limits based on whether all values being plotted are 0. – Cotton.Rockwood Oct 27 '14 at 03:33
  • I added an edit to my answer below to address your desired outcome. It also occurred to me that you could just use `expand_limits(y = c(0, 1))` or something similar if you just always want your y-axis to at least show 0-1 (with or w/o ggplot expansion). – Cotton.Rockwood Oct 27 '14 at 15:24

2 Answers2

4

Edit

After clarification, the OP is looking for a solution to plot data that has all zeros for y-values so that the axes are not set by the expand function to be equal on either side of 0. Here is one possible solution:

example data:

set.seed(1)

df <- data.frame(x=1:10,
                 y=rep(0, 10))
df1 <- data.frame(x=1:10,
                  y=sample(1:10 , 10, replace=T))
df
df1

Add a wrapper that plots all-zero data appropriately:

plot.zeros <- function(data) {
  upper.lim <- ifelse(any(data$y != 0), NA, 1)
  print(ggplot(data, aes(x, y)) + geom_point() +
    scale_y_continuous(limits = c(0, upper.lim), expand = c(0.01, 0)))
}

plot.zeros(df)
plot.zeros(df1)

This uses a simple function to set the upper y-axis limit to 1 if all the data have y-values of 0. If any y-values are non-zero, the minimum y-axis is set to 0 and the maximum is determined internally by ggplot. You can change the y-max value as desired by changing the 'else' part of the ifelse statement to something other than 1. Also, if you don't want to mess with the expand argument and just want to use the default, you can use ylim(0, upper.lim) instead of the scale_y_continuous call.

End Edit


If your data is always positive but sometimes the min value is above zero, you could use expand_limits. In that case, this should give you what you are looking for:

df <- data.frame(type=sample(c("a","b"), 20, replace=T),
                  x=rep(1:10, 2),
                  y=c(rep(0, 10), sample(1:10 , 10, replace=T)))
df

ggplot(df,aes(x,y)) + geom_point() +
    facet_wrap(facets='type', scales="free") +
    expand_limits(y=0)

enter image description here

Alternately, you can use a manually set scale, but that wouldn't work for facet_wrap or grid_wrap, as it would set the scale for all facets:

scale_y_continuous(limits=c(0, max(df$y) * 1.1))
Cotton.Rockwood
  • 1,601
  • 12
  • 29
  • 1
    `expand_limits` will only make sure that a particular value will be included. It will not make sure that values on one side or the other are not included on the axis – Brian Diggs Oct 25 '14 at 13:55
  • I see your point, but in the case of this question, since the data is always positive, wouldn't it serve the purpose required by the OP? – Cotton.Rockwood Oct 25 '14 at 19:17
4

Unlike this question which was wanting to expand all axes to include a value, you want to exclude values which otherwise would be on the axis.

The general case of this (setting a fixed upper or lower limit and allowing the other to be determined in the usual way) is not possible and a feature request had been filed for it was introduced in version 1.0.0 and can be used by specifying one fixed limit and using NA for the other one that is to be determined from the data (thanks to @Cotton.Rockwood for pointing this out to me).

Community
  • 1
  • 1
Brian Diggs
  • 57,757
  • 13
  • 166
  • 188
  • It looks like this has now been implemented. You can specify NA for the upper limit and it will be calculated internally. See [here](https://github.com/hadley/ggplot2/pull/908). The example provided by the OP behaves oddly though because it is all 0 values. – Cotton.Rockwood Oct 25 '14 at 22:22