[英]how to force map zero to white color in R plotly color scale
我的代碼如下,但我希望將白色映射到 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 ))
您可以創建自己的colorscale
,從紅色(最小)到白色(零)再到綠色(最大)。 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')
一個簡單的方法是設置限制,這里min是-2,max是2,0在中間。
colorbar(title = "Change (%)", limits = c(-2, 2))
並選擇一個發散的調色板;
colorscale = "RdBu",
reversescale = TRUE,
發散的調色板是:BrBG、PiYG、PRGn、PuOr、RdBu、RdGy、RdYlBu、RdYlGn、Spectral。
反轉比例會反轉色階的方向。
只是為了增加 Maximilian Peters 的出色答案,在某些應用程序中,可能需要一個不對稱的色標來反映數據中的不對稱性。 在馬克西米利安回答的示例中,這意味着 -4 的紅色陰影與值 4 的綠色陰影的亮度相當。
這可以通過以下方式實現:
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.