There's a given dataframe
df <- data.frame("V1" = c(0,0,0,0,0,2,2,2,2,2,3,3,3),
"V2" = c(9,9,9,0,0,2,2,2,0,0,3,0,0))
and I would like to create a bar plot out of it, where each value has a specific colour. With the great help of one of users we managed to create code
p <- df %>%
mutate(index = 1) %>%
pivot_longer(cols = -index) %>%
mutate(color = case_when(value == 9 ~ 'white',
value == 0 ~ 'darkgreen',
value == 1 ~ 'blue',
value == 2 ~ 'red',
value == 3 ~ 'darkorange')) %>%
ggplot(aes(x = index, y = name, fill = color))
geom_col(width = 0.3)
scale_fill_identity(guide = 'legend')
theme_classic()
scale_x_continuous(expand = c(0,0), breaks = pretty_breaks(2))
vec_colors <- df %>%
mutate(index = 1) %>%
pivot_longer(cols = -index) %>%
mutate(color = case_when(value == 9 ~ 'white',
value == 0 ~ 'darkgreen',
value == 1 ~ 'blue',
value == 2 ~ 'red',
value == 3 ~ 'darkorange')) %>%
arrange(name) %>%
pull(color)
q <- ggplot_build(p)
q$data[[1]] <- q$data[[1]] %>%
group_by(y) %>%
arrange(x, .by_group = TRUE)
q$data[[1]]$fill <- vec_colors
q <- ggplot_gtable(q)
plot(q)
Question: how do I create a legend that looks like this?
Or like this?
CodePudding user response:
Well, first your approach to achieve your desired result is quite complicated. Instead you could simplify using a named color vector and switching to scale_fill_manual
. Doing so will give you atomatically a legend similar to your desired result which I tweak a bit using the breaks
argument. Also, instead of geom_col
I would go for geom_tile
. To this end use the row number as the index
.
library(dplyr)
library(tidyr)
library(ggplot2)
df_long <- df %>%
mutate(index = row_number()) %>%
pivot_longer(cols = -index)
cols <- c( 'white', 'darkgreen', 'blue', 'red', 'darkorange')
names(cols) <- c(9, 0, 1, 2, 3)
ggplot(df_long, aes(x = index, y = name, fill = factor(value)))
geom_tile(height = .3)
scale_fill_manual(values = cols, limits = force, breaks = c(0, 3, 2), name = "State")
theme_classic()
scale_x_continuous(expand = c(0,0), breaks = scales::pretty_breaks(2))