Заставить сюжетный график скрипки не отображать скрипку на нулевых значениях

У меня есть измерения из нескольких групп, которые я хотел бы построить в виде графиков скрипки:

set.seed(1)
df <- data.frame(val = c(runif(100,1,5),runif(100,1,5),rep(0,100)),
                 group = c(rep("A",100),rep("B",100),rep("C",100)))

Использование ggplot2 R:

library(ggplot2)
ggplot(data = df, aes(x = group, y = val, color = group)) + geom_violin()

Я получаю: введите здесь описание изображения

Но когда я пытаюсь получить эквивалент с plotly R, используя:

library(plotly)
plot_ly(x = df$group, y = df$val, split = df$group, type = 'violin', box = list(visible = F), points = F, showlegend = T, color = df$group)

Я получаю: введите здесь описание изображения

Где группа "С" получает надутую/искусственную скрипку.

Любая идея, как справиться с этим, а не с помощью ggplotly?


person dan    schedule 05.03.2019    source источник
comment
Интересно, что если вы просто используете ggplotly на изначально созданном графике, он отлично работает. Не публикуйте это как ответ, так как должен быть способ сделать это через каналы, отличные от ggplot.   -  person OganM    schedule 06.03.2019


Ответы (1)


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

Чтобы продемонстрировать, я использую library(data.table) для этапа фильтрации. Вы можете использовать dplyr или базовые версии той же процедуры, если хотите:

setDT(df)[, toplot := diff(range(val)) > 0, group]

Теперь мы можем построить группы, используя разные стили трассировки, в зависимости от того, должны ли они иметь скрипки или нет.

plot_ly() %>%
  add_trace(data = df[(toplot)], x = ~group, y = ~val, split = ~group, 
            type = 'violin', box = list(visible = F), points = F) %>% 
  add_boxplot(data = df[(!toplot)], x = ~group, y = ~val, split = ~group)

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

person dww    schedule 06.03.2019