简体   繁体   English

如何在R plotly色标中强制将零映射为白色

[英]how to force map zero to white color in R plotly color scale

My code is the following but I would like to have white color mapped to 0 instead of the middle values of the max and min of data_bydate$avg_score我的代码如下,但我希望将白色映射到 0 而不是 data_bydate$avg_score 的最大值和最小值的中间值

g <- plot_ly(data_bydate, x = ~Date, y = ~avg_score, color =data_bydate$avg_score, colors = c("#FF0000","#FFFFFF", "#008000"), mode ='markers', marker = list(size=3)) %>%
layout(legend = list(orientation = 'h'), 
       xaxis = list(title = "",
                    zeroline = FALSE,
                    tickformat="%X",
                    showline = TRUE), 
       yaxis = list(title = "",
                    zeroline = FALSE,
                    showline = TRUE ))

You could create your own colorscale which goes from red (min) to white (zero) to greenish (max).您可以创建自己的colorscale ,从红色(最小)到白色(零)再到绿色(最大)。 The colorscale is a list of arrays which is composed of two separate colorscales, one for the part below zero, from red to white, and the other one above, from white to green. colorscale是一个数组列表,它由两个单独的色标组成,一个用于低于零的部分,从红色到白色,另一个用于高于零的部分,从白色到绿色。

在此处输入图片说明

library(plotly)
library(scales)

set.seed(42)
colorlength <- 100

data_bydate <- data.frame(Date = c(1:23),
                          avg_score = c(runif(10, -5, -1), 
                                        rep(0,3), 
                                        runif(10, 1, 10)
                                        )
                          )

null_value <- (0 - min(data_bydate$avg_score)) / (max(data_bydate$avg_score) - min(data_bydate$avg_score))        
border <- as.integer(null_value * colorlength)
colorscale <- as.list(1:colorlength)

#colorscale below zero
s <- scales::seq_gradient_pal("#FF0000", "#FFFFFF", "Lab")(seq(0,1,length.out=border))
for (i in 1:border) {
    colorscale[[i]] <- c((i - 1) / colorlength, s[i])
}

#colorscale above zero
s <- scales::seq_gradient_pal("#FFFFFF", "#008000", "Lab")(seq(0,1,length.out=colorlength - border))
for (i in 1:(colorlength - border)) {
  colorscale[[i + border]] <- c((i + border) / colorlength, s[i])
}

plot_ly(data_bydate, 
        x = ~Date, 
        y = ~avg_score, 
        type = 'scatter',
        mode ='markers', 
        marker = list(size = 10,
                      color = ~avg_score,
                      colorscale = colorscale,
                      colorbar = list(len=1))) %>%
  layout(plot_bgcolor = 'black')

A simple way is to set limits, here min is -2, max is 2, and 0 is in the middle.一个简单的方法是设置限制,这里min是-2,max是2,0在中间。

colorbar(title = "Change (%)", limits = c(-2, 2))

And choose a diverging palette like;并选择一个发散的调色板;

colorscale = "RdBu",
reversescale = TRUE,

The diverging palettes are : BrBG, PiYG, PRGn, PuOr, RdBu, RdGy, RdYlBu, RdYlGn, Spectral.发散的调色板是:BrBG、PiYG、PRGn、PuOr、RdBu、RdGy、RdYlBu、RdYlGn、Spectral。

Reversing the scale reverses the direction of the colorscale.反转比例会反转色阶的方向。

Just to add to Maximilian Peters' excellent answer, in some applications it may be desirable to have an asymmetric colour scale that reflects the asymmetry in the data.只是为了增加 Maximilian Peters 的出色答案,在某些应用程序中,可能需要一个不对称的色标来反映数据中的不对称性。 In the example in Maximilian's answer, this would mean that -4 would be of a shade of red comparable in brightness to the shade of green of value 4.在马克西米利安回答的示例中,这意味着 -4 的红色阴影与值 4 的绿色阴影的亮度相当。

This can be achieved as follows:这可以通过以下方式实现:

library(plotly)
library(scales)

set.seed(42)
colorlength <- 100

data_bydate <- data.frame(Date = c(1:23),
                          avg_score = c(runif(10, -5, -1), 
                                        rep(0,3), 
                                        runif(10, 1, 10)
                                        )
                          )

null_value <- (0 - min(data_bydate$avg_score)) / (max(data_bydate$avg_score) - min(data_bydate$avg_score))        
border <- as.integer(null_value * colorlength)
colorscale <- as.list(1:colorlength)


if (border < colorlength / 2) {
    ## colorscale below zero
    border_neg <- colorlength - border
    s <- scales::seq_gradient_pal("#FF0000", "#FFFFFF", "Lab")(seq(0,1,length.out=border_neg))
    for (i in 1:border) {
        colorscale[[i]] <- c((i - 1) / colorlength, s[i + border_neg - border - 1])
    }

    ## colorscale above zero
    border_pos <- border
    s <- scales::seq_gradient_pal("#FFFFFF", "#008000", "Lab")(seq(0,1,length.out=colorlength - border_pos))
    for (i in 1:(colorlength - border_pos)) {
        colorscale[[i + border_pos]] <- c((i + border) / colorlength, s[i])
    }
} else {
    ## colorscale below zero
    border_neg <- border
    s <- scales::seq_gradient_pal("#FF0000", "#FFFFFF", "Lab")(seq(0,1,length.out=border_neg))
    for (i in 1:border_neg) {
        colorscale[[i]] <- c((i - 1) / colorlength, s[i])
    }

    ## colorscale above zero
    border_pos <- colorlength - border
    s <- scales::seq_gradient_pal("#FFFFFF", "#008000", "Lab")(seq(0,1,length.out=border))
    for (i in 1:border_pos) {
        colorscale[[i + border]] <- c((i + border) / colorlength, s[i])
    }
}


plot_ly(data_bydate, 
        x = ~Date, 
        y = ~avg_score, 
        type = 'scatter',
        mode ='markers', 
        marker = list(size = 10,
                      color = ~avg_score,
                      colorscale = colorscale,
                      colorbar = list(len=1))) %>%
  layout(plot_bgcolor = 'black')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM