rbokeh icon indicating copy to clipboard operation
rbokeh copied to clipboard

Add heatmap layer

Open MySchizoBuddy opened this issue 9 years ago • 12 comments

Bokeh already allows heatmaps. Can you add a heatmap layer to rBokeh as well. For an example of existing interactive heatmap check out the d3heatmap R package. The dendrograms are not needed

MySchizoBuddy avatar Jun 30 '15 09:06 MySchizoBuddy

Sounds good. This should be a very simply layer function making use of ly_image or ly_crect.

hafen avatar Jul 06 '15 16:07 hafen

Bokeh has a build in heatmap function. http://bokeh.pydata.org/en/latest/docs/gallery/cat_heatmap_chart.html

MySchizoBuddy avatar Jul 06 '15 18:07 MySchizoBuddy

+1 This would be helpful for gene expression data.

kaneplusplus avatar Jan 08 '16 17:01 kaneplusplus

was this feature released in the current comments. The current heatmap documentation is http://bokeh.pydata.org/en/latest/docs/gallery/heatmap_chart.html

ziyadsaeed avatar Jan 08 '16 18:01 ziyadsaeed

Thanks for the link @ziyadsaeed. That is part of the high-level python api so we will still need to implement our own that translates to the rect glyphs. Should be pretty straightforward. I'll give this issue precedence.

hafen avatar Jan 09 '16 08:01 hafen

I see histogram related commits in the log. So is this feature implemented?

ziyadsaeed avatar Jan 28 '16 19:01 ziyadsaeed

No sorry I'll get on it - should be pretty straightforward. @jrounds, did you have an implementation we could base off of?

hafen avatar Jan 29 '16 08:01 hafen

Honestly I am not sure. I would need to figure out

  • how to handle arguments properly
  • how to generalize a color gradient in an rbokeh way
  • how to draw a color legend properly

I do have this snippet that demos how to use rbokeh to make heatmaps "by-hand" and it has the elements in place:

ly_heatMap = function(fig, x, y, heat_color_var, data,title){
        data = as.data.frame(data)
        #color
        colorQuantileFn = pnorm; 
        colorQuantileFn = ecdf(data[[heat_color_var]])
        fill_alpha=.8; width=.99; height=.99;  NA.color ="#333333"
        colorFn = colorRamp(c("blue", "white", "red"))
        colMapFn = function(v) {
                col = colorFn(colorQuantileFn(v))
                col[is.nan(v)] = 33  
                col[is.na(v)] = 33
                rgb(col, maxColorValue=255)
            }   
        color = colMapFn(data[[heat_color_var]])
        r = quantile(data[[heat_color_var]], c(0,10)/10, na.rm=TRUE)
        ld = list()
        ld$legend_values = seq(r[1],r[2], length.out=20)
        ld$width = unique(round(diff(ld$legend_values), 5))
        ld$legend_colors = colMapFn(ld$legend_values)
        ld$y = 1
        legend_data = as.data.frame(ld)
        #bquote({legend_data = .(legend_data)})
        legend = figure(height=150, width=800,tools=NULL, xlab="", ygrid=FALSE, xgrid=FALSE,xaxes="below", yaxes=FALSE , xlim=r) %>% ly_crect(x=legend_values,y=y, data=legend_data,color=legend_colors,width=width, line_alpha=0,fill_alpha=fill_alpha)

        hover_data = data
        hover_data = subset(hover_data, select=setdiff(colnames(hover_data), c("color")))

        p = fig %>% ly_crect( x=x, y=y, .99, .99, data=data, fill_color=color, line_color=color, fill_alpha=fill_alpha,hover=hover_data, legend=TRUE)
        p = p %>% theme_axis("x", major_label_orientation = 90)

        plots = list()
        plots[[title]] = p
        plots[["Legend"]] = legend
        p =  grid_plot(plots, nrow=2, ncol=1)
        p
}

library(reshape2)
mtscaled = as.matrix(scale(mtcars))
data =  melt(mtscaled, c("Model", "Measure"))
data[1:3,"value"] = as.numeric(NA)
call = list()
call$fig = figure()
call$data = data 
call$heat_color_var = heat_color_var = "value"
call$x= "Measure"
call$y = "Model"
call$title = "Car Model Heatmap"
do.call(ly_heatMap,call)

jrounds avatar Jan 30 '16 19:01 jrounds

Any updates on this? I'm moving from trelliscope to trelliscopejs, and exploring rbokeh as an alternative to ggplot2. An elegant way to do heatmaps would be really nice.

colinbrislawn avatar Jun 28 '17 19:06 colinbrislawn

I do plan to support this. I'm working on a complete overhaul of the internals of rbokeh right now that will clear things up a lot for easier future development. This should be out in 4-6 weeks. I'd prefer to add this to the updated version and think I (or a contributor) could do it pretty soon after that is released.

hafen avatar Jun 28 '17 21:06 hafen

I'm glad to hear there is an update planned! Thank you for developing this constellation of software.

EDIT: Well this works surprisingly well.

df %>%
  figure(xgrid = FALSE, ygrid = FALSE, xlim = c(.5, 5.5), ylim = c(.5, 4.5)) %>%
    ly_crect(x, y, hover = value, color = value)

colinbrislawn avatar Jun 28 '17 22:06 colinbrislawn

Wow, thanks for the tip, past Colin!

Here's how I'm going it today (for 2021 Colin).

df %>%
  figure(xgrid = FALSE, ygrid = FALSE, legend_location = NULL,
    width = 96*8, height = 96*7, toolbar_location = NULL) %>%
  ly_crect(x, y, hover = value, color = value) %>%
  theme_axis("x", major_label_orientation = 30) %>%
  x_range(c("a", "b", "c"))

colinbrislawn avatar Oct 22 '19 18:10 colinbrislawn