Home > Mobile >  ggplot2: add color (square) indicator to axis labels
ggplot2: add color (square) indicator to axis labels

Time:10-27

I have the following simple MWE.

set.seed(2022102517)
df <- data.frame(letter =factor(colors()[1:8], levels = colors()[1:8]), value = rnorm(8))
library(ggplot2)
ggplot(data = df, aes(x = letter, y = value, group = 1))   geom_line()

Which gives me a line plot for "value" for each "letter" as follows:

enter image description here

Note the ordering.

Now, what I would like to do is to have a small square in front of each colorname of different (assigned) color (from fill.col) (in the x-axis). So, basically, wherever we have a letter on x-axis, then add a filled color box to the left of each letter, where the colors are picked up from,say, fill.col.

fill.col <- c("#005A32", "#FC8D62", "#D95F02", "#8DA0CB", "#7570B3", "#E78AC3", "#E7298A", "#A6D854")

I tried the following (from the solution provided below):

library(tidyverse)
library(RColorBrewer)
library(ggtext)

df %>% 
  mutate(new_letter = paste("<span style = 'color: ",
                            fill.col,
                            ";'>",
                            "\u25a0",
                            "</span>",
                            " ",
                            letter,
                            sep = ""), 
         new_letter = fct_reorder(new_letter, as.character(letter))) %>%
  ggplot(aes(new_letter, value, group = 1))   
  geom_line()   
  theme(axis.text.x = element_markdown(size = 12))

which gives me:

enter image description here

It appears to me that in this case, we are reordering "letter" by the alphabet, though the color attachments appear to be correct here. Is it possible to keep the original order so that I can have control on the display? Thanks for further help and clarifications!

CodePudding user response:

One solution using ggtext, based on enter image description here

A slightly easier way is to add the colors in the axis theme, but this will also color the letters (and generate a warning):

df %>% 
  mutate(letter = paste("\u25a0", letter)) %>% 
  ggplot(aes(letter, value, group = 1))   
  geom_line()   
  theme(axis.text.x = element_text(color = brewer.pal(8, "Set2")))

Result:

enter image description here

CodePudding user response:

This is cumbersome, but I can't think of a better solution:

set.seed(2022102517)
df <- data.frame(letter =letters[1:8], value = rnorm(8))
library(ggplot2)
ggplot(data = df, aes(x = letter, y = value, group = 1))  
  geom_line()  
  coord_cartesian(clip = "off", ylim = c(-0.5, 1.2))  
  annotate("rect", fill = "#66C2A5",
           xmin = 0.7, xmax = 0.85,
           ymin = -0.65, ymax = -0.6)  
  annotate("rect", fill = "#FC8D62",
           xmin = 1.7, xmax = 1.85,
           ymin = -0.65, ymax = -0.6)  
  annotate("rect", fill = "#8DA0CB",
           xmin = 2.7, xmax = 2.85,
           ymin = -0.65, ymax = -0.6)  
  annotate("rect", fill = "#E78AC3",
           xmin = 3.7, xmax = 3.85,
           ymin = -0.65, ymax = -0.6)  
  annotate("rect", fill = "#A6D854",
           xmin = 4.7, xmax = 4.85,
           ymin = -0.65, ymax = -0.6)  
  annotate("rect", fill = "#FFD92F",
           xmin = 5.7, xmax = 5.85,
           ymin = -0.65, ymax = -0.6)  
  annotate("rect", fill = "#E5C494",
           xmin = 6.7, xmax = 6.85,
           ymin = -0.65, ymax = -0.6)  
  annotate("rect", fill = "#B3B3B3",
           xmin = 6.7, xmax = 6.85,
           ymin = -0.65, ymax = -0.6)  
  annotate("rect", fill = "grey50",
           xmin = 7.7, xmax = 7.85,
           ymin = -0.65, ymax = -0.6)

Created on 2022-10-27 by the reprex package (v2.0.1)

Does this solve your problem, or are you looking for a more 'flexible' solution?

  • Related