Search code examples
rhighchartsplotlyheatmapr-highcharter

Is it possible to have different colormaps in a highchart heatmap? Or to gray out some of the items?


I want to create a heatmap with two different kind of values. For the sake of some example, let's imagine, I have a number of animals "a1", "a2" and "a3" and a set of body-part-lenghts, let's say a scientist measured the length of the "left arm", "right arm", "left leg" and "right leg".

Now lets imagine that the arm measurements of "a2" and "a3" were taken by an intern and we want to make clear that this measurement is distinct (e.g. not as reliable) from the others.

One way I could think of is graying out these two measurements a bit? The color should still be the same, just not as strong. Also great would be to simply use another color scale.

As a bonus question, let's say the left leg of a1 was forgotten, is there a good way to make this element completely gray then?

I use R as my programming language. I preferably use highcharter as the library, but also plotly would be OK for me to use.

Here is some code that should make it possible to play around a bit:

library(highcharter)

mat <- matrix(data=rnorm(4*3, 1,.2), nrow = 4)
rownames(mat) <- c("left arm", "right arm", "left leg", "right leg")
colnames(mat) <- c("a1", "a2", "a3")

hchart(mat, type="heatmap")

mat["left leg", "a1"] <- NA

unreliable_info_mat <- matrix(FALSE, nrow = 4, ncol = 3)
rownames(unreliable_info_mat) <- c("left arm", "right arm", "left leg", "right leg")
colnames(unreliable_info_mat) <- c("a1", "a2", "a3")
unreliable_info_mat[c("left arm", "right arm"), c("a2", "a3")] <- TRUE
unreliable_info_mat

this is not yet grayed out but already a heatmap


Solution

  • Here's an option to have more than one colorAxis in the chart. Basically, you denote which observations are "unreliable" and split up the dataframe into two. Add each individual series to the plot and then we can set up two different colorAxis in hc_colorAxis.

    You'll notice the second series has colorAxis = 1. This technically means the second colorAxis since the default is colorAxis = 0.

    Let me know if you have any questions. Hopefully this is inline with what you're trying to achieve.

    library(highcharter)
    
    # assumes stringsAsFactors = T
    set.seed(101)
    mat <- data.frame(values=round(rnorm(4*3, 1,.2),2),
                      limbs = rep(c("left arm", "right arm", "left leg", "right leg"), 3),
                      animals = rep(c("a1", "a2", "a3"), 4),
                      reliable = as.factor(sample(c(T,F), 12, replace = T)))
    
    mat[1,1] = NA
    
    split_df = split(mat, mat$reliable)
    names(split_df) = c("unreliable", "reliable")
    
    highchart(type = "chart") %>%
      hc_xAxis(type = "category", categories = levels(mat$animals), reversed = TRUE) %>%
      hc_yAxis(categories = levels(mat$limbs)) %>%
      hc_add_series(split_df$unreliable, hcaes(x = animals, y = limbs, value = values), type = 'heatmap', 
                    showInLegend = T, name = "Unreliable", dataLabels = list(enabled = T)) %>%
      hc_add_series(split_df$reliable, hcaes(x = animals, y = limbs, value = values), type = 'heatmap', 
                    colorAxis = 1, showInLegend = T, name = "Reliable",dataLabels = list(enabled = T), nullColor = "grey") %>%
      hc_colorAxis(
        list(minColor = "grey", maxColor = "grey"),
        list(minColor ="powderblue", maxColor = "cornflowerblue")
      ) %>%
      hc_tooltip(formatter = JS("function() { return '<b>' + this.series.name + '</b><br>' + this.point.xf + ' ~ ' + 
                                 this.point.yf + '<br> Value: ' + this.point.value }")) %>%
      hc_colors(c("grey","cornflowerblue")) # to update legend icon colors
    

    animation