dfrankow
dfrankow

Reputation: 21469

Simple way to split a plot into panels in ggplot?

Suppose I have this example:

df <- data.frame(name=c('aaa', 'bbb', 'ccc', 'ddd'), x = c(1,2,3,4))
ggplot(df, aes(name, x)) + geom_point() + coord_flip()

plot1

Now suppose I actually have 100 names, so I want to split this into two plots, each with 50 names.

I can try faceting, but each facet still has all the names.

df <- df %>% mutate(panel = floor((row_number()-1)/2))

ggplot(df, aes(name, x)) + geom_point() + coord_flip() +
  facet_wrap(~panel)

plot2

I can write a loop to make multiple plots, and then stick them together later in a doc:

plots <- list()
for (idx in 1:2) {
  plots[[idx]] <- ggplot(df %>% filter(panel == (idx-1)),
                       aes(name, x)) + geom_point() + coord_flip()
}

However, is there a simpler way to display two panels, each with only its own names? For example, maybe facet_wrap (or something else) will drop names without any data?

Upvotes: 1

Views: 2186

Answers (1)

Duck
Duck

Reputation: 39623

Short answer:

Use facet_wrap(~panel, scales="free_y"). It will drop points with no y value.

Wordier example:

Maybe you are looking for this. You can use cut() and quantile() to determine a, in some sense, cut point into a key dataframe that contains the unique names and an index i so that you split data in two groups as desired. Here, I have added a dummy data with 50 rows and different groups to see how it works (Updated many thanks to @dfrankow for the advice):

library(ggplot2)
#Data
df <- data.frame(name=sample(c('aaa', 'bbb', 'ccc',
                               'ddd','eee','fff',
                               'ggg','hhh','iii','jjj'),50,replace = T), x = c(1:50))
#Create unique names
keys <- data.frame(name=unique(df$name))
keys$i <- 1:nrow(keys)
keys$panel <- cut(keys$i,breaks = c(-Inf,quantile(keys$i,0.5),Inf),include.lowest = T,right = T,
                labels = c('G1','G2'))
#Add group
df$panel <- keys[match(df$name,keys$name),"panel"]
#Plot
ggplot(df, aes(name, x)) + geom_point() + coord_flip() +
  facet_wrap(~panel,scales = 'free_y')

Output:

enter image description here

Upvotes: 1

Related Questions