【问题标题】:Layered axes in ggplot?ggplot中的分层轴?
【发布时间】:2014-10-30 15:54:29
【问题描述】:

我想知道是否可以在 GGLPOT2(或其他图形包;我更喜欢 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')

产生这个:

但我真正想要的是,在每个时期的条形图内,每个动物都有三个单独的堆叠条形(按颜色堆叠)。

我觉得我在这里遗漏了一段简单的语法,但“显而易见”的东西似乎不起作用,例如,

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

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    执行此操作的两个步骤:

    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")
    

    这看起来像:

    这里的一个问题是它没有描述哪种动物是哪种动物:没有特别简单的方法可以解决这个问题。这就是为什么我可能会通过刻面来制作这个情节:

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

    【讨论】:

    • 谢谢大卫;第一个解决方案是我一直在寻找的,但考虑到标签问题,facet wrap 效果很好
    • @MarcTulla 很好。另一种选择是ggplot(data, aes(x=period:animal, y=value, fill=color)) + geom_bar(stat="identity"):即将交互项放在 x 轴上。这就是你想要的吗?如果是这样,我会将其添加到答案中。
    【解决方案2】:

    即使已经有一个好的答案,我也想添加我的解决方案。如果我有 3 个分类变量并且我不想使用分面或类似的可视化,我总是使用这种可视化。

    这个图表是由下面的代码产生的,即使代码看起来很杂乱,我也已经习惯了:-)

    基本上我只是使用 geom_rect 来绘制我的条形图

    这是我的代码

    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]
    

    为内部 xaxis 的文本标签构建 data.table

    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
    

    【讨论】:

      猜你喜欢
      • 2017-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-26
      相关资源
      最近更新 更多