Elena
Elena

Reputation: 61

legend change the color specified for geom_bar

I have the following plot that includes data from two different data frames:

ggplot(one100, aes(x=hour, y=countPerHour)) +
  ylab("Times reached") +
  xlab("Hour of the day") +
  geom_bar( stat="identity",
            color="turquoise3", fill="turquoise2", alpha=0.3) +
  geom_bar( stat="identity", 
            aes(x=noventa99$hour, y=noventa99$countPerHour), 
            color="green3", fill="green3", alpha=0.3) +
  theme_bw()

initial plot

I added a legend with the code below, but at the moment I add it, I lost the original colors filling the bars of geom_bar().

ggplot(one100 ) +
  ylab("Times reached") +
  xlab("Hour of the day") +
  geom_bar( stat="identity",
            aes(x=one100$hour, y=one100$countPerHour, colour="100%"), 
            alpha=0.3) +
  geom_bar( stat="identity", 
        aes(x=noventa99$hour, y=noventa99$countPerHour, colour="80-99%"), 
        alpha=0.3) +
  theme_bw() +
  scale_colour_manual("Critical % Occupation", 
                      values=c("100%" = "turquoise2", "80-90%" = "green3"))

This is the result I get:

with lengend

one100 data frame is as follow, where "hour" is a factor

"hour"  "countPerHour"
"9"     30
"11"    24
 "8"    21
"10"    18
"13"    17
"12"    15
 "7"    15
"14"    14
 "5"    12
"17"    7
"15"    7
"16"    6
 "4"    6
 "6"    5
"21"    4
"20"    3
"19"    2
 "3"    2
 "2"    2
"23"    1
"22"    1
"18"    1
 "0"    1
 "1"    0

noventa99 contains the following data:

"hour"  "countPerHour"
 "1"    1
 "3"    2
 "4"    1
 "5"    3
 "6"    1
 "7"    6
 "8"    5
 "9"    7
"10"    6
"11"    3
"12"    4
"13"    4
"14"    5
"15"    4
"16"    3
"17"    2
"18"    1
"19"    1
"21"    1
"22"    1
"23"    1
"20"    0
 "2"    0
 "0"    0

How can I keep the original colors I specified filling up the bars?

Upvotes: 1

Views: 2664

Answers (1)

alistaire
alistaire

Reputation: 43334

The problem is simply because you're passing values to color, which controls the outline of bars, not fill. That said, the best way to generate legends is to combine the data so you can map variables to those aesthetics, not hard-coded values:

library(ggplot2)

one100 <- data.frame(hour = c(9L, 11L, 8L, 10L, 13L, 12L, 7L, 14L, 5L, 17L, 15L, 16L, 4L, 6L, 21L, 20L, 19L, 3L, 2L, 23L, 22L, 18L, 0L, 1L), 
                     countPerHour = c(30L, 24L, 21L, 18L, 17L, 15L, 15L, 14L, 12L, 7L, 7L, 6L, 6L, 5L, 4L, 3L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 0L))
noventa99 <- data.frame(hour = c(1L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 21L, 22L, 23L, 20L, 2L, 0L), 
                        countPerHour = c(1L, 2L, 1L, 3L, 1L, 6L, 5L, 7L, 6L, 3L, 4L, 4L, 5L, 4L, 3L, 2L, 1L, 1L, 1L, 1L, 1L, 0L, 0L, 0L))

# rbind and add ID column for which data frame it came from
combined_data <- dplyr::bind_rows(`100%` = one100, `80-90%` = noventa99, .id = "critical")

str(combined_data)
#> 'data.frame':    48 obs. of  3 variables:
#>  $ critical    : chr  "100%" "100%" "100%" "100%" ...
#>  $ hour        : int  9 11 8 10 13 12 7 14 5 17 ...
#>  $ countPerHour: int  30 24 21 18 17 15 15 14 12 7 ...

# set aes once with fill and color, without `$` subsetting
ggplot(combined_data, aes(hour, countPerHour, fill = critical, color = critical)) + 
    geom_col(alpha = 0.3) +    # geom_col is short for `geom_bar(stat = "identity)
    # set scale for fill and color aesthetics
    scale_fill_manual("Critical % Occupation", values = c("100%" = "turquoise2", "80-90%" = "green3")) + 
    scale_color_manual("Critical % Occupation", values = c("100%" = "turquoise2", "80-90%" = "green3")) + 
    labs(x = "Hour of the day", y = "Times reached") +    # set multiple labels at once
    hrbrthemes::theme_ipsum_rc()    # pretty theme

barplot with correct fill colors

Upvotes: 3

Related Questions