1

I want to plot a table as a stacked bar plot and label the bars with the percentages. Here is an example:

data <- matrix(c(34, 66, 22, 78), ncol = 2)
data <- as.table(data)
colnames(data) <- c("shop1", "shop2")
rownames(data) <- c("prod1", "prod2")

library(reshape2)
data_m <- melt(data, varnames = c("Product", "Shop"), id.vars = "Product")

library(scales)
library(ggplot2)
ggplot(data_m, aes(x = Shop, y = value, fill = Product)) + 
geom_bar(position = "fill", stat = "identity") + 
scale_y_continuous(labels = percent_format()) +
labs(x = "", y = "")

enter image description here

I tried to add the labels with

geom_text(data = data_m, aes(x = Shop, y = value, 
                         label = paste0((value/100) * 100,"%")), size=4)

but this results in enter image description here

EDIT: With JanLauGe's answer I get

enter image description here

Now, the percentages are wrongly assigned.

Another remark: what to do if the column sums of the table were not the same, say 91 and 107 instead of 100 as assumed in my above example?

zx8754
  • 52,746
  • 12
  • 114
  • 209
Joe
  • 1,628
  • 3
  • 25
  • 39

1 Answers1

5

Try this instead

geom_text(data = data_m, 
          aes(x = Shop, 
              y = value / max(value), 
              label = paste0(value/100,"%")), 
          size = 4)

The problem: label position is relative to the plot area (0 to 1, 1 = max(value)).

The solution: rescale value accordingly.


EDIT: Duplicate of this post.

What you are looking for is this:

ggplot(data = data_m, 
       aes(x = Shop, 
           y = value, 
           fill = Product,
           cumulative = TRUE)) +
  geom_col() +
  geom_text(aes(label = paste0(value/100,"%")), 
            position = position_stack(vjust = 0.5)) + 
  theme_minimal()
Community
  • 1
  • 1
JanLauGe
  • 2,297
  • 2
  • 16
  • 40
  • actually, try `value / 100` as well. But at the end of the day it depends on where exactly you would like the label. At the bottom, in the middle, or at the top of each chunk. – JanLauGe Mar 28 '17 at 09:32
  • Ideally, the labels were at the middle of each chunk as in http://t-redactyl.io/blog/2016/01/creating-plots-in-r-using-ggplot2-part-4-stacked-bar-plots.html – Joe Mar 28 '17 at 09:43
  • duplicate, see my edit – JanLauGe Mar 28 '17 at 09:53
  • How to modify your snippet in the case of different column sums? – Joe Mar 28 '17 at 10:09
  • the second snippet should still work exactly the same way – JanLauGe Mar 28 '17 at 10:15
  • No, it does not, because the "100" in `paste0(value/100,"%")` has to be replaced by two different values. – Joe Mar 28 '17 at 10:21
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/139233/discussion-between-joe-and-janlauge). – Joe Mar 28 '17 at 10:23
  • Your value / 100 only affects the labels, not their position of the labels. However, you can use something like value / sum(value) to get a different label value. This will give you percentage of total across all shops. If you want it grouped by shop, I recommend adding a separate total column to your data frame and using that to generate the label you would like. – JanLauGe Mar 28 '17 at 11:25