Search code examples
rplotlystacked-bar-chart

R plotly: Color textfont on condition


what I want to do is following: I am working with Plotly and I want to colour the textfont in white if the bar is not yellow (#FFF761) / if the animal isn't rabbit. If the bar is yellow / the animal is rabbit, I want the textfont to be black. I was able to achieve it in a normal barchart but it just doesn't work for a stacked barchart, so I am very lost.

Here is the example:

library(plotly)

Color1 <- "#EC4239"
Color2 <- "#FC954C"
Color3 <- "#FFF761"

rbind(
  c("red","#EC4239"),
  c("orange","#FC954C"),
  c("yellow","#FFF761")
) %>% as.data.frame() %>%
  dplyr::rename(colors3_name = V1,
                colors3_hex = V2) -> colors3

colors3$colors3_hex -> bar_colors

city <- rep(c("Berlin", "London"), each = 9)
year <- rep(rep(c(2010, 2011, 2012), each = 3), times = 2)
animal <- rep(c("cat", "dog", "rabbits"), times = 6)
amount <- c(14, 67, 73,
            43, 50, 56,
            21, 24, 28,
            44, 32, 32,
            73, 45, 56,
            60, 67, 58
            )

df <- as.data.frame(cbind(year, city, animal, amount))

schriftfarbe <- ifelse(bar_colors != "#FFF761", "#000000", "#ffffff")


fig <-
  plot_ly(df,
          y = ~amount,
          x = factor(df$city, levels = unique(df$city)),
          frame = ~year,
          color = ~animal,
          colors = ~bar_colors,
          type = 'bar',
          text=~df$amount,
          textposition = 'auto',
          textfont=list(color= schriftfarbe)
  ) %>%

  layout(barmode = 'stack',
         title = "<b>Test Plot (2010–2012)</b>",
         titlefont = list(size = 20),
         font = list(family = "calibri",size = 14),
         separators = ',',
         xaxis = list(title = list(text = "", standoff = 4),
                      zeroline = TRUE),
         yaxis = list(title = "Amount",
                      range= c(0,200)),
         legend = list(orientation = 'v'))

fig

Thank you very much in advance!


Solution

  • One option would be set text color via inline CSS, i.e. wrap your labels inside a span tag for which you set the color property according to your desired colors:

    library(plotly)
    
    df$schriftfarbe <- ifelse(df$animal == "rabbits", "#000000", "#ffffff")
    
    plot_ly(df,
      y = ~amount,
      x = factor(df$city, levels = unique(df$city)),
      frame = ~year,
      color = ~animal,
      colors = ~bar_colors,
      type = "bar",
      text = ~paste0("<span style='color: ", df$schriftfarbe, "'>", df$amount, "</span>"),
      textposition = "auto"
    ) %>%
      layout(
        barmode = "stack",
        title = list(text = "<b>Test Plot (2010–2012)</b>", font = list(size = 20)),
        font = list(family = "calibri", size = 14),
        separators = ",",
        xaxis = list(
          title = list(text = "", standoff = 4),
          zeroline = TRUE
        ),
        yaxis = list(
          title = "Amount",
          range = c(0, 200)
        ),
        legend = list(orientation = "v")
      )
    

    enter image description here