Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add different labels to show totals in stacked bar plot in ggplot R? [duplicate]

My question is somewhat similar to this: How to add text label to show total n in each bar of stacked proportion bars in ggplot?

However, the solutions offered there don't work in my case because the stacked bars are not always the same height and don't add up to 100%

I will let the example speak for itself:

company=c('CompanyA','CompanyA', 'CompanyA', 'CompanyA','CompanyB', 'CompanyB', 'CompanyB', 'CompanyB')
SubSegment = c('SubSeg1', 'SubSeg1', 'SubSeg2', 'SubSeg2', 'SubSeg1', 'SubSeg1', 'SubSeg2', 'SubSeg2')
variable = c('Ratio1', 'Ratio2','Ratio1', 'Ratio2','Ratio1', 'Ratio2','Ratio1', 'Ratio2')
value = c(0.311, 0.256, 0.389, 0.105, 0.256, 0.1002, 0.2569, 0.2856)
df = as.data.frame(cbind(company, SubSegment, variable, value))
df=df%>% mutate(Label=value)
df[,4:ncol(df)]<- sapply(df[,4:ncol(df)] , as.numeric)
df[,ncol(df)]<- sapply(df[,ncol(df)] , function(x) scales::percent(x, accuracy = 0.1))

var_levels= c('Ratio1', 'Ratio2')
colors= c("#F3DF6C", "cyan")

plot.1<- ggplot(df, aes(fill=factor(variable, levels = var_levels), y=value, x=company)) + 
  geom_bar(position="stack", stat="identity", alpha=1) +
  scale_y_continuous(limits = c(0, 0.6)) +
  geom_text(aes(label=Label), position = position_stack(vjust = 0.5), size=2.5) +
  #geom_text(data=df_totals_2, aes(x= Company, label= Label, y=value, fill=NULL), nudge_y=10)+
  facet_wrap(~factor(SubSegment ), ncol=1)  +
  theme(plot.title = element_text(size = 11), axis.title.x = element_blank(), axis.title.y = element_blank(), axis.text.x = element_blank(), 
        axis.ticks.x = element_blank(),     panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        legend.position = c(0.88, 0.89) , legend.text = element_text(size = 9.5),
        legend.title =  element_text(size = 11),
        legend.background = element_rect(fill="gray92", linetype="solid",colour ="gray75")) +
  scale_fill_manual(values=colors, name="SubSegment") + 
  coord_flip()

plot(plot.1)

By doing that I get the following plot: Stacked Plot with labels inside

I would like to also add a label that will give the total of each stacked bar:

df_t = df[,c(1,2,4)] # df with TOTALS
df_t[,ncol(df_t)]<- sapply(df_t[,ncol(df_t)] , as.numeric)
df_t = df_t %>% group_by(company, SubSegment) %>%
  summarise(value = sum(value)) %>% mutate(Label=value)
df_t[,ncol(df_t)]<- sapply(df_t[,ncol(df_t)] , function(x) scales::percent(x, accuracy = 0.1))

If I plotted the totals without the stacked plot I could get something like this: enter image description here

Basically, I want to "combine" the two plots, or simply add the total labels to the stacked plot. I have tried a few different approaches but I can't get the totals to appear on the right place (at the end of each bar)

for the non-stacked barplot this is what I used to create the labels:

plot.2<- ggplot(df_t, aes(fill=company, y=value, x=company)) + 
  geom_bar(stat="identity", position = 'dodge')+
  scale_y_continuous(limits = c(0, 0.6)) +
  geom_text(aes(label=Label),position=position_dodge(width=0.9), vjust=-0.25, hjust=-0.2) +
 facet_wrap(~factor(SubSegment ), ncol=1)  + coord_flip()
 
like image 858
lu-202 Avatar asked Jan 28 '26 10:01

lu-202


1 Answers

You can use your second dataframe df_t in a new geom_text where you could add for example 0.03 to value by specifing the position of your labels. You can use the following code:

library(ggplot2)
plot.1<- ggplot(df, aes(fill=factor(variable, levels = var_levels), y=value, x=company)) + 
  geom_bar(position="stack", stat="identity", alpha=1) +
  scale_y_continuous(limits = c(0, 0.6)) +
  geom_text(aes(label=Label), position = position_stack(vjust = 0.5), size=2.5) +
  geom_text(aes(company, value + 0.03, label = Label, fill = NULL), data = df_t) +
  facet_wrap(~factor(SubSegment ), ncol=1)  +
  theme(plot.title = element_text(size = 11), axis.title.x = element_blank(), axis.title.y = element_blank(), axis.text.x = element_blank(), 
        axis.ticks.x = element_blank(),     panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        legend.position = c(0.88, 0.89) , legend.text = element_text(size = 9.5),
        legend.title =  element_text(size = 11),
        legend.background = element_rect(fill="gray92", linetype="solid",colour ="gray75")) +
  scale_fill_manual(values=colors, name="SubSegment") + 
  coord_flip()

plot(plot.1)

Output:

enter image description here

like image 91
Quinten Avatar answered Jan 30 '26 00:01

Quinten



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!