2

I am trying to produce a plot with a sort of "hybrid" layout between facet_grid and facet_wrap:

example:

library(reshape2)
library(ggplot2)

data(diamonds)

# sample and reshape diamond dataset
diamonds_l <- melt(diamonds[sample(1:nrow(diamonds), 200), 
                            c("cut", "depth", "table", "price", "x")],
                   id.vars = c("cut","x"))

this is the plot arrangement that I want (quality in columns and depth, table, price as rows)

ggplot( diamonds_l, aes( x = value, y = x, colour= cut))+
  geom_point( ) +
  facet_wrap( variable ~  cut, scales = "free_x", nrow=3) 

enter image description here

however, I would prefer the facet_grid design (only one header per column / row) but scales = "free_x" doesn't work in this layout

ggplot( diamonds_l, aes( x = value, y = x, colour= cut))+
  geom_point( ) +
  facet_grid(variable ~  cut, scales = "free_x") 

enter image description here

it works here but thats not the arrangement that I want (quality as rows)

ggplot( diamonds_l, aes( x = value, y = x, colour= cut))+
  geom_point( ) +
  facet_grid(cut ~ variable, scales = "free_x")

enter image description here

I understand why it won't work but I was wondering if there was a work-around?

thanks!

Fabian

Latrunculia
  • 696
  • 1
  • 7
  • 15

1 Answers1

3

After some digging, I managed to pull the trick. Pieces of code borrowed from here (@baptiste, @Roland) and here (@Sandy Muspratt). Looks scary, but I'm basically removing/renaming text strips from the first plot of yours via low-level manipulations.

p <- ggplot( diamonds_l, aes( x = value, y = x, colour= cut))+
  geom_point( ) +
  facet_wrap( variable ~ cut, scales = "free_x", nrow = 3) 

library(gridExtra)
gt <- ggplotGrob(p)
panels <- grep("panel", gt$layout$name)
top <- unique(gt$layout$t[panels])
gt <- gt[-(top[-1]-1), ]

gg <- gt$grobs      
strips <- grep("strip_t", names(gg))
labels <- levels(diamonds_l$cut)
for(ii in seq_along(labels))  {
  modgrob <- getGrob(gg[[strips[ii]]], "strip.text", 
                     grep=TRUE, global=TRUE)
  gg[[strips[ii]]]$children[[modgrob$name]] <- editGrob(modgrob,label=labels[ii])
}
gt$grobs <- gg
grid.newpage()
grid.draw(gt)

enter image description here

Community
  • 1
  • 1
tonytonov
  • 25,060
  • 16
  • 82
  • 98
  • thanks, its really nice! I saw some other places that you could remove the strips with low level manipulations but I was hoping for a simpler solution.. Also, would it be possible to add the row labels as in facet_grid in addition to removing the panel column labels? I leave the question open a bit longer but will accept your answer if nobody comes up with something simpler (which doesn't seem to be possible) – Latrunculia Jun 25 '15 at 10:47
  • Okay. Yes, potentially this could be possible, though adding things is generally easier than removing ones :) The outline would be 1) to take row strips from the `facet_grid` plot and 2) insert them to the grob tree of the plot above. I'm afraid my grid-fu is not cool enough, though. – tonytonov Jun 25 '15 at 11:19
  • You know what, if no one else shows up, you can ask a follow-up question, describing our current state and the proposed outline. Tag that with `grid` and `gridExtra`, and maybe we're lucky. If you do that, ping me with a comment, otherwise I may miss it. – tonytonov Jun 25 '15 at 11:24