Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ggplot2 Force y-axis to start at origin and float y-axis upper limit

Tags:

r

ggplot2

After a bit of searching I am still not happy!

Is there a simple way to make a graph with a y-axis that starts at the origin and clearly shows all your data?

Here's my problem:

set.seed(123)
my.data<- data.frame(x.var = rnorm(100, 50),
                     y.var = rnorm(100, 50,10))


## Annoying because it doesn't start at origin
ggplot(my.data, aes(x.var, y.var))+
  geom_point()


## Annoying because origin is not at bottom
ggplot(my.data, aes(x.var, y.var))+
  geom_point()+
  expand_limits(y = 0)

## Annoying because point is cut off
ggplot(my.data, aes(x.var, y.var))+
  geom_point()+
  scale_y_continuous(expand = c(0,0))+
  expand_limits(y = 0)

The top answer for the question "Force the origin to start at 0 in ggplot2 (R)" ends with

"You may need to adjust things a little to make sure points are not getting cut off"

Why does this happen? I could manually adjust the axis but I don't want to have to do that every time!

Some dude on the internet has a solution that involves

#Find the current ymax value for upper bound
#(via http://stackoverflow.com/questions/7705345/how-can-i-extract-plot-axes-ranges-for-a-ggplot2-object#comment24184444_8167461 )
gy=ggplot_build(g)$panel$ranges[[1]]$y.range[2]
g=g+ylim(0,gy)

#Handle the overflow by expanding the x-axis
g=g+scale_x_continuous(expand=c(0.1,0))

Which seems complicated for what I feel like is a relatively simple idea. Am I missing something?

Thank you!


EDIT: As of summer of 2018 a ggplot update makes the above fix no longer work. Currently (August 2018) to get the y-max from the plot you now need to do the following.

gy=ggplot_build(g)$layout$panel_scales_y[[1]]$range$range[[2]]

like image 213
Michael Avatar asked Nov 19 '14 23:11

Michael


2 Answers

I found this issue frustrating, and then read the R help file for expansion(). There is a good ggplot option for this that is facet-friendly, dynamic, and concise.

Quoting from the help file:

mult
vector of multiplicative range expansion factors. If length 1, both the lower and upper limits of the scale are expanded outwards by mult. If length 2, the lower limit is expanded by mult[1] and the upper limit by mult[2].

Note that add is also an option with similar structure. I would solve this issue like so:

ggplot(my.data, aes(x.var, y.var))+
  geom_point()+
  scale_y_continuous(limits = c(0, NA),
                     expand = expansion(mult = c(0, 0.1)))

A big reason to prefer this appraoch is if you have geoms with different aesthetics (e.g. points and error bars) and facets with free scales... you can still take advantage of ggplot's clever default y-axis behavior, but force x to intersect y at 0 in every panel, and still see the uppermost data points.

like image 157
Michael Avatar answered Oct 10 '22 05:10

Michael


Why not just:

ggplot(my.data, aes(x.var, y.var))+
    geom_point()+
    scale_y_continuous(expand = c(0,0))+
    expand_limits(y = c(0,1.05 * max(my.data$y.var)))
like image 42
joran Avatar answered Oct 10 '22 05:10

joran