2014-09-05 4 views
2

Мне интересно, можно ли сделать слоистые/сегментированные оси в GGLPOT2 (или другой графический пакет, я просто предпочитаю ggplot).Слоистые оси в ggplot?

Что я хочу сделать, это взять данные ниже, сделать сложную гистограмму, которая имеет период по оси x, но в течение каждого периода, каждое животное также. Тогда цвета баров в пределах каждого животного будет «цвет» переменная

set.seed(1234) 
data <- data.frame(
    animal = sample(c('bear','tiger','lion'), 50, replace=T), 
    color = sample(c('black','brown','orange'), 50, replace=T), 
    period = sample(c('first','second','third'), 50, replace=T), 
    value = sample(1:100, 50, replace=T)) 

затем положить это в столбчатой ​​диаграмме:

library(ggplot2) 
plot <- ggplot(data, aes(x=period, y=value, fill=color)) + 
    geom_bar(stat='identity') 

который производит это:

enter image description here

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

У меня есть чувство, что я отсутствующий простой кусок синтаксиса здесь, но «очевидные» вещи, кажется, не работает, например,

plot <- ggplot(data, aes(x=c(period,animal), y=value, fill=color)) + 
    geom_bar(stat='identity') 

ответ

4

Два шага к делать это:

  1. Добавьте group=animal эстетические к сюжету (пересказывайте группу животных)

  2. Добавить position="dodge" в свой geom_bar слой (скажи это бруски должны быть разделены)

Таким образом:

ggplot(data, aes(x=period, y=value, fill=color, group=animal, color=animal)) + 
     geom_bar(stat="identity", position="dodge") 

Это выглядит следующим образом:

enter image description here

Одна из проблем здесь является то, что она не описывает, какое животное является который: нет особо простого способа исправить это. Вот почему я бы, вероятно, сделать этот участок через огранку:

ggplot(data, aes(x=animal, y=value, fill=color)) + geom_bar(stat="identity") + 
    facet_wrap(~ period) 

enter image description here

+0

Благодаря David; первое решение - это то, что я искал, но, учитывая проблемы с маркировкой, фацетная упаковка работает достаточно хорошо –

+0

@MarcTulla Это хорошо. Другой альтернативой является ggplot (data, aes (x = period: animal, y = value, fill = color)) + geom_bar (stat = "identity") ': т. Е. Помещение члена взаимодействия по оси x. Это больше того, что вы искали? Если так, я добавлю это к ответу. –

2

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

Эта диаграмма производится следующим кодом, даже если код выглядит суматоху, я уже привык к нему :-)

В основном я просто использовать geom_rect нарисовать мой шкальный

enter image description here

А вот мой код

library(data.table) 
library(ggplot2) 

данные

set.seed(1234) 
data <- data.frame(
animal = sample(c('bear','tiger','lion'), 50, replace=T), 
color = sample(c('black','brown','orange'), 50, replace=T), 
period = sample(c('first','second','third'), 50, replace=T), 
value = sample(1:100, 50, replace=T)) 

только для удобства, я больше знаком с data.table, как с основным data.frame

dt <- as.data.table(data) 

группировкой основных данных

groups <- c("period", "animal", "color") 
thevalue <- c("value") 
dt.grouped <- dt[,lapply(.SD, sum), by = groups, .SDcols = thevalue] 

внутренней группа

xaxis.inner.member <- unique(dt.grouped$animal) 
xaxis.inner.count <- length(unique(xaxis.inner.member)) 
xaxis.inner.id <- seq(1:xaxis.inner.count) 
setkey(dt.grouped, animal) 
dt.grouped <- dt.grouped[J(xaxis.inner.member, inner.id = xaxis.inner.id)] 

внешняя группа

xaxis.outer.member <- unique(dt.grouped$period) 
xaxis.outer.count <- length(unique(xaxis.outer.member)) 
xaxis.outer.id <- seq(1:xaxis.outer.count) 
setkey(dt.grouped, period) 
dt.grouped <- dt.grouped[J(xaxis.outer.member, outer.id = xaxis.outer.id)] 

черчение параметров

xaxis.outer.width <- 0.9 
xaxis.inner.width <- (xaxis.outer.width/xaxis.inner.count) 
xaxis.inner.width.adjust <- 0.01/2 

dt.ordered <- dt.grouped[order(outer.id,inner.id, color),] 
dt.ordered[,value.cum := cumsum(value), by = list(period, animal)] 
dt.ordered[,xmin := (outer.id - xaxis.outer.width/2) + xaxis.inner.width * (inner.id - 1) +  xaxis.inner.width.adjust] 
dt.ordered[,xmax := (outer.id - xaxis.outer.width/2) + xaxis.inner.width * inner.id - xaxis.inner.width.adjust] 
dt.ordered[,ymin := value.cum - value] 
dt.ordered[,ymax := value.cum] 

строительство data.table для текстовых меток внутреннего Xaxis

dt.text <- data.table(
period = rep(xaxis.outer.member, each = xaxis.inner.count) 
,animal = rep(xaxis.inner.member, times = xaxis.inner.count) 
) 
setkey(dt.text, animal) 
dt.text <- dt.text[J(xaxis.inner.member,inner.id = xaxis.inner.id),] 
setkey(dt.text, period) 
dt.text <- dt.text[J(xaxis.outer.member,outer.id = xaxis.outer.id),] 
dt.text[, xaxis.inner.label := animal] 
dt.text[, xaxis.inner.label.x := (outer.id - xaxis.outer.width/2) + xaxis.inner.width * inner.id - (xaxis.inner.width/2) ] 

помещены изображение начинается здесь

p <- ggplot() 
p <- p + geom_rect(data = dt.ordered, 
aes(
,x = period 
,xmin = xmin 
,xmax = xmax 
,ymin = ymin 
,ymax = ymax 
,fill = color) 
) 

добавление значений в качестве меток

p <- p + geom_text(data = dt.ordered, 
aes(
label = value 
,x = (outer.id - xaxis.outer.width/2) + xaxis.inner.width * inner.id - (xaxis.inner.width/2) 
,y = value.cum 
) 
,colour = "black" 
,vjust = 1.5    
) 

добавления метки для внутреннего Xaxis

p <- p + geom_text(data = dt.text, 
aes(
label = xaxis.inner.label 
,x = xaxis.inner.label.x 
,y = 0 
) 
,colour = "darkgrey" 
,vjust = 1.5 
) 

наконец черчения диаграмму

p 
+0

Это серьезно много кода! – geotheory

Смежные вопросы