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]]
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.
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)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With