Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Excluding negative y-axis values in ggplot2

Tags:

r

ggplot2

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)

like image 472
Berk U. Avatar asked Oct 24 '14 23:10

Berk U.


2 Answers

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))
like image 173
Cotton.Rockwood Avatar answered Oct 10 '22 09:10

Cotton.Rockwood


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).

like image 25
Brian Diggs Avatar answered Oct 10 '22 09:10

Brian Diggs