1

Working from a solution posted elsewhere (ggplot2: text color based on background contrast), I've created a simple bar chart with labels that should be coloured white or black depending on the colour of the bar (i.e. white text for dark bars).

Firstly, I'm not sure that the code is working as intended, as white text is being used to label light-coloured bars. Secondly, the legend includes some of the code I've used for assigning colours.

Have you any suggestions to resolve these two issues? I've included an image of the chart for reference.

enter image description here

# Create a table of the proportions for use when creating the plot.
plotdata <- treatment_dataset %>%
  group_by(STAGE, TREATMENT_GROUP) %>%
  summarize(n = n()) %>% 
  mutate(pct = n/sum(n),
         percentages = scales::percent(pct))
plotdata

# Plot the data from the table above
ggplot(plotdata, 
       aes(x = STAGE, 
           y = pct, 
           fill = TREATMENT_GROUP)) + 
  geom_bar(stat = "identity",
           position = "fill") +
  labs(y = "Proportion of tumours",
       x = "Tumour stage at diagnosis",
       fill = "Treatment group"
       )  +
  scale_y_continuous(labels = scales::percent) -> treatment_by_stage

# Apply PHE formatting.
treatment_by_stage + theme_phe("phe") +
  scale_fill_phe(name = "Treatment group",
                 theme = "phe") +
  geom_text(aes(label = ifelse(pct < 0.05, NA, percentages), color = plotdata$pct > 0.01), 
            size = 3, 
            position = position_stack(vjust = 0.5)
            ) +
  scale_color_manual(values = c("black", "white"))
user518206
  • 93
  • 1
  • 1
  • 7
  • Possible duplicate of [How to control label color depending on fill darkness of bars?](https://stackoverflow.com/questions/49716005/how-to-control-label-color-depending-on-fill-darkness-of-bars) – tjebo Nov 27 '19 at 12:51
  • if you don't think that the question you pointed towards does not help you - please explain in the question why you think so and what you have tried – tjebo Nov 27 '19 at 12:52
  • Hey, if the text colors are conditional on the fill colors, then pct < 0.05 is conditioning on percentages, and will not work. Can you dput(treatment_dataset) and paste the output as part of your question? I am sure a lot of SO users can make that work – StupidWolf Nov 27 '19 at 13:35

1 Answers1

3

Your situation is a bit different from the post mentioned by @Tjebo. In your case, you know which colors you need to label with white text, and which with black. It's a case of assigning the text colors to the right group (Treatment Group).

First we simulate data like yours:

library(tidyverse)
library(RColorBrewer)

#simulate data

set.seed(100)
df <- data.frame(
STAGE = rep(LETTERS[1:4],each=5),
n=sample(1:100,20),
TREATMENT_GROUP=rep(paste("T",1:5,sep=""),4))

And we make the data for plotting like you did, note I set the NAs here.

# make plotdata with percentages

plotdata <- df %>%
  group_by(STAGE) %>%
  mutate(pct = n/sum(n),
         percentages = scales::percent(pct))

# set NA to percentages here
# not very sure the ifelse you had previously works
plotdata$percentages[plotdata$pct < 0.05]<-NA

Now we can manually define the colors. I cannot find the color schemes you used, so I used a "Oranges" from RColorBrewer.

COLS=brewer.pal(5,"Oranges")
names(COLS) = levels(plotdata$TREATMENT_GROUP)
# here the last 2 colors are dark, so we just set 
# first 3 to black and last 2 to white
TEXTCOLS = c("black","black","black","white","white")
names(TEXTCOLS) = levels(plotdata$TREATMENT_GROUP)

Make the preliminary plot

treatment_by_stage =
ggplot(plotdata, 
       aes(x = STAGE, 
           y = pct, 
           fill = TREATMENT_GROUP)) + 
  geom_bar(stat = "identity") +
  labs(y = "Proportion of tumours",
       x = "Tumour stage at diagnosis",
       fill = "Treatment group"
       )  +
  scale_y_continuous(labels = scales::percent)+
  scale_fill_manual(values=COLS)

And now we add the labels:

treatment_by_stage + 
geom_text(aes(label=percentages,
          color = TREATMENT_GROUP), 
            size = 3, show.legend=FALSE,
            position = position_stack(vjust = 0.2)
            ) +
  scale_color_manual(values = TEXTCOLS)

enter image description here

StupidWolf
  • 45,075
  • 17
  • 40
  • 72