Как сделать так, чтобы линейки погрешностей на графике следовали шкале цветов?

Позвольте мне начать с того, что я пробовал методы, описанные в Цветовое кодирование полосы ошибок на графике разброса, но мне не удалось заставить их работать. Из того, что я могу сказать, были изменения в том, как обрабатываются колораксы в plotly версии 4, что может быть причиной того, что это больше не решает проблему.

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

set.seed(1)
x.data <- rnorm(20, 0, 1)
y.data <- rnorm(20, 2, 1)
x.err <- runif(20, 0.2, 0.8)
y.err <- runif(20, 0.2, 0.8)
z.data <- runif(20, 1.7, 2.8)

p <- plot_ly() %>%
  add_markers(x=x.data, y=y.data,
              error_x=list(array=x.err, color=z.data),
              error_y=list(array=y.err, color=z.data),
              marker=list(color=z.data, colorscale='Viridis',
                          colorbar=list(title='Z', limits=range(z.data)))) %>%
  layout(xaxis=list(title='X'), yaxis=list(title='Y'))

введите описание изображения здесь

z.norm <- (z.data - min(z.data))/(max(z.data)-min(z.data))
mycramp<-colorRamp(c("darkblue","yellow"))
mycolors<-rgb(mycramp(z.norm), maxColorValue = 255)

p <- plot_ly() %>%
  add_markers(x=x.data, y=y.data,
              error_x=list(array=x.err, color=mycolors),
              error_y=list(array=y.err, color=mycolors),
              marker=list(color=mycolors,
                          colorbar=list(title='Z', limits=range(z.data)))) %>%
  layout(xaxis=list(title='X'), yaxis=list(title='Y'))

Плохие цветные полосы


person Ben    schedule 30.10.2019    source источник


Ответы (3)


Документации по r plotly может немного не хватать. Я думаю, что это то, что вы ищете. Вы хотите использовать аргумент name. Оба color и name должны быть включены. Мы должны определить уровни аргумента name вручную. Мы также можем установить color на коэффициент, но тогда мы потеряем цветовую шкалу. colors давайте изменим цветовую палитру, используя RColorBrewer палитры.

plot_ly() %>%
  add_markers(x = x.data, 
              y = y.data, 
              showlegend = F, # must hide legend here or it shows up twice
              name = factor(z.data, levels = z.data, labels = z.data), # this is missing
              color = z.data, 
              colors = "Set1", 
              error_x = list(array = x.err),
              error_y = list(array = y.err))

введите описание изображения здесь

person hmhensen    schedule 11.11.2019
comment
Отлично, спасибо. Не могли бы вы помочь мне изменить цветовую шкалу? По умолчанию используется Viridis, если я попробую что-то еще в приведенном выше коде, он останется Viridis. - person Ben; 12.11.2019
comment
Ах, подожди! Что-то не так - шкалы ошибок теперь зашифрованы, я заметил в результатах, которые строил. Вы можете ясно увидеть это в примере здесь, в точке в правом нижнем углу. Сравните полосы погрешностей на вашем графике с моими. - person Ben; 12.11.2019
comment
@ Бен Хорошо, мы идем. Я добавил возможность изменить цветовую гамму. Также исправлено перепутывание полос ошибок. Это произошло потому, что имя и цвет преобразовывают вектор в множитель, а когда это происходит, он перемещает значения. Нам нужно создать фактор вручную и установить метки. Со мной случилась одна странная вещь: plotly не распознал цветовую схему Виридис. Я думаю, это потому, что plotly использует RColorBrewer, но когда я вынул colors, по умолчанию используется Viridis. В любом случае, вы всегда можете вручную вызвать любую цветовую схему с цветовыми пакетами. - person hmhensen; 12.11.2019

Мне пришлось установить последние dev-версии ggplot2 и plotly, чтобы заставить это работать (не уверен, какая из них сработала, я просто установил обе из исходников). Но после этого решение кажется довольно простым.

#get the latest ggplot2 and plotly from github
# devtools::install_github("tidyverse/ggplot2")
# devtools::install_github("ropensci/plotly")

#first, create a static ggplot2 charts    
p1 <- 
  ggplot( df, aes( x = x.data, y = y.data, color = z.data ) ) +
  #plot points
  geom_point( ) +
  #plot horizontal errorbars
  geom_errorbarh( aes( xmin = x.data - x.err, xmax = x.data + x.err ), 
                  height = 0.1 ) +
  geom_errorbar( aes( ymin = y.data - y.err, ymax = y.data + y.err ), 
                 width = 0.1 ) +
  #set color scale
  scale_color_gradient2( low = "purple4", mid = "darkcyan", high = "yellow", 
                         midpoint = min(df$z.data) + ( max(df$z.data) - min(df$z.data) ) / 2 )

#and then plot the chart as plotly
ggplotly(p1)

введите здесь описание изображения

person Wimpel    schedule 11.11.2019
comment
Немного некрасиво, но я думаю, что это единственное решение, которое в принципе сработает. Не могли бы вы показать мне, как изменить настройки холста и шрифта, чтобы придать им тот же вид по умолчанию, что и plotly? - person Ben; 12.11.2019
comment
добавьте + theme_linedraw() в код ggplot ... подробнее / другие темы можно найти здесь: ggplot2.tidyverse. org / reference / ggtheme.html Вы всегда можете настроить элемент темы так, как вам нравится ... - person Wimpel; 12.11.2019

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

# create the base plot
# if you uncomment the marker line it will also show the colourbar on the side
# but the formatting is messed up, haven't figured out yet how to solve that
p <- plot_ly(
  type='scatter',
  mode='markers'
  # , marker=list(colorscale='Viridis', colorbar=list(title='Z', limits=range(z.data)))
)

# create a vector of colours per point
z <- (z.data - min(z.data)) / (max(z.data) - min(z.data))
z <- viridis::viridis(1001)[round(z * 1e3) + 1]

# add each point separately
for (i in seq_along(x.err)){
  p <- p %>% add_markers(
    x=x.data[i],
    y=y.data[i], 
    error_x=list(array=x.err[i], color=z[i]),
    error_y=list(array=y.err[i], color=z[i]),
    marker=list(color=z[i]),
    showlegend=F
  )
}
p %>% layout(xaxis=list(title='X'), yaxis=list(title='Y'))

Что генерирует:  введите описание изображения здесь

person bobbel    schedule 08.11.2019
comment
Я поигрался с некоторыми вещами в этом направлении, но важно иметь цветовую полосу, чтобы указывать, что означают значения. - person Ben; 12.11.2019