Reputation: 51
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)
Upvotes: 0
Views: 499
Reputation: 24722
If you make a couple of changes:
team_color = c(1,5,2,6,3,7,4,8)
barplot(performance ~ teams, data = df,
col = sapply(team_color,choose_color))
Upvotes: 1
Reputation: 51
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)
Upvotes: 0