4

I have grouped boxplots with ggplot

require(ggplot2)
require(tidyr)
require(lubridate)

dat.1415<-as.data.frame(sample(1:1000, 181))
dat.1415$date<-seq(as.Date("2014-11-1"), as.Date("2015-4-30"), "day")
names(dat.1415)<-c("value", "date")
dat.1415$month<-month(dat.1415$date)
dat.1415$season<-"2014/15"

dat.1516<-as.data.frame(sample(1:1000, 182))
dat.1516$date<-seq(as.Date("2015-11-1"), as.Date("2016-4-30"), "day")
names(dat.1516)<-c("value", "date")
dat.1516$month<-month(dat.1516$date)
dat.1516$season<-"2015/16"

dat.1617<-as.data.frame(sample(1:1000, 181))
dat.1617$date<-seq(as.Date("2016-11-1"), as.Date("2017-4-30"), "day")
names(dat.1617)<-c("value", "date")
dat.1617$month<-month(dat.1617$date)
dat.1617$season<-"2016/17"

dat.1718<-as.data.frame(sample(1:1000, 181))
dat.1718$date<-seq(as.Date("2017-11-1"), as.Date("2018-4-30"), "day")
names(dat.1718)<-c("value", "date")
dat.1718$month<-month(dat.1718$date)
dat.1718$season<-"2017/18"


dat<-rbind(dat.1415, dat.1516, dat.1617, dat.1718)
dat$month<-month.abb[dat$month]
dat$month<-factor(dat$month)
dat$facet = factor(dat$month, levels = c("Nov", "Dec", "Jan", "Feb", "Mar", "Apr"))

ggplot(dat, aes(x=season, y=value)) + 
    geom_boxplot(fill="grey50") + 
    facet_grid(~facet) + 
    theme_classic()+    
    theme(legend.position="top") +
    labs(x="", y="", title="") +
    guides(fill=F) +
    theme(panel.background = element_rect(fill="grey95"))

Grouped boxplots

But because it's so many boxes, I get overlapping labels on the x-axis. Is there a way I can make them alternating between the different facets? I don't want the position of the x-axis to alternate but the actual labels, say in facet one it's "2014/15" and "2016/17", in facet 2 it's "2015/16" and "2017/18" and so on. Is that possible?

Anke
  • 527
  • 1
  • 6
  • 19
  • Have you considered flipping the facets so there's only one x-axis? facet_grid(facet ~ .) – Jordo82 Nov 01 '18 at 18:27
  • It's a rather unusual request, but if there has been a similar question in hte past, then a ggplot2 based answer would probably have involved the use of `guide`-type functions. – IRTFM Nov 01 '18 at 18:36
  • I'd take a stab at it if you post a [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). That includes a representative but minimal sample of data, and a minimal amount of code (i.e. no cleanup, just what's needed to recreate the issue) – camille Nov 01 '18 at 20:06
  • @Jordo82: Yes, that would be an option, but I just tried it and feel like it makes the graph less intuitive to read. – Anke Nov 01 '18 at 23:03
  • @42 Not sure what guide-type functions are, but will look into this. Thank you – Anke Nov 01 '18 at 23:03
  • @camille Let me try to add some data. I will not be able to publicly post my own data, so let me work on creating a reproducible example. I will edit my original post. – Anke Nov 01 '18 at 23:04
  • `Error in month(dat.1415$date) : could not find function "month"`.Perhaps you assumed incorrectly that everyone loves the lubridate package? – IRTFM Nov 02 '18 at 00:33
  • @42 Oops, sorry! I have so many libraries running in my original code with a lot of different things going on, I just forgot which is for what. Will add it above. Thanks! – Anke Nov 02 '18 at 00:36
  • Keeping code to a minimum is helpful for folks who are debugging. If you post the output of `dput(dat)` instead of everything that goes into creating and rearranging `dat`, you'd eliminate about 30 lines of code from the question – camille Nov 02 '18 at 01:01
  • @camille the output of dput(dat) is magnitudes of number of lines longer than the code. Maybe I'm missing the point (my apologies), but the code above let's people copy&paste the code and recreate the dataset, no? I may eliminate 30 lines of code from the question, but add over 300 lines of data. If I miss something, please bear with me as I'm still fairly new to working with R and happy to learn. – Anke Nov 02 '18 at 01:11
  • That's fair, but there's a lot you could do to simplify, though. Your data frame has 5 variables, but only 3 are used for plotting; 2 facets would be enough to illustrate the issue; you could make the boxplots with only 5 to 10 observations each. That gets you down to a couple lines of `dput` output, and after eliminating plot formatting that isn't essential, you have a minimal and easy to understand question – camille Nov 02 '18 at 01:27
  • Suspect you will need to make separate plots and then bind them together: https://stackoverflow.com/questions/50513257/ggplot2-facet-grid-with-distinct-x-axis-labels-using-facet-grid – IRTFM Nov 02 '18 at 03:56

2 Answers2

6

try to rotate you labels to have full information

+ theme(axis.text.x = element_text(angle = 30, hjust = 1)) 

Edits

Or try to manipulate your data somehow and use something like

+ scale_x_discrete(breaks=c("1","3"), labels=c(...))

Edits2: I set the color to 0 for the ones to skip.

ggplot(dat, aes(x=season, y=value)) + 
  geom_boxplot(fill="grey50") + 
  facet_grid(~facet) + 
  theme_classic()+    
  theme(legend.position="top") +
  labs(x="", y="", title="") +
  guides(fill=F) +
  theme(panel.background = element_rect(fill="grey95"))+ 
  theme(axis.text.x = element_text(color=c(1,0,1,0))) 

enter image description here

Bing
  • 1,083
  • 1
  • 10
  • 20
  • That would be an option, yes, but it would also make it inconsistent with other graphs I have. But It's probably a last resort – Anke Nov 01 '18 at 22:56
  • I just added data above in my original post. I tried assinging labels manually with scale_x_discrete(), but that didn't work. I could do all "2014/15" and "2016/17", for example, but couldn't alternate them. Will try your edited approach, now. – Anke Nov 02 '18 at 00:25
  • Please see my edits. By setting the colors, you can omit (hide) some labels. – Bing Nov 05 '18 at 16:56
3

The new version of ggplot v3.3.0 has added the ability to use guide_axis to dodge the labels.

scale_x_discrete(guide = guide_axis(n.dodge = 2))

So adding that to your plot:

ggplot(dat, aes(x=season, y=value)) + 
    geom_boxplot(fill="grey50") + 
    facet_grid(~facet) + 
    theme_classic()+    
    theme(legend.position="top") +
    labs(x="", y="", title="") +
    guides(fill=F) +
    theme(panel.background = element_rect(fill="grey95")) + 
    scale_x_discrete(guide = guide_axis(n.dodge = 2))

produces the following:

enter image description here

Russ Thomas
  • 938
  • 4
  • 13
  • 23