0

I'm trying to make a heatmap in plotly with a binned colorbar with assigned colors to represent a categorical variable in my data.

I assigned the categories to numbers to make it continous for the heatmap, and then I thought I could use tickvals to label the numbers as their categorical variable. I'm close but the color scale I've created doesn't seem to work as an array. I want the colorbar in the legend to be the 5 discrete colors in colors_df. I've looked at some other examples in stackoverflow but I can't see why mine isn't working based on the code in the solutions of those posts (for example).

colors_df <- structure(list(
    c(0.99, 1.99, 1.99, 2.99, 2.99, 3.99, 3.99, 4.99, 4.99, 5.99), 
    c("#65B32E", "#65B32E", "#7CBDC4", "#7CBDC4", "#C0D236", "#C0D236", "#3E5B84", "#3E5B84", "#008C75", "#008C75")), 
    class = "data.frame", 
    row.names = c(NA, 10L))
values <- letters[1:5]
df <- data.frame(a = LETTERS[1:5], b = month.abb[1:5]) %>%
    complete(a,b) %>%
    mutate(c = sample(values, 25, replace = T)) %>%
    mutate(continuousc = as.numeric(factor(c, levels = values, labels = 1:length(values))))

plot_ly(
    data = df,
    x = ~b,
    y = ~a,
    z = ~continuousc,
    ygap = 2,
    xgap = 2,
    type = "heatmap",
    colorscale=colors_df,
    colorbar = list(
        tickmode="array",
        tickvals=1:5, 
        ticktext=values, 
        len=0.5))

UPDATE

I figured out a solution that works, though I can't figure out how to assign a color to null values (if possible) - any recommendations?


library(tidyverse)
library(plotly)
library(RColorBrewer)

n_values <- 7
values <- c(letters[1:n_values], NA)
scale_step <- 1/n_values
cols <- brewer.pal(n_values, "RdYlBu")
# scales::show_col(cols)

df <- data.frame(a = LETTERS[1:n_values], b = month.abb[1:n_values]) %>%
  complete(a,b) %>%
  mutate(c = sample(values, n_values * n_values, replace = T)) %>%
  mutate(continuousc = as.numeric(factor(c, levels = values, labels = 1:n_values)))


cdf <- structure(list(
  sort(c(seq(0, 1, scale_step), seq(scale_step, 1-scale_step, scale_step))),
  rep(cols, each=2)),
  row.names = c(NA,-n_values*2L), class = "data.frame")

tickvalues <- seq(1 +(n_values-1)/n_values/2, n_values - (n_values-1)/n_values/2, (n_values-1)/n_values/2)
tickvalues <- tickvalues[seq(1, length(tickvalues), 2)]

plot_ly(data = df,
        x = ~b,
        y = ~a,
        z = ~continuousc,
        customdata = ~c,
        ygap = 2,
        xgap = 2,
        type = "heatmap",
        colorscale=cdf,
        hovertemplate=paste(
          '<b>a</b>: %{y}',
          '<br><b>b</b>: %{x}',
          '<br><b>c</b>: %{customdata}<extra></extra>'),
        colorbar = list(
          tickmode="array",
          tickvals=tickvalues,
          ticktext=values, 
          len=0.5))


0 Answers0