2016-09-24 48 views
0

我一直在使用plotly的R口创建一个热图,像这样:修复plotly颜色规模突破

df <- data.frame(date = rep(seq(ymd('2016-09-01'), ymd('2016-09-10'), by='day'), each=2), 
       period = rep(c('lunch', 'dinner'), times=10), 
       diff=rnorm(20)) 

df %>% 
    plot_ly(x = date, 
      y = period, 
      z = abs(diff), 
      type = "heatmap", 
      hoverinfo='none', 
      colors = rev(RColorBrewer::brewer.pal(5, "RdYlGn")), 
      showscale = F) %>% 
    add_trace(x = date, 
      y = period, 
      text = paste0(round(diff*100), '%'), 
      mode='text', 
      hoverinfo='none') 

产生这样的:

heatmap

有没有什么办法可以解决这个休息的色阶?我希望色标的中点为20%,任何超过50%的值在刻度的末尾用红色标出。

回答

2

好吧,热图通常应该具有随元素值而变化的颜色,但您可以根据所需的任何标准将每个元素强制为5个组中的1个,并相应地分配5种颜色。然后,该分组将被传递给z。 ž应该是一个数,虽然,不是一个因素,这样你就可以在分组转换为整数:

# create 5 levels or groups for the diff variable 
# choose breaks as desired 
diffLevel <- cut(abs(df$diff), 
       breaks = c(0, 0.0625, .125, .3, .5, Inf)) 

df %>% 
    plot_ly(x = date, 
      y = period, 
      z = as.integer(diffLevel), 
      type = "heatmap", 
      hoverinfo='none', 
      colors = rev(RColorBrewer::brewer.pal(5, "RdYlGn")), 
      showscale = F) %>% 
    add_trace(x = date, 
      y = period, 
      text = paste0(round(diff*100), '%'), 
      mode='text', 
      hoverinfo='none') 

另一种方法是将zmax值设定为0.5(和zauto = FALSE)。这不一定会将色阶的中心设置为0.2,但它的工作原理相当不错,并且建立了0.5的截止点,高于这个截止点是红色的。它也可以让你在abs(diff)直接传递:

df %>% 
    plot_ly(x = date, 
      y = period, 
      z = abs(diff), 
      zauto = FALSE, # set this to FALSE! 
      zmax = 0.5,    
      type = "heatmap", 
      hoverinfo='none', 
      colors = rev(RColorBrewer::brewer.pal(5, "RdYlGn")), 
      showscale = F) %>% 
    add_trace(x = date, 
      y = period, 
      text = paste0(round(diff*100), '%'), 
      mode='text', 
      hoverinfo='none') 

最后一个方法是使用自定义colorscale工作。我发现这很难得到righ格式的色彩参数。可能有更好的方法来做到这一点,但我无法想出任何优雅的东西。

customPalette <- colorRampPalette(c("red", "yellow", "green"))(61) 
# I put 30 values between 0 and .2 and and 30 between .2 and 1. 
# And so, my palette has 61 colors 
customColors <- setNames(
    data.frame(breaks = c(seq(0, .2, length.out = 31), seq(.21, 1, length.out = 30)), 
      colors = as.character(
       apply(col2rgb(rev(customPalette)), 2, function(ii) 
       paste("rgb(", paste(ii, collapse = ","),")", sep = ""))), 
      stringsAsFactors = FALSE), 
    NULL) 
# not perfect, but it seems to work decently 

# initialize a list 
colList <- list() 
colList[[dim(customColors)[1]]] <- 0 

# format custom color list 
for(i in seq_len(dim(customColors)[1])) { 
    colList[[i]] <- c(customColors[i, 1], customColors[i, 2]) 
} 

# set zmax = 0.5 and zauto = FALSE 
df %>% 
    plot_ly(x = date, 
      y = period, 
      z = abs(diff), 
      zauto = FALSE, 
      zmax = 0.5, 
      type = "heatmap", 
      hoverinfo='none', 
      colorscale = colList, 
      showscale = F) %>% 
    add_trace(x = date, 
      y = period, 
      text = paste0(round(diff*100), '%'), 
      mode='text', 
      hoverinfo='none')