Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

Right now it doesn't give a graph where the above zero values are green and below zero values are red...

like image 545
user7891984 Avatar asked Oct 12 '25 14:10

user7891984


1 Answers

You could create your own colorscale which goes from red (min) to white (zero) to greenish (max). 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.

enter image description here

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')
like image 132
Maximilian Peters Avatar answered Oct 14 '25 07:10

Maximilian Peters



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!