Change text color for single facets in ggplot2
Asked Answered
J

3

5

I have created the plot below with these commands:

ggplot(long.data, aes(owner,value)) + stat_summary(fun.y=mean,geom="bar",
       fill=c("deepskyblue","deepskyblue4")) + 
       stat_summary(fun.data=mean_cl_normal,geom="errorbar",position=
       position_dodge(width=.90),width=.1) +
       labs(x="",y="") + facet_grid(IV~experiment+type,scales="free_y") + 
       theme(strip.text.y = element_text(colour = 'red4'))

If I want to change the text color (and possibly also the background color) for only the upper x facet (in this case 'Implicit' and 'Explicit' levels), how can I do that? Is it possible? I have not read nothing about that in the ggplot2 documentation.

plot

EDIT: I'm sorry for the confusion. My aim is to change the text and background color of one of the upper strips, not the color of the facet.

Joinery answered 24/4, 2013 at 12:44 Comment(6)
Doing background is certainly feasible; see this question. Text can be handled similarly by adding a variable for colour.Liscomb
Yes, in the link you posted the problem was to change the background of the full graph. I want to change the text color (and the background) for only one of the facet labels.Joinery
I have done that, I think by setting the variable for the facets I did not want coloured to NULL. Have a careful read and you should get it.Liscomb
@Liscomb I have carefully read the post, but nothing. Adding a color variable does not work for me. Basically, what I want to do is to use strip.text.x=element_text(color="red") only for the Implicit/Explicit labels, and not foe the Body/Objects label.Joinery
I'm afraid I don't understand what it is you want. You said you want to change the "upper x facet"? If not the facet, what is it that you want to change?Liscomb
Sorry, not the facets, but the labels (and possibly the background) of one of the two upper strips, specifically the Implicit/Explicit strip. Is it possible?Joinery
L
6

You want to change the attributes of the strip element, not the facet. Try something like the code below. Note that this is a minimal example based on fake data made up at random, as you did not provide your own data for us to work with. You'll have to adapt the code to your needs.

require(reshape)
require(ggplot2)
require(scales)

# fake data
mydf <- data.frame(val1 = runif(10, 0, 1), val2 = runif(10, 0, 1))
mydf

# reshape to long format
long.data <- melt(mydf)
long.data$facetvar <- "implicit"
long.data$facetvar[seq(1, 19, 2)] <- "explicit"
long.data

# plot
ggplot(long.data, aes(y = value, x = variable)) +
    geom_bar(position = 'dodge', stat = "identity") +
    facet_wrap (~ facetvar) +
    theme(strip.background = element_rect(fill = alpha('green', 0.3))) +
    theme(strip.text.x = element_text(colour = 'blue', size = 10))

This produces a plot like this: screenshot

Liscomb answered 25/4, 2013 at 7:49 Comment(2)
Thanks for your answer. In my case, I have two upper strips (so two factors), and I want to change the color for only one of them. So the strip Implicit/Explicit would be (say) red, and the strip Body/Objects would be (say) orange. Can strip.text.x work for selected strips?Joinery
I don't know. Have you tried yet? As I don't have your data (or 'fake' data arranged in the same way as your real data) I can't experiment without a lot of guesswork and inconvenience on my part. This is a classic example of why you should include data. My advice is to try and see.Liscomb
C
4

I get a warning... but this seems a good starting point for a more elegant solution:

ggplot(mtcars) + geom_rect(data = subset(mtcars, cyl == 4), aes(fill = cyl),xmin = -inf,xmax = Inf, ymin = -Inf,ymax = Inf, alpha = 0.05) +
  geom_point(aes(mpg, wt)) +  facet_grid(. ~ cyl)

enter image description here

Constant answered 24/4, 2013 at 13:10 Comment(2)
Maybe I was not very clear in my explanation, so I apologize with you for that. Baically, my aim is to make the words 'Implicit' and 'Explicit' in (say) red color, and possible also make the relative background color from gray to (say) orange.Joinery
@Joinery since you already did that for the vertical labels (making them red) I guess you want something different that I didn't get yet, sorry about that.Constant
T
-1

There's a cool library called "ggh4x" which allows for better handling of strip labels. Check this answer. You have to manually set a list of aesthetics (let that be color, font, size etc) through strip_themed() function. Then add the list to the ggh4x::facet_grid2() or ggh4x::facet_wrap2() functions via the "strip" argument.

Edit: addition of an example as requested in the comments:

library(tidyverse)

library(ggh4x)

 strip <- strip_themed(background_x = elem_list_rect(fill = c("#00000000", "#00000000", "#49d278", "#49d278", "red")), #strip background

                       text_x=elem_list_text(face = c("bold", "italic", "plain", "plain", "plain"))) #strip text
 
diamonds|> ggplot(aes(x=price, y=carat))+
geom_point()+
scale_x_continuous(labels=scales::label_number_si())+
facet_grid2(~cut, strip=strip) 

Resulting plot

Tetryl answered 1/3, 2024 at 16:58 Comment(2)
While your link may solve the OP's question, link-only answer are discouraged for these reasons. Further, it is expected that if users find another relevant answer on SO, that they comment rather than posting links as questions. Once you have enough reputation, you will be able to comment. ThanksTricho
Thanks. Updated the answer with a reproducible example. Hope that'll do the trick. Cheers.Tetryl

© 2022 - 2025 — McMap. All rights reserved.