lu-202
lu-202

Reputation: 131

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

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

Upvotes: 3

Views: 1404

Answers (1)

Quinten
Quinten

Reputation: 41235

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

Upvotes: 4

Related Questions