Reputation: 799
I'm generating a lot of faceted graphs with discrete x-axis inside my R scripts. Sometimes, I get overlapping labels in x-axis, and I would like to avoid it:
Since I don't know in advance how big the graph is going to be (number of facets and breaks), I can't assign it manually to ggsave.
Any tips or best practices in this case?
Upvotes: 4
Views: 287
Reputation: 22313
You can extract the number of facets of your plot with the following function. I have tried to be as general as possible and it should be applicable for both facet_grid
and facet_wrap
faceting. It is however possible that I have overlooked some possibilities. If so, please leave a comment.
nfacetcols <- function(p) {
if (is.null(p$facet$cols) & is.null(p$facet$facets)) return(1)
# facet_grid - version
if (! is.null(p$facet$cols)) {
if (length(p$facet$cols)==0) return(1)
dat <- p$data[,as.character(p$facet$cols)]
if (is.factor(dat)) return(nlevels(dat))
if (is.data.frame(dat)) return(nrow(unique(dat)))
if (is.numeric(dat)) return(length(unique(dat)))
}
# facet_wrap - version
if (! is.null(p$facet$facets)){
if (!is.null(p$facet$ncol)) return(p$facet$ncol)
dat <- p$data[,as.character(p$facet$facets)]
tot <- ifelse(is.factor(dat), nlevels(dat), nrow(unique(dat)))
if (!is.null(p$facet$nrow)) return(ceiling(tot/p$facet$nrow))
return(ceiling(sqrt(tot)))
}
}
With this function, you can extract the number of columns. The number of levels of your x
-factor can easily be extracted using
xlvls <- nlevels(p$data[,p$labels$x])
Then using the suggestion of @agstudy, you can use the following code to ggsave
your plot:
# create data set
set.seed(123)
N <- 20
df <- data.frame(a = sample(LETTERS[1:10], N, replace=TRUE),
b = sample(letters[1:5], N, replace=TRUE),
yax = rnorm(N),
xax = factor(sample(letters[16:20], N, replace=TRUE)))
# plot
p <- ggplot(df, aes(xax, yax)) + geom_point() + facet_grid(b~a)
ggsave("eg.plot.png",
p + theme(axis.text.x = element_text(angle = 90, hjust = 1)),
width=xlvls*nfacetcols(p)/5)
Upvotes: 1
Reputation: 121578
Not an exact solution but a practice that usually works well: You can rotate the axis labels.
data(diamonds)
diamonds$cut <- paste("Super",as.character(diamonds$cut))
q <- qplot(cut,carat,data=diamonds,geom="boxplot") +
facet_grid(~color)
library(gridExtra)
grid.arrange(q,
q + theme(axis.text.x = element_text(angle = 90, hjust = 1)))
second solution
Use facet_wrap
with one column ( 1 or few columns)
qplot(cut,carat,data=diamonds,geom="boxplot") +
facet_wrap(~color,ncol=1)
Upvotes: 2