удалить пустой контур в гистограмме ggplot - PullRequest
0 голосов
/ 23 апреля 2019

У меня есть фрейм данных, подобный этому:

df <- data.frame(time = rep(1:10, 2),
                 value = c(0,0,0,0, abs(rnorm(6)),
                           0,0,0,0,0, abs(rnorm(5))),
                 group = c(rep("B", 10),
                         rep("A", 10)),
                 group_fill = c(rep("no", 7),
                              rep("B", 3),
                              rep("no", 7),
                              rep("A", 3)) )

Я представляю это в виде столбчатой ​​диаграммы с накоплением:

ggplot(df, aes(x = time, y = value, color= group, fill = group_fill)) + 
  geom_bar(stat = "identity") +
  scale_color_manual(values=c("#E69F00", "#56B4E9", "#333333")) +
  scale_fill_manual(values=c("#E69F00", "#56B4E9", "#FFFFFF")) +
  scale_x_continuous(breaks = 1:10) +
  theme_bw()

enter image description here

Из набора данных очевидно, что первые 5 наблюдений для «B» и первые 4 аберрации для «A» точно равны нулю.

Однако ggplot добавляет небольшой оранжевый контур для этих значений.

Как я могу удалить оранжевый контур для "A" в первых наблюдениях 1: 5?

Важно, чтобы время 5-7 не заполнялось, т.е. только контуры.

Второй вопрос: как сделать так, чтобы легенда «группы» была заполнена синим и оранжевым, а не серым?

Ответы [ 3 ]

2 голосов
/ 23 апреля 2019

Подмножество фрейма данных, чтобы исключить нули subset(df, value != 0), и удалить легенду для цвета с помощью guide = FALSE:

set.seed(1)
df <- data.frame(time = rep(1:10, 2),
                 value = c(0,0,0,0, abs(rnorm(6)),
                           0,0,0,0,0, abs(rnorm(5))),
                 group = c(rep("B", 10),
                         rep("A", 10)),
                 group_fill = c(rep("no", 7),
                              rep("B", 3),
                              rep("no", 7),
                              rep("A", 3)) )    
    ggplot(subset(df, value != 0), aes(x = time, y = value, color= group, fill = group_fill)) +
          geom_bar(stat = "identity") +
          scale_color_manual(values = c("#E69F00", "#56B4E9", "#333333"),  guide = FALSE) +
          scale_fill_manual(values = c("#E69F00", "#56B4E9", "#FFFFFF")) +
          scale_x_discrete(breaks = 1:10) +
          theme_bw()

enter image description here

2 голосов
/ 23 апреля 2019

Отредактировано, чтобы превратить нули в NA, что, кажется, работает.

df <- data.frame(time = rep(1:10, 2),
                 value = c(0,0,0,0, abs(rnorm(6)),
                           0,0,0,0,0, abs(rnorm(5))),
                 group = c(rep("B", 10),
                           rep("A", 10)),
                 group_fill = c(rep("no", 7),
                                rep("B", 3),
                                rep("no", 7),
                                rep("A", 3)) )

 df[df == 0] <- NA

  ggplot(df, aes(x = time, y = value, color = group, fill = group_fill)) + 
  geom_bar(stat = "identity") +
  scale_color_manual(values=c("#E69F00", "#56B4E9", "#333333"), guide = F) +
  scale_fill_manual(values=c("#E69F00", "#56B4E9", "#FFFFFF")) +
  scale_x_continuous(breaks = 1:10) +
  theme_bw()
0 голосов
/ 23 апреля 2019

Если вы также хотите отображать пустое время просто без какой-либо линии бара, есть способ использовать базу barplot. Сначала нам нужны данные в широком формате, чего можно достичь с помощью reshape (вы также можете посмотреть на ?data.table::dcast) и создать два клона.

dat1 <- reshape(dat[-4], idvar="group", direction="wide")
dat1[] <- lapply(dat1, function(x) if (all(x == 0)) NA else x)  # set zeros to NA
dat1.1 <- dat1.2 <- dat1  # create clones

В одном клоне мы устанавливаем «нет раз» на NA, в другом - противоположности.

no.times <- paste0("value.", 1:7)

dat1.1[names(dat1) %in% no.times] <- NA
dat1.2[-which(names(dat1) %in% no.times)] <- NA

Теперь мы можем построить один график поверх другого (используя опцию add=TRUE) с различными настройками для border и col.

barplot(as.matrix(dat1.1[-1]), names.arg=1:10, 
        ylim=c(-.1, max(colSums(dat1[-1]), na.rm=TRUE) + .1),
        border=0, col=c("#56B4E9", "#E69F00"), 
        main="My plot", xlab="Time", ylab="Value")
barplot(as.matrix(dat1.2[-1]), names.arg=1:10,
        border=c("#56B4E9", "#E69F00"), col=NA, add=TRUE)
box()  # add box around plot
legend("topleft", legend=c("A", "B", "no"), pch=c(15, 15, 0),  # add legend
       col=c("#56B4E9", "#E69F00", "black"), title="Group")

Результат

enter image description here

Данные

dat <- structure(list(time = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 
1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L), value = c(0, 0, 0, 
0, 1.37095844714667, 0.564698171396089, 0.363128411337339, 0.63286260496104, 
0.404268323140999, 0.106124516091484, 0, 0, 0, 0, 0, 1.51152199743894, 
0.0946590384130976, 2.01842371387704, 0.062714099052421, 1.30486965422349
), group = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("A", "B"), class = "factor"), 
    group_fill = structure(c(3L, 3L, 3L, 3L, 3L, 3L, 3L, 2L, 
    2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 1L, 1L, 1L), .Label = c("A", 
    "B", "no"), class = "factor")), class = "data.frame", row.names = c(NA, 
-20L))
...