簡體   English   中英

修復色標損壞

[英]fix plotly color scale breaks

我已經使用plotly的R接口創建了一個熱圖,如下所示:

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')

產生這個:

熱圖

有什么辦法可以解決色標的問題嗎? 我希望色標的中點為20%,任何超過50%的值在色標的末尾用紅色進行着色。

好吧,通常認為熱圖的顏色會隨元素的值而變化,但是您可以根據所需條件將每個元素分為5組中的1組,並相應地分配5種顏色。 然后,該分組將傳遞到z中。 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 )。 這並不一定將色標的中心設置為.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')

最后一種方法是使用自定義色標。 我發現這很難以righ格式獲取colorscale參數。 可能有更好的方法來執行此操作,但是我無法提出任何優雅的方法。

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')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM