4

I have a kind of data such as:

y<-rep(c(1, 2, 3), times=5)
group<-rep(c("a", "b", "c", "d", "e"), each=3)
x<-c(2, 3, 4, 5, 7, 10, 10, 15, 19, 8, 10, 14, 25, 28, 33)

a<-data.frame (x, y, group)

and when I use facet_grid() with scales="free_x" option I obtain 5 graphs with different number of breaks. It is possible that the 5 graphs have the same number of breaks? For example 3.

ggplot(a, aes(x, y))+geom_point()+ facet_grid(~group, scales="free_x")

I know that if I remove the scales="free_x" option I obtain the same scale for the 5 graphs, but the plot it turns so ugly. Can you help me?

agamesh
  • 559
  • 1
  • 10
  • 26
Nacho Glez
  • 385
  • 3
  • 15
  • it's not clear what you want from your question. What do you mean by "different breaks"? If you want all graphs to be comparable on the same x scale, it might look better if they were on top of each other like so `ggplot(a, aes(x, y))+geom_point()+ facet_wrap(~group, ncol=1)` – MattLBeck Feb 10 '15 at 17:31
  • check http://stackoverflow.com/questions/17271968 – agenis Feb 10 '15 at 17:33
  • I'm sorry if I have not explained well. When I said "different breaks" I mean that "a" has 5 breaks (2.0, 2.5, 3.0, 3.5, 4.0), "b" has 6 (5, 6, 7, 8, 9, 10), "c" has 4 (10.0, 12.5, 15.0, 17.5) and the same occurs with "d" and "e". My question is, there is any way to set the same number of breaks? With ncol=1 axis x has the same scale, but I don't want it, because the range between xmin and xmas is so wide. – Nacho Glez Feb 11 '15 at 10:10
  • I tried the ways I've seen in the linkg, agenis, but it doesn't work for geom_point() or I have been not able to do it well :/ – Nacho Glez Feb 11 '15 at 10:45

1 Answers1

14

You can define your own favorite breaks function. In the example below, I show equally spaced breaks. Note that the x in the function has a range that is already expanded by the expand argument to scale_x_continuous. In this case, I scaled it back (for the multiplicative expand argument).

# loading required packages
require(ggplot2)
require(grid)
# defining the breaks function, 
# s is the scaling factor (cf. multiplicative expand)
equal_breaks <- function(n = 3, s = 0.05, ...){
  function(x){
    # rescaling
    d <- s * diff(range(x)) / (1+2*s)
    seq(min(x)+d, max(x)-d, length=n)
  }
}
# plotting command 
p <- ggplot(a, aes(x, y)) + 
  geom_point() + 
  facet_grid(~group, scales="free_x") +
  # use 3 breaks, 
  # use same s as first expand argument, 
  # second expand argument should be 0
  scale_x_continuous(breaks=equal_breaks(n=3, s=0.05), 
                     expand = c(0.05, 0)) + 
  # set the panel margin such that the 
  # axis text does not overlap 
  theme(axis.text.x = element_text(angle=45), 
        panel.margin = unit(1, 'lines'))

resulting image

shadow
  • 21,823
  • 4
  • 63
  • 77
  • Nice!! Thank you! But, no I've another problem. Here there are 1 or 0 decimals, but if I use this function with my real data I've 5 or 6 decimals. I've tried to use `fmt <- function(){ function(x) format(x,nsmall = 2,scientific = FALSE) }` and add `fmt` in `scale_x_continuous`. But I've got an error: Error in scale$labels(breaks) : unused argument (breaks). How can I set de number of decimals using this function? – Nacho Glez Feb 12 '15 at 10:00
  • 1
    In the `equal_breaks` function, you could just round the breaks to two decimals. E.g. use `round(seq(min(x)+d, max(x)-d, length=n), 2)` as a return statement. – shadow Feb 12 '15 at 11:40
  • @shadow I modified the function to return: `ifelse(x > 1e-02, round(seq(min(x)+d, max(x)-d, length=n), 2), round(seq(min(x)+d, max(x)-d, length=n), 4) )` because my data have different orders of magnitude, but now I get only two of them shown on plot, no matter what `n` is. My data is here: http://stackoverflow.com/questions/31961170/changing-the-breaks-and-limits-in-a-facet-grid-where-scales-free-y – user4786271 Aug 12 '15 at 10:28
  • This works also for me, but I do not have any idea why. In particular, what does the use of ellipsis (i.e. "...") in the function "equal_breaks" mean ?? Is this an official way of using scale_continuous or is it some kind of hack ? – fstevens Nov 26 '15 at 10:20
  • 1
    @fstevens: (1) The ellipsis argument is absolutely not necessary. Don't remember now why I added it, probably meant to extend the function somehow and then did not remove the ellipsis before posting. (2) This is a standard way of using the breaks argument in `scale_continuous`. For many possible breaks, there are standard functions in the `scales` package, e.g. `pretty_breaks`, `log_breaks`. But it is not uncommon that you have to add your own, if you want the scales to look in some specific way. – shadow Dec 01 '15 at 08:45