Plot words and points with gradient, except for a few in black as specified in another column (R ggplot2)

Viewed 75

I would like to plot some words with points, where the data are plotted according to a gradient except for those in the middle which are coloured black (with no gradient). See example data and plot below, where I would like the variable color_black to override the gradient for those words (and their points) with 0.

(I suspect I would like to avoid adding another layer on-top as it might make the plot messy when more words are plotted on it?)

# Possibility to increase the data to test that there are no (only little) overlap of labels
n=5
#Labels plotted in figure
text <- c(rep("zero", n),
          rep("one", n),
          rep("two", n),
          rep("three", n),
          rep("four", n),
          rep("five", n),
          rep("six", n),
          rep("seven", n),
          rep("eight", n))

# Variable forming the color gradient (and position)
color_my <- c(rep(-4, n),
          rep(-3, n),
          rep(-2, n),
          rep(-1, n),
          rep(0, n),
          rep(1, n),
          rep(2, n),
          rep(3, n),
          rep(4, n))


# Words with "1" should be part of the gradient; 0 should just be "gray" with NO gradient
color_gray <- c(rep(1, n),
              rep(1, n),
              rep(1, n),
              rep(0, n),
              rep(0, n),
              rep(0, n),
              rep(1, n),
              rep(1, n),
              rep(1, n))


data_test <- data.frame(text, color_my, color_gray)
data_test <- as_tibble(data_test)
colors_words_scale = c(-1, 0, 1)

library(ggplot2)
library(ggrepel)
library(scales)

# Plot
plot <- data_test %>%

  ggplot2::ggplot(ggplot2::aes(color_my, y=1, label = text)) +

  ggrepel::geom_text_repel(
    ggplot2::aes(color = color_my)
  ) +

  # Color of the points
  ggplot2::geom_point(
    ggplot2::aes(color = color_my)
  ) +

  # Color gradient
  ggplot2::scale_colour_gradientn(
    colours = c("blue", "lightblue", "black", "orange", "red"),
    values = scales::rescale(colors_words_scale),
    aesthetics = "colour"
  ) +

  # minimal theme
  ggplot2::theme_minimal()

plot

example of plot

Thanks you for your help.

1 Answers

You are looking to have a separate part of your data have color not applied according to the gradient, right? The most straightforward way to do this is to have two sets of geom calls and subset from your data accordingly. It does double your geom_ function calls, but avoids any overplotting.

Here's my adjustments (Note I changed the color in the middle to magenta so that it's more obvious the effect here):

plot <- ggplot(data_test, aes(color_my, y=1, label = text)) +  
  geom_text_repel(
    data=data_test[which(data_test$color_gray!=0),],
    aes(color = color_my)) +  
  geom_point(
    data=data_test[which(data_test$color_gray!=0),],
    aes(color = color_my)) +
  geom_text_repel(
    data=data_test[which(data_test$color_gray==0),],
    color='magenta') +
  geom_point(data=data_test[which(data_test$color_gray==0),],
    color='magenta') +
  scale_colour_gradientn(
    colours = c("blue", "lightblue", "black", "orange", "red"),
    values = rescale(colors_words_scale), aesthetics = "colour") +
  ggplot2::theme_minimal()

plot

enter image description here

Related