2016-11-10 5 views
3

Я пытаюсь распечатать сетку тепловых карт, используя сюжет для R в Shiny. Я хочу дать им пользовательскую цветовую гамму, но она не ведет себя так, как я этого хочу. Когда я использую опцию colors = при создании моей графической диаграммы, она, похоже, использует распределение значений, а не zmin и zmax, которые я дал ей, чтобы назначать цвета.Цвета ярких цветов не работают в заговоре

В приведенном ниже примере кода вы можете увидеть, что я даю каждому сюжету такую ​​же цветовую шкалу (colorScale), используя параметр colors =. Это работает, как я ожидаю, когда у меня есть хорошо распределенный набор данных, как в первой, второй и четвертой строках.

Однако в третьем ряду, где участки имеют очень искаженные данные, вы можете видеть, что весы выглядят иначе, чем все остальное - они имеют синий и красный цвет, но пропускают белый в середине, вместо этого имеют фиолетовый ,

В моем фактическом коде это вызывает большую проблему для диаграммы, которая имеет множество значений по середине, с некоторыми крайностями на обоих концах. Я хочу, чтобы эти значения в середине выглядели белыми, чтобы показать, что там не было никаких изменений, но вместо этого они фиолетовые, что затрудняет выбор важных значений (экстремальных).

Есть ли способ заставить назначение цвета вести себя так, как я хочу?

Спасибо, Клифф

server.R

if (!require("pacman")) install.packages("pacman") 

pacman::p_load(shiny,data.table,plotly) 


colorScale <- colorRamp(c("darkblue","cornflowerblue","white","sandybrown","firebrick")) 

nCodeNames <- c("a","b","c","d","e","f","g","h","i","j","k","l") 
means = c(rnorm(600,0,2.5),runif(600,-5,5),runif(130,-4,-3.9),runif(70,4.5,5),rnorm(150,-3),rnorm(50,4),rnorm(180,-2.5),runif(20,4.93,4.98),runif(300,-4,3),rnorm(300,3.5)) 



dt <- data.table(age=rep(rep(c(11:20),times=20),times=12),composite=rep(rep(c(81:100),each=10),times=12),mean=means,n_code=rep(nCodeNames,each=200)) 

sub<-dt[n_code=="a"] 

shinyServer(function(input, output) { 

for(Ncode in nCodeNames){ 
    local({ 
    ncode = Ncode 
    output[[paste0("grid",ncode)]] <- renderPlotly({ 
     sub <- dt[n_code == ncode] 
     p <- plot_ly(data=sub, x=~age, y=~composite, z=~mean, type="heatmap", zmin=-5,zmax=5, 
        colors = colorScale, colorbar=list(thickness="15"))%>% 
      layout(title=ncode,xaxis=list(type="category",tickvals=c(11,15,20)),yaxis=list(title="",ticks="")) 
    }) 
    }) 
} 
}) 

ui.R

if (!require("pacman")) install.packages("pacman") 

pacman::p_load(shiny, plotly) 

nCodeNames <- c("a","b","c","d","e","f","g","h","i","j","k","l") 


shinyUI(navbarPage(
    "E-N Matrics: Proportion of E-Code Resulting in each N-Code", 

    tabPanel("Grid", 

      lapply(c(1:4), function(i) fluidRow(
       lapply(c(1:3), function(j) column(4, plotlyOutput(paste0("grid",nCodeNames[(i-1)*3+j])))) 
      )) 

      #fluidRow(column(4,plotlyOutput(paste0("grid",nCodeNames[(1-1)*3+1]))),column(4,plotly)) 
) 
)) 

ответ

3

я столкнулся с подобными проблемами с colorscale в R plotly Heatmap. Когда данные для аргумента z прикрутили дистрибутив, только сюжетные значения, указанные в цветовой шкале, используются по графику.

Я нашел решение для работы, создав новую переменную в соответствии с квантилями исходной переменной и передав ее аргументу z. Вот код R для общей идеи. Вам нужно будет настроить его, чтобы он работал для конкретной проблемы.

library(plotly) 
library(RColorBrewer) 

# create a dataframe where z has a skewed distribution 
set.seed(1) 
df = data.frame(x = rep(1:50, 20) , y = rep(1:20,each =50), z = rgamma(1000, 2, 0.5)) 

# check distribution of z 
plot_ly(data = df, x = ~z, type = "histogram")%>% 
    layout(title = "histogram of z") 

# original heatmap 
# pass the column z with screwed distribution to z argument 
plot_ly(data=df, x=~x, y=~y, z=~z, type="heatmap", 
     colors = "Spectral") %>% 
    layout(title = "original heatmap") 

# some data processing work 

# find unique quantiles of z 
quantiles = unique(quantile(df$z, seq(0,1,0.1))) 

# create a dummy column z1 of discrete values using the quantiles as cut off 
# the ideas is to arrage the data to subgroups of roughly the same size 
df$z1= cut(df$z, breaks = c(quantiles[1]-1,quantiles[-1]), right = TRUE, labels = FALSE) 

# check distribution of z1 
plot_ly(data = df, x = ~z1, type = "histogram")%>% 
    layout(title = "histogram of z1") 


# new heatmap 
# passes the new column z1 to z argument 
plot_ly(data=df, x=~x, y=~y, z=~z1, type="heatmap", 
     # make sure hovering over displays original z 
     text =~z, hoverinfo = "text", 
     # use the color palettes from RColorBrewer, 
     # or your customized colorscale 
     colors = "Spectral", 
     # map the label of the colorbar back to the quantiles 
     colorbar=list(tickmode="array", tickvals = 1:(length(quantiles)-1), ticktext = round(quantiles,2)[-1], title = "z")) %>% 
layout(title = "new heat map") 

Ниже приведены оригинальные карты тепла и новая карта отопления, созданная по сюжету. Новая тепловая карта использует больше цветов из палитры «Спектр», чтобы различать меньшие значения.

enter image description here

Надеется, что это помогает!


Обновление апреля 3,2017

Я открыл запрос на R plotly хранилище для возможности трансформировать цветовую гамму.

https://github.com/ropensci/plotly/issues/920