user213544
user213544

Reputation: 2126

How to show only available geom_segment values in a facet_grid() in ggplot?

I am trying to create a swimmerplot using facet_grid() in ggplot, that displays the time per id.

I managed to visualize the data with the code below. Using facet_grid() I was able to differentiate the IDs that have a time>100 vs. time<=100.

# Create sample dataframe
df <- data.frame(id=seq(1,15,1),
                 time=c(50, 101, 45, 35, 200, 78, 30, 149, 156,58, 39, 10, 65, 38, 20), 
                 test = c(F,T,F,F,T,F,F,T,T,F,F,F,F,F,F))
# Swimmerplot
ggplot(data=df) +
  geom_segment(aes(x=id, xend=id, y=0, yend=time), size = 4) +
  facet_grid(test~.) +
  coord_flip()

Here is the output produced, sample_output

As can be seen from the output, every id is shown in both facets.

Question

I would like to show only the IDs that have an 'available' time value per facet_grid. How do I do that in ggplot? Is geom_segment the proper geom?

Upvotes: 1

Views: 650

Answers (3)

deepseefan
deepseefan

Reputation: 3791

Probably this is what you want (just add scales = "free", space = "free") which does the magic of removing unused factors from the facets.

ggplot(data=df) +
  geom_segment(aes(x=as.factor(id), xend=as.factor(id), y=0, yend=time), size = 4) +
  facet_grid(test~., scales = "free", space = "free") +
  coord_flip()

Output

Output_desired

Upvotes: 3

m070ch
m070ch

Reputation: 56

This is the solution i found for what you're looking for:

ggplot(data=df) +
 geom_bar(aes(x=as.factor(id), y=time), size = 4, stat = "identity") +
 facet_grid(test~., scales = "free") +
 coord_flip()

as.factor changes id into a categorical variable, and scales=free allows the facets to have different scales, so they now have only the values of id with data in their facet.

This solution didn't work with geom_segment but did for geom_bar(..., stat = "identity")

Upvotes: 1

yoland
yoland

Reputation: 554

You should store id as a factor or character vector. Also I think, it is more straigforward to use geom_bar() with stat = "identity". It's not pretty, but this does what you want I think:

df <- data.frame(id=seq(1,15,1),time=c(50, 101, 45, 35, 200, 78, 30, 149, 156,58, 39, 10, 65, 38, 20), test = c(F,T,F,F,T,F,F,T,T,F,F,F,F,F,F))
ggplot(data=df, aes(x=factor(id), y=time)) +
  geom_bar(size = 4, stat = "identity", na.rm = T) +
  facet_wrap(~test, scales = "free_y", ncol = 1) +
  coord_flip()

Result:

enter image description here

Upvotes: 2

Related Questions