Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combining new lines and italics in facet labels with ggplot2

Tags:

r

ggplot2

facet

I have a problem getting some words used in facet labels in italics. I use the following code to create new lines for the labels:

    levels(length_subject$CONSTRUCTION) <- 
c("THAT \n Extraposed", "THAT \n Post-predicate", "TO \n Extraposed \n for-subject", "TO \n Post-predicate \n for-subject", "THAT \n Extraposed \n that-omission", "THAT \n Post-predicate \n that-omission")

However, I want the words "that" and "for" to appear in italics. I've tried something like

"TO \n Extraposed \n (italics(for))-subject"

bit it doesn't work.

This is what the plots look like:

enter image description here

produced with the following code:

ggplot( length_subject, aes( x = SUBJECT ) ) +
  geom_histogram(binwidth=.6, colour="black", fill="grey") +
  ylab("Frequency") +  
  xlab("Subject length") +  
  scale_x_discrete(breaks=c(2,4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30)) + #
  facet_grid( SUBJECT_TYPE~CONSTRUCTION, scales="free_x", space="free") +
  theme(strip.text.x = element_text(size = 8)) 

Here is a reduced variant of the data:

structure(list(ID = structure(1:86, .Label = c("A05_122_01", 
"A05_253_01", "A05_277_07", "A05_400_01", "A05_99_01", "A06_1076_01", 
"A06_1261_01", "A06_1283_01", "A06_1283_02", "A06_1317_01", "A06_1326_01", 
"A06_1389_01", "A06_1390_01", "A06_1437_01", "A06_1441_02", "A06_1441_03", 
"A06_1442_03", "A06_1456_01", "A06_1461_01", "A06_830_01", "A06_868_01", 
"A06_884_01", "A06_884_03", "A0K_1057_02", "A0K_1144_07", "A0K_1177_01", 
"A0K_1190_03", "A0K_1214_03", "A0K_1216_01", "A0K_950_02", "A0K_986_01", 
"A1A_102_02", "A1A_163_01", "A1A_199_01", "A1A_45_01", "A1A_97_01", 
"A1B_1008_02", "A1B_1013_01", "A1B_1028_02", "A1B_1042_01", "A1B_1064_01", 
"A1B_1126_03", "A1B_1152_01", "A1B_1174_01", "A1B_1271_01", "A1B_997_01", 
"A1J_487_01", "A1J_544_02", "A1J_555_03", "A1J_569_01", "A1J_601_01", 
"A1N_422_04", "A1N_70_02", "A1S_191_01", "A1S_329_01", "A1S_330_01", 
"A1S_465_04", "A1Y_248_01", "A1Y_278_02", "A1Y_292_01", "A1Y_466_01", 
"A1Y_521_01", "A1Y_612_01", "A1Y_634_01", "A26_139_03", "A26_142_01", 
"A26_148_01", "A26_289_01", "A26_345_02", "A26_439_01", "A26_441_02", 
"A26_463_01", "A28_171_01", "A28_244_01", "A28_245_01", "A28_30_01", 
"A28_341_01", "A28_42_01", "A28_494_03", "A2A_301_01", "A2A_396_01", 
"A2A_599_01", "A2A_637_01", "A2A_676_01", "A2E_22_01", "A2E_25_03"
), class = "factor"), SUBJECT = c(3L, 2L, 6L, 2L, 2L, 1L, 1L, 
1L, 1L, 2L, 4L, 1L, 4L, 2L, 3L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 7L, 1L, 3L, 2L, 2L, 1L, 6L, 7L, 4L, 1L, 5L, 4L, 2L, 9L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 3L, 5L, 3L, 4L, 1L, 1L, 1L, 1L, 5L, 
2L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 5L, 2L, 1L, 2L, 2L, 1L, 7L, 1L, 
4L, 1L, 2L, 1L, 1L, 3L, 1L, 13L, 2L, 1L, 1L, 1L, 3L, 1L, 1L), 
    CONSTRUCTION = structure(c(1L, 3L, 1L, 1L, 1L, 4L, 4L, 1L, 
    1L, 5L, 5L, 1L, 1L, 5L, 1L, 3L, 5L, 1L, 5L, 4L, 3L, 3L, 1L, 
    5L, 3L, 5L, 1L, 1L, 2L, 3L, 1L, 1L, 3L, 1L, 1L, 1L, 3L, 1L, 
    4L, 3L, 1L, 3L, 1L, 1L, 1L, 1L, 4L, 2L, 4L, 1L, 1L, 3L, 2L, 
    5L, 1L, 1L, 1L, 3L, 1L, 1L, 4L, 4L, 3L, 1L, 2L, 3L, 3L, 1L, 
    3L, 1L, 1L, 1L, 6L, 1L, 1L, 2L, 4L, 4L, 3L, 5L, 3L, 3L, 3L, 
    3L, 5L, 1L), .Label = c("THAT_EXT", "THAT_EXT_NT", "THAT_POST", 
    "THAT_POST_NT", "TO_EXT_FOR", "TO_POST_FOR"), class = "factor"), 
    SUBJECT_TYPE = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
    2L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 2L, 2L, 2L, 2L, 
    1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 3L, 1L, 1L, 
    2L, 3L, 1L, 2L, 2L, 3L, 1L, 3L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 
    1L, 1L, 1L, 2L, 2L, 3L, 2L, 2L, 2L, 3L, 1L, 1L, 2L, 1L, 1L, 
    2L, 1L, 2L, 1L, 2L, 1L, 2L, 2L, 1L, 2L, 1L, 1L, 2L, 2L, 2L, 
    1L, 3L, 3L), .Label = c("NP", "PRO", "PROPER"), class = "factor")), .Names = c("ID", 
"SUBJECT", "CONSTRUCTION", "SUBJECT_TYPE"), class = "data.frame", row.names = c(NA, 
-86L))
like image 480
user1504579 Avatar asked May 10 '13 20:05

user1504579


People also ask

How do you change facet wrap labels in R?

Change the text of facet labels Facet labels can be modified using the option labeller , which should be a function. In the following R code, facets are labelled by combining the name of the grouping variable with group levels. The labeller function label_both is used.

Can I facet wrap by two variables?

Note that you can add as many (categorical) variables as you'd like in your facet wrap, however, this will result in a longer loading period for R.

What is the function of Facet_grid () in Ggplot ()?

facet_grid() forms a matrix of panels defined by row and column faceting variables. It is most useful when you have two discrete variables, and all combinations of the variables exist in the data. If you have only one variable with many levels, try facet_wrap() .

How do I change the size of a facet label in ggplot2?

By default, the size of the label is given by the Facets, here it is 9. But we can change the size. For that, we use theme() function, which is used to customize the appearance of plot. We can change size of facet labels, using strip.


2 Answers

To get italics, you need the formatting described in plotmath (and then for that to be parsed as an expression). However, the plotmath syntax does not have a line break operation. You can get something similar with atop, though. With your given example, you can set the labels to

levels(length_subject$CONSTRUCTION) <- 
  c("atop(textstyle('THAT'),textstyle('Extraposed'))", 
    "atop(textstyle('THAT'),textstyle('Post-predicate'))",
    "atop(atop(textstyle('TO'),textstyle('Extraposed')),italic('for')*textstyle('-subject'))",
    "atop(atop(textstyle('TO'),textstyle('Post-predicate')),italic('for')*textstyle('-subject'))",
    "atop(atop(textstyle('THAT'),textstyle('Extraposed')),italic('that')*textstyle('-omission'))",
    "atop(atop(textstyle('THAT'),textstyle('Post-predicate')),italic('that')*textstyle('-omission'))")

and then adding labeller=label_parsed to the facet_grid call

ggplot( length_subject, aes( x = SUBJECT ) ) +
  geom_histogram(binwidth=.6, colour="black", fill="grey") +
  ylab("Frequency") +  
  xlab("Subject length") +  
  scale_x_discrete(breaks=c(2,4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30)) + #
  facet_grid( SUBJECT_TYPE~CONSTRUCTION, scales="free_x", space="free", 
              labeller=label_parsed) +
  theme(strip.text.x = element_text(size = 8)) 

gives

enter image description here

It's not perfect (the spacing between lines is not the same, and the disparity would only get worse the more lines there are), but that is the only way I've found to combine the two (newlines in plotmath expressions).

like image 114
Brian Diggs Avatar answered Nov 06 '22 11:11

Brian Diggs


Edit (2016)

With the new facet labelling system, this solution does not work anymore. The trick of inheriting from element_blank to make a custom grob is now explicitly disabled. I guess the lesson is to accept that some things cannot be done in ggplot2, by design, and not waste too much energy with workarounds that may get broken at any time in the future.


Original answer

You could try to create a suitable custom element to place in the theme settings. The theme design does not make it very easy, unfortunately,

require(ggplot2)
require(gridExtra) # tableGrob

element_grob.element_custom <- function(element, label="", ...)  {

  mytheme <- ttheme_minimal(core = list(fg_params = list(parse=TRUE)))
  disect <- strsplit(label, "\\n")[[1]]

  g1 <- tableGrob(as.matrix(disect), theme=mytheme)
  # wrapping into a gTree only because grobHeight.gtable would be too tight
  # cf. absolute.units() squashing textGrobs
  gTree(children=gList(g1), height=sum(g1$heights), 
        cl = "custom_strip")
}

# gTrees don't know their size and ggplot would squash it, so give it room
grobHeight.custom_strip = heightDetails.custom_axis = function(x, ...)
  x$height
# silly wrapper to fool ggplot2's inheritance check...
facet_custom <- function(...){
  structure(
    list(...), # this ... information is not used, btw
    class = c("element_custom","element_blank", "element") # inheritance test workaround
  ) 

}


title <- c("First~line \n italic('wait, a second')", 
           "this~is~boring",
           "integral(f(x)*dx, a, b)")

iris2 <- iris
iris2$Species <- factor(iris$Species, labels=title)
ggplot(iris2, aes(Sepal.Length, Sepal.Width)) +
  geom_line() + facet_grid(.~Species) +
  theme(strip.text.x = facet_custom())

enter image description here

like image 27
baptiste Avatar answered Nov 06 '22 10:11

baptiste