'applying custom color function to plots in R

I'm trying to apply a custom color function to barplots that take in a dataframe. Teams are associated with a color, and depending on the year from which the data is taken, team colors will have a different opacity. So in 2000, the red team would have full opacity, and in 2020, it would have 50% opacity (but the same base color). I've tried passing in rgb formats and hashed values (#FF0011) all to no avail. This was from a shiny app, but I created a reprex to highlight the issue. Thanks in advance.

# team performances in year 2000 and 2020
teams <- c('A2000', 'B2000', 'C2000', 'D2000', 'A2020', 'B2020', 'C2020', 'D2020')
performance  <- c(10, 3, 5, 4, 7, 8, 9, 2)
team_color <- c(1, 2, 3, 4, 5, 6, 7, 8)
df <- data.frame(teams, performance, team_color) 

base_colors <- c("darkgoldenrod2", "darkblue", "darkred","darkcyan")

lighten_color <- function(color_name, opacity = 50, newname = NULL) {
  rgb.val <- col2rgb(color_name)   ## Get RGB values for named color

  # Make new color using input color as base and alpha set by transparency
  lighter_color <- rgb(rgb.val[1], rgb.val[2], rgb.val[3],
                       max = 255,
                       alpha = opacity * 255 / 100,
                       names = newname)
  return(lighter_color) # not clear if I need to "unlist"
}

# Function so that "reds" will be associated with one team, "blues" with another, ...
choose_color <- function(color_num) {
  if (color_num < 5) { # If from the first year (numbers 1-4) will use a base color as is.
    named_color <- base_colors[color_num]
    rgb_color <- col2rgb(named_color)
    hash_color <- rgb(rgb_color[1,1], rgb_color[2,1], rgb_color[3,1], max=255, alpha = 255, names = '')
  }
  else { # Otherwise, you compute the base color by subtracting 4 and alter opacity
    team_base_color <- color_num - 4
    perf_color <- base_colors[team_base_color]
    hash_color <- lighten_color(perf_color, opacity = 50)
  }
  return(unlist(hash_color))
}

# fails (all bars in red) if I try to apply the function to the barplot
barplot(performance ~ teams, data = df, 
        col = choose_color(team_color)) 
       # also tried col = lapply(team_color, choose_color)


Solution 1:[1]

If you make a couple of changes:

  1. team_color should be adjusted
team_color = c(1,5,2,6,3,7,4,8)
  1. use sapply to feed the team colors one by one to your function
barplot(performance ~ teams, data = df, 
        col = sapply(team_color,choose_color)) 

team_colors

Solution 2:[2]

I have discovered that one possibility would be to convert all the assigned colors to their hex equivalents and place those values in the dataframe. Then you can simply assign color to the color value given in the dataframe. It's an OK workaround, though I would have liked to know why the first one didn't work.

# team performances in year 2000 and 2020

base_colors <- c("darkgoldenrod2", "darkblue", "darkred","darkcyan")

teams <- c('A2000', 'B2000', 'C2000', 'D2000')
performance  <- c(10, 3, 5, 4)
team_color <- c('#AA2233FF', '#BB000033', '#CC00AA33', '#DD0000FF')
df <- data.frame(teams, performance, team_color) 

barplot(performance ~ teams, data = df, 
        col = team_color)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 langtang
Solution 2 wdchild