【问题标题】:How to center stacked percent barchart labels如何使堆积百分比条形图标签居中
【发布时间】:2016-04-26 11:53:05
【问题描述】:

我正在尝试使用ggplot2 绘制漂亮的stacked percent barchart。我已经阅读了一些材料并且几乎设法绘制出我想要的东西。另外,我附上材料,它可能在一个地方有用:

How do I label a stacked bar chart in ggplot2 without creating a summary data frame?

Create stacked barplot where each stack is scaled to sum to 100%

R stacked percentage bar plot with percentage of binary factor and labels (with ggplot)

我的问题是我无法将labels 放置在我想要的位置 - 在栏的中间。

您可以在上图中看到问题 - 标签看起来很糟糕,而且还相互重叠。

我现在正在寻找的是:

  1. 如何在条(区域)中间放置标签

  2. 如何绘制不是所有标签,但例如大于 10% 的标签?

  3. 如何解决重叠问题?

对于Q 1. @MikeWise 建议可能的solution。但是,我仍然无法处理这个问题。

另外,我附上了可重现的例子,我是如何绘制这张图的。

library('plyr')
library('ggplot2')
library('scales')
set.seed(1992)
n=68

Category <- sample(c("Black", "Red", "Blue", "Cyna", "Purple"), n, replace = TRUE, prob = NULL)
Brand <- sample("Brand", n, replace = TRUE, prob = NULL)
Brand <- paste0(Brand, sample(1:5, n, replace = TRUE, prob = NULL))
USD <- abs(rnorm(n))*100

df <- data.frame(Category, Brand, USD)

# Calculate the percentages
df = ddply(df, .(Brand), transform, percent = USD/sum(USD) * 100)


# Format the labels and calculate their positions
df = ddply(df, .(Brand), transform, pos = (cumsum(USD) - 0.5 * USD))

#create nice labes
df$label = paste0(sprintf("%.0f", df$percent), "%")  



ggplot(df, aes(x=reorder(Brand,USD,
                              function(x)+sum(x)),  y=percent, fill=Category))+
  geom_bar(position = "fill", stat='identity',  width = .7)+
  geom_text(aes(label=label, ymax=100, ymin=0), vjust=0, hjust=0,color = "white",  position=position_fill())+
  coord_flip()+
  scale_y_continuous(labels = percent_format())+
  ylab("")+
  xlab("")

【问题讨论】:

    标签: r ggplot2 bar-chart labels


    【解决方案1】:

    以下是如何使标签居中并避免为小百分比绘制标签。数据中的另一个问题是每种颜色都有多个条形部分。相反,在我看来,给定颜色的所有条形部分都应该组合在一起。下面的代码使用dplyr 而不是plyr 来设置绘图数据:

    library(dplyr)
    
    # Initial data frame   
    df <- data.frame(Category, Brand, USD)
    
    # Calculate percentages
    df.summary = df %>% group_by(Brand, Category) %>% 
      summarise(USD = sum(USD)) %>%   # Within each Brand, sum all values in each Category
      mutate(percent = USD/sum(USD))
    

    使用 ggplot2 版本 2,不再需要计算文本标签的坐标以使它们居中。相反,您可以使用position=position_stack(vjust=0.5)。例如:

    ggplot(df.summary, aes(x=reorder(Brand, USD, sum), y=percent, fill=Category)) +
      geom_bar(stat="identity", width = .7, colour="black", lwd=0.1) +
      geom_text(aes(label=ifelse(percent >= 0.07, paste0(sprintf("%.0f", percent*100),"%"),"")),
                    position=position_stack(vjust=0.5), colour="white") +
      coord_flip() +
      scale_y_continuous(labels = percent_format()) +
      labs(y="", x="")
    


    对于旧版本,我们需要计算位置。 (同上,但多了一行定义pos):

    # Calculate percentages and label positions
    df.summary = df %>% group_by(Brand, Category) %>% 
      summarise(USD = sum(USD)) %>%   # Within each Brand, sum all values in each Category
      mutate(percent = USD/sum(USD),
             pos = cumsum(percent) - 0.5*percent)
    

    然后使用ifelse 语句绘制数据以确定是否绘制了标签。在这种情况下,我避免为低于 7% 的百分比绘制标签。

    ggplot(df.summary, aes(x=reorder(Brand,USD,function(x)+sum(x)), y=percent, fill=Category)) +
      geom_bar(stat='identity',  width = .7, colour="black", lwd=0.1) +
      geom_text(aes(label=ifelse(percent >= 0.07, paste0(sprintf("%.0f", percent*100),"%"),""),
                    y=pos), colour="white") +
      coord_flip() +
      scale_y_continuous(labels = percent_format()) +
      labs(y="", x="")
    

    【讨论】:

    • 附加问题。有没有一种简单的方法可以在框中绘制标签? geom_label 函数似乎不起作用。 This link 也不要帮忙。方式看起来很复杂
    • 对如何通过新版本实现这一目标有任何想法吗?此页面上的最后一个“答案”显示了我遇到的类似问题,标签看起来是以相反的顺序放置的。我已经成功使用这种方法几个月了。
    【解决方案2】:

    我按照示例找到了如何为简单的堆叠条形图放置漂亮标签的方法。我认为它也可能有用。

    df <- data.frame(Category, Brand, USD)
    
    # Calculate percentages and label positions
    df.summary = df %>% group_by(Brand, Category) %>% 
      summarise(USD = sum(USD)) %>%   # Within each Brand, sum all values in each Category
      mutate( pos = cumsum(USD)-0.5*USD)
    
    ggplot(df.summary, aes(x=reorder(Brand,USD,function(x)+sum(x)), y=USD, fill=Category)) +
      geom_bar(stat='identity',  width = .7, colour="black", lwd=0.1) +
      geom_text(aes(label=ifelse(USD>100,round(USD,0),""),
                    y=pos), colour="white") +
      coord_flip()+
      labs(y="", x="")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-27
      • 1970-01-01
      • 2018-03-09
      • 2018-06-04
      相关资源
      最近更新 更多