3

I am trying to set the labels on a categorical axis within a faceted plot using the ggplot2 package (1.0.1) in R (3.1.1) with scales="free". If I plot without manually setting the axis tick labels they appear correctly (first plot), but when I try to set the labels (second plot) only the first n labels are used on both facets (not in sequence as with the original labels).

Here is a reproducible code snippet exemplifying the problem:

foo <- data.frame(yVal=factor(letters[1:8]), xVal=factor(rep(1:4,2)), fillVal=rnorm(8), facetVar=rep(1:2,each=4))
## axis labels are correct
p <- ggplot(foo) + geom_tile(aes(x=xVal, y=yVal, fill=fillVal)) + facet_grid(facetVar ~ ., scales='free')
print(p)
## axis labels are not set correctly
p <- p + scale_y_discrete(labels=c('a','a','b','b','c','d','d','d'))
print(p)

I note that I cannot set the labels correctly within the data.frame as they are not unique. Also I am aware that I can accomplish this with arrange.grid, but this requires "manually" aligning the plots if there are different length labels etc. Additionally, I would like to have the facet labels included in the plot which is not an available option with the arrange.grid solution. Also I haven't tried viewports yet. Maybe that is the solution, but I was hoping for more of the faceted look to this plot and that seems to be more similar to grid.arrange.

It seems to me as though this is a bug, but I am open to an explanation as to how this might be a "feature". I also hope that there might be a simple solution to this problem that I have not thought of yet!

cr1msonB1ade
  • 1,716
  • 9
  • 14
  • 1
    You can still get facet strip labels even if you make individual plots and then combine them with `grid.arrange`. `facet_grid` and `facet_wrap` will still work, even if your facetting variable has only one category. That's not to say there aren't other difficulties to overcome with the `grid.arrange` solution (as you note), but I thought I'd point out that you can at least get the facet labels with standard `ggplot` code, even for single plots. – eipi10 Jun 16 '15 at 20:13
  • Another option might be to remove the axis text labels and add them inside the plot with `geom_text`. [This answer](http://stackoverflow.com/a/20526579/2461552) shows the general idea, although in your case I could see skipping the `stat_summary` and use white text directly on top of each tile. – aosmith Jun 16 '15 at 20:47

2 Answers2

2

The easiest method would be to create another column in your data set with the right conversion. This would also be easier to audit and manipulate. If you insist on changing manually:

You cannot simply set the labels directly, as it recycles (I think) the label vector for each facet. Instead, you need to set up a conversion using corresponding breaks and labels:

p <- p + scale_y_discrete(labels = c('1','2','3','4','5','6','7','8'), breaks=c('a','b','c','d','e','f','g','h'))
print(p)

Any y axis value of a will now be replaced with 1, b with 2 and so on. You can play around with the label values to see what I mean. Just make sure that every factor value you have is also represented in the breaks argument.

Chris
  • 6,302
  • 1
  • 27
  • 54
  • This is great and works perfectly! In terms of your first suggestion though, once the correct column is added to the data set how would I use this column in order to specify the correct labels? As far as I know there is not an aesthetic for tick labels and as I noted I cannot just add a column for the y-value as they are not unique and thus would not plot correctly. – cr1msonB1ade Jun 16 '15 at 21:16
  • 1
    Fair point, the duplication of labels for different 'true' values of y prohibits you from adding the column. I'm not sure what your specific use case is, but in my mind this might lead to a fairly misleading graph. – Chris Jun 16 '15 at 21:22
  • I'm actually using this to do a sort of nested facet (two facets in one dimension) and using the tick labels as the label for the inner facet (as well as an added `geom_hline`). Thus most of the tick labels are actually empty strings. I know that I can accomplish this with a combined facet variable, but I wanted to emphasize one facet over the other which this would not accomplish. I know that is a bit convoluted, but thought it was a weird behavior so thought I would ask. Thanks for this workaround! – cr1msonB1ade Jun 16 '15 at 21:29
0

I think I may actually have a solution to this. My problem was that my labels were not correct because as someone above has said - it seems like the label vector is recycled through. This line of code gave me incorrect labels.

ggplot(dat, aes(x, y))+geom_col()+facet_grid(d ~ t, switch = "y", scales = "free_x")+ylab(NULL)+ylim(0,10)+geom_text(aes(label = x))

However when the geom_text was moved prior to the facet_grid, the below code gave me correct labels.

ggplot(dat, aes(x, y))+geom_col()+geom_text(aes(label = x))+facet_grid(d ~ t, switch = "y", scales = "free_x")+ylab(NULL)+ylim(0,10)

There's a good chance I may have misunderstood the problem above, but I certainly solved my problem so hopefully this is helpful to someone!

MokeEire
  • 638
  • 1
  • 8
  • 19