I have integer data that I want to plot using R's plotly as a heatmap with the elements of the heatmap color coded by the size of the integer data. I also want to annotate each element by a text annotation of the integer and also color code that text by the size of the integer data.
Here's the data:
library(dplyr)
pal <- grDevices::colorRamp(c("black","gray"))
set.seed(1)
df <- rbind(data.frame(col = "a",
group = paste0("g",1:20),
n = as.integer(runif(20, 1, 20))) %>%
dplyr::mutate(text.col = rgb(pal((n - min(n))/diff(range(n))),max=255)),
data.frame(col = "b",
group = paste0("g",1:20),
n = as.integer(runif(20, 1, 40))) %>%
dplyr::mutate(text.col = rgb(pal((n - min(n))/diff(range(n))),max=255)))
df$group <- factor(df$group, levels = paste0("g",1:20))
So my heatmap will have 20 rows corresponding to df$group and 2 columns corresponding to df$col. As you can see I'm specifying the color of each element in df.
Here's a data.frame specifying the color range of the heatmap's background color, for each df$col:
colors.df <- data.frame(col = c("a", "b"),
fill.low = c("#a6c4ba", "#f2edda"),
fill.high = c("#4e8a75", "#b49823"),
stringsAsFactors = F)
And here's my plotly code:
lapply(c("a","b"), function(l){
col.df <- dplyr::filter(df, col == l)
n.text <- as.character(col.df$n)
plotly::plot_ly(ygap = 1, z = col.df$n, x = col.df$col, y =col.df$group,
colors = grDevices::colorRamp(c(dplyr::filter(colors.df,col == l)$fill.low, dplyr::filter(colors.df,col == l)$fill.high)), type = "heatmap") %>%
plotly::hide_colorbar() %>%
plotly::add_annotations(font = list(color = col.df$text.col, size = 8),text = n.text,x = col.df$col,y = col.df$group,showarrow = F)
}) %>% plotly::subplot(shareX = T, shareY = T, nrows = 1, margin = 0.001, widths = c(0.5, 0.5))
As you can see passing col.df$text.col to the font list in plotly::add_annotations is not obeyed and all text annotations are color with the same color.
Any idea how to get them colored according to col.df$text.col?



