1
votes

In a shiny app, I let users subset data, and then create a plot in which a categorical variable is reordered from higher to lower according to the value of another variable and displayed following the user input.

I would like color and fill to be linked to the category variable irrespective of the order.

Tried and not working solutions:

MWE:


data <- mtcars %>% 
  rownames_to_column() %>% 
  rowid_to_column() %>% 
  mutate(rowname = reorder(rowname, mpg))

plot <- data %>% 
  ggplot(aes(rowname, mpg, fill = rowname, color = rowname))+
  geom_col()+
  coord_flip()

plot %+% droplevels(filter(data, rowid < 3))

produces this:

enter image description here

while

plot %+% droplevels(filter(data, rowid < 4))

produces this:

enter image description here

In a nutshell:

Intended behavior: colors are matched to category irrespective of order of the plot.

Actual behavior: colors change depending on position of the category once reordered.

1

1 Answers

2
votes

You should assign a colour value to each category which you can use in scale_fill_manual and scale_color_manual.

values = c("Mazda RX4" = "red", "Mazda RX4 Wag" = "blue", "Datsun 710" = "green")
plot %+% droplevels(filter(data, rowid < 3)) +
  scale_fill_manual(values = values) +
  scale_color_manual(values = values)
plot %+% droplevels(filter(data, rowid < 4)) +
  scale_fill_manual(values = values) +
  scale_color_manual(values = values)

example 1 example 2

You can also do this automatically for all the levels.

library(scales)
values <- c(hue_pal()(length(levels(data$rowname))))
names(values) <- levels(data$rowname)

However, you'll have to think a bit more carefully about the colours when you have a large number of categories.