AK47 - 1 year ago 69
R Question

# How to center stacked percent barchart labels

I am trying to plot nice

`stacked percent barchart`
using
`ggplot2`
. I've read some material and almost manage to plot, what I want. Also, I enclose the material, it might be useful in one place:

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

Create Stacked percent barplot in R

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

My problem is that I can't place
`labels`
where I want - in the middle of the bars.

You can see the problem in the picture above - labels looks awfull and also overlap each other.

What I am looking for right now is:

1. How to place labels in the midde of the bars (areas)

2. How to plot not all the labels, but for example which are greather than 10%?

3. How to solve overlaping problem?

For the
`Q 1.`
@MikeWise suggested possible solution. However, I still can't deal with this problem.

Also, I enclose reproducible example, how I've plotted this grahp.

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

Here's how to center the labels and avoid plotting labels for small percentages. An additional issue in your data is that you have multiple bar sections for each colour. Instead, it seems to me all the bar sections of a given colour should be combined. The code below uses `dplyr` instead of `plyr` to set up the data for plotting:

``````library(dplyr)

# Initial data frame
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(percent = USD/sum(USD),
pos = cumsum(percent) - 0.5*percent)
``````

To plot the data, use an `ifelse` statement to determine whether a label is plotted or not. In this case, I've avoided plotting a label for percentages less than 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="")
``````

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download