ggplot2在堆叠的条形图上放置标签

时间:2019-06-27 15:21:43

标签: r ggplot2

我想在每个栏的顶部标记函数调用的输出(这是每月长度的总和)。

我试图将所需的数字存储在向量中,并将其用作标签,但这不起作用。

这是我的示例代码

library(ggplot2)

month<-c(1,3,2,4,3,10,12,4,9,5,6,6,7,9,9,8,10,9,11,12,9)
length<-c(2,3.5,4,10,14,16,20,34,10.5,2,10.4,3.4,4,5,6,12,5,34,5.6,56.5,22)
year<-c(2019,2018,2018,2017,2018,2016,2016,2017,2018,2019,2016,2017,2017,2018,2019,2016,2017,2018,2019,2016,2019)

df<-data.frame(month,length,year)


ggplot(df) +
  geom_bar(aes(month, length, fill = as.factor(year)), 
           position = "stack", stat = "summary", fun.y = "sum")+
  scale_x_continuous(breaks = seq(1,12,by = 1))

有没有办法将fun.y = "sum"的输出直接用作geom_text()标签?

2 个答案:

答案 0 :(得分:3)

根据文档:

  

...如果您希望条形的高度代表数据中的值,请改用geom_col()。 ...

因此,您的结果可以用更简洁的代码重现(我还自由转换了明显的因素)。

library(tidyverse)

month <- c(1,3,2,4,3,10,12,4,9,5,6,6,7,9,9,8,10,9,11,12,9)
length <- c(2,3.5,4,10,14,16,20,34,10.5,2,10.4,3.4,4,5,6,12,5,34,5.6,56.5,22)
year <- c(2019,2018,2018,2017,2018,2016,2016,2017,2018,2019,2016,2017,2017,2018,2019,2016,2017,2018,2019,2016,2019)

data.frame(month,length,year) %>% 
  mutate(
    month = as.factor(month),
    year = as.factor(year)) ->
  df

df %>% 
  ggplot() +
  geom_col(aes(month, length, fill = year))

在ggplot中,使用stat =总是很痛苦的,因此使用令人敬畏的dplyr动词来预先计算统计数据会更加容易。

df %>% 
  group_by(month) %>% 
  mutate(monthly = sum(length)) %>% 
  ggplot() +
  geom_col(aes(month, length, fill = year)) +
  geom_text(aes(month, monthly, label = monthly),
            vjust = -1) +
  ylim(0, 90)

此方法的怪异之处在于,它会多次多次打印某些标签。您可以创建一个单独的数据集来摆脱这种情况。

df %>% 
  ggplot() +
  geom_col(aes(month, length, fill = year)) +
  geom_text(aes(month, monthly, label = monthly),
            vjust = -1,
            data = . %>% group_by(month) %>% summarise(monthly = sum(length))) +
  ylim(0, 90)

我使用.代替了数据框引用,因此,如果要使用其他数据集,则只需替换df的一个实例。

enter image description here

答案 1 :(得分:2)

我不知道您的问题的答案是否可以将汇总结果直接用于geom_text。但我为您的问题提出了另一种解决方案:

library(ggplot2)
library(dplyr)

month<-c(1,3,2,4,3,10,12,4,9,5,6,6,7,9,9,8,10,9,11,12,9)
length<-c(2,3.5,4,10,14,16,20,34,10.5,2,10.4,3.4,4,5,6,12,5,34,5.6,56.5,22)
year<-c(2019,2018,2018,2017,2018,2016,2016,2017,2018,2019,2016,2017,2017,2018,2019,2016,2017,2018,2019,2016,2019)

df<-data.frame(
  year = as.factor(year),
  month = as.factor(month),
  length
)

df %>% 
  group_by(year, month) %>% 
  summarise(length = sum(length)) %>% 
  arrange(month, desc(year)) %>%
  plyr::ddply("month", transform, label_pos = cumsum(length) - .5 * length) %>% ## calculate label offset
  ggplot(aes(month, length)) +
  geom_bar(aes(fill = year), position = "stack", stat = "identity") +
  geom_text(aes(label = length, y = label_pos))

enter image description here


如果您希望每月总计达到100%的百分比,则可以使用scales软件包

df %>% 
  group_by(year, month) %>% 
  summarise(length = sum(length)) %>% 
  group_by(month) %>% 
  mutate(perc = scales::percent(round(length / sum(length), 3))) %>% 
  arrange(month, desc(year)) %>%
  plyr::ddply("month", transform, label_pos = cumsum(length) - .5 * length) %>% ## calculate label offset
  ggplot(aes(month, length)) +
  geom_bar(aes(fill = year), position = "stack", stat = "identity") +
  geom_text(aes(label = perc, y = label_pos))

enter image description here