【问题标题】:Stacked bar chart with varying widths in ggplotggplot中不同宽度的堆积条形图
【发布时间】:2018-12-10 16:46:50
【问题描述】:

我尝试构建一个不同宽度的堆积条形图,宽度表示分配的平均数量,而高度表示分配的数量。

接下来,你会发现我的可重现数据:

procedure = c("method1","method2", "method3", "method4","method1","method2", "method3", "method4","method1","method2", "method3","method4")
sector =c("construction","construction","construction","construction","delivery","delivery","delivery","delivery","service","service","service","service") 
number = c(100,20,10,80,75,80,50,20,20,25,10,4)
amount_mean = c(1,1.2,0.2,0.5,1.3,0.8,1.5,1,0.8,0.6,0.2,0.9) 

data0 = data.frame(procedure, sector, number, amount_mean)

当使用 geom_bar 并在 aes 中包含宽度时,我收到以下错误消息:

position_stack requires non-overlapping x intervals. Furthermore, the bars are no longer stacked. 
bar<-ggplot(data=data0,aes(x=sector,y=number,fill=procedure, width = amount_mean)) + 
geom_bar(stat="identity") 

我还查看了 mekko-package,但似乎这仅适用于条形图。

这里是我最后想要的(不是基于上面的数据):

知道如何解决我的问题吗?

【问题讨论】:

  • 如果一切都失败了,可以预先计算一切并使用geom_rect
  • 您希望如何订购堆叠?我现在用geom_tile 做,它可以让你设置矩形的中心,然后设置它的宽度和高度,但它看起来很奇怪

标签: r ggplot2


【解决方案1】:

我也尝试过同样的方法,geom_col(),但我遇到了同样的问题 - 使用 position = "stack" 似乎我们无法在不取消堆叠的情况下分配 width 参数。

但事实证明,这个解决方案非常简单——我们可以使用geom_rect()“手动”构建这样的情节。

有你的数据:

df <- data.frame(
  procedure   = rep(paste("method", 1:4), times = 3),
  sector      = rep(c("construction", "delivery", "service"), each = 4),
  amount      = c(100, 20, 10, 80, 75, 80, 50, 20, 20, 25, 10, 4),
  amount_mean = c(1, 1.2, 0.2, 0.5, 1.3, 0.8, 1.5, 1, 0.8, 0.6, 0.2, 0.9)
)

起初我已经转换了你的数据集:

df <- df |>
  mutate(
      amount_mean = amount_mean / max(amount_mean),
      sector_num  = as.numeric(sector)
  ) |>
  arrange(desc(amount_mean)) |>
  group_by(sector) |>
  mutate(
    xmin = sector_num - amount_mean / 2,
    xmax = sector_num + amount_mean / 2,
    ymin = cumsum(lag(amount, default = 0)), 
    ymax = cumsum(amount)
  ) |>
  ungroup()

我在这里做什么:

  1. 我缩小了amount_mean,所以0 &gt;= amount_mean &lt;= 1(更适合绘图,反正我们没有其他比例来显示amount_mean 的真实值);
  2. 我还将sector 变量解码为数值(用于绘图,见下文);
  3. 我已按amount_mean 的降序排列数据集(重表示 - 在底部,轻表示在顶部);
  4. 按部门分组,我计算了xminxmax 来表示amount_mean,以及yminymax 的金额。前两个有点棘手。 ymax 很明显 - 您只需从第一个 amount 开始计算所有 amount累积和。您还需要累计和来计算ymin,但从0开始。所以第一个矩形用ymin = 0 绘制,第二个矩形用ymin = ymax 绘制,等等。所有这些都是在sectors 的每个单独组中执行的。

绘制数据:

df |>
  ggplot(aes(xmin = xmin, xmax = xmax,
             ymin = ymin, ymax = ymax, 
             fill = procedure
             )
         ) +
  geom_rect() +
  scale_x_continuous(breaks = df$sector_num, labels = df$sector) +
  #ggthemes::theme_tufte() +
  theme_bw() +
  labs(title = "Question 51136471", x = "Sector", y = "Amount") +
  theme(
    axis.ticks.x = element_blank()
  )

结果:

防止对procedure 变量重新排序的另一个选项。所以所有人都可以说“红色”在下降,“绿色”在上面等等。但它看起来很丑:

df <- df |>
  mutate(
      amount_mean = amount_mean / max(amount_mean),
      sector_num = as.numeric(sector)
  ) |>
  arrange(procedure, desc(amount), desc(amount_mean)) |>
  group_by(sector) |>
  mutate(
    xmin = sector_num - amount_mean / 2,
    xmax = sector_num + amount_mean / 2,
    ymin = cumsum(lag(amount, default = 0)), 
    ymax = cumsum(amount)
  ) |>
  ungroup()

【讨论】:

  • 非常感谢您的逐步解释。 amount_mean 的重新缩放为您提供了极大的设计灵活性。完美。
  • 我不知道为什么,但是按组计算ymin和ymax不能正常工作。我总是得到所有值的累积。可能是什么问题?
  • 也许dplyr::mutate(...) 会有所帮助
  • 要将扇区变量解码为数字,您需要使用factor。那是sector_num = as.numeric(factor(sector))
猜你喜欢
  • 2020-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多