Home > Enterprise >  ggplot: How to set different alignments on the geom_text position based on type of variable?
ggplot: How to set different alignments on the geom_text position based on type of variable?

Time:11-30

I have a 100% stacked bar chart that displays 3 types of variable. I've set a example db so I could create a graph more easily.

I've already adjust the chart with the colors and information I need. But I'm not being able to independently position the labels. Here's the current code and output.

Code:

(empilhado<-ggplot(dfm, aes(y = Year, x = abs(value), fill = variable))   
  scale_x_continuous(sec.axis = sec_axis(trans = ~.*1, name="Trab."), expand=expansion(mult=c(0,0.05))) 
  geom_col(data = rotulo, aes(y = Year, x=abs(trabalho), fill=NULL), width = .7, colour="black", lwd=0.1, position = "fill", orientation = "y")  
  geom_label(data = rotulo, aes(y= Year, x = abs(trabalho), fill=NULL, label=paste(format(round(trabalho, digits=0), nsmall=0, decimal.mark=",", big.mark="."), 
                                                                                  format(round(aprovado, digits=0), nsmall=0, decimal.mark=",", big.mark="."))
                              ), color="black", size=4, position = position_fill(vjust=1.06))  
  geom_col(width = .7, colour="black", lwd=0.1, position = "fill", orientation = "y")  
  geom_text(aes(label=format(round(value, digits=0), nsmall=0, decimal.mark=",", big.mark=".")),
            size=4, color="white", position = position_fill(vjust=0.5))  
  theme(panel.grid.major =   element_line(colour = "gray90",size=0.75), panel.grid.minor =   element_line(colour = "gray90",size=0.75),
        legend.position="top", axis.text.x = element_blank(), axis.ticks.x = element_blank(),
        axis.title.x = element_blank(), panel.background = element_blank()) 
  scale_fill_manual(values = c("#000000","tomato","blue"))

Output:

Current Output

How is it now? Position_fill(vjust=0.5), so all the labels are centered inside its respective bar.

What I want? To be able to set the position of the 'Marionete' label on the left(like a vjust=0 would do), keep the 'Pedido' label as is (in the center of the 'Pedido' stacked bar) and place the 'Fatura' label on the right (like a vjust=1 would do).

Thanks in advance!

CodePudding user response:

One option to achieve your desired result would be to compute/set the positions for each label and the horizontal alignment manually instead of making use of position="fill":

Making use of some random mock data:

library(ggplot2)
library(dplyr)

dfm <- dfm %>%
  group_by(Year) %>%
  arrange(desc(variable)) %>%
  mutate(
    pct = value / sum(value),
    x_label = case_when(
      variable == "Marionete" ~ 0,
      variable == "Pedido" ~ .5 * (cumsum(pct)   lag(cumsum(pct))),
      TRUE ~ 1
    ),
    hjust = case_when(
      variable == "Marionete" ~ 0,
      variable == "Pedido" ~ .5,
      TRUE ~ 1
    )
  )


ggplot(dfm, aes(y = Year, x = abs(value), fill = variable))  
  scale_x_continuous(sec.axis = sec_axis(trans = ~ . * 1, name = "Trab."), expand = expansion(mult = c(0, 0.05)))  
  geom_col(width = .7, colour = "black", lwd = 0.1, position = "fill", orientation = "y")  
  geom_text(aes(x = x_label, label = format(round(value, digits = 0), nsmall = 0, decimal.mark = ",", big.mark = "."), hjust = hjust),
    size = 4, color = "white"
  )  
  theme(
    panel.grid.major = element_line(colour = "gray90", size = 0.75), panel.grid.minor = element_line(colour = "gray90", size = 0.75),
    legend.position = "top", axis.text.x = element_blank(), axis.ticks.x = element_blank(),
    axis.title.x = element_blank(), panel.background = element_blank()
  )  
  scale_fill_manual(values = c("#000000", "tomato", "blue"))

DATA

set.seed(123)

dfm <- data.frame(
  Year = rep(c(2006:2016), each = 3),
  value = sample(1:100, 3 * 11, replace = TRUE),
  variable = c("Fatura", "Pedido", "Marionete")
)
dfm$variable <- factor(dfm$variable, levels = c("Fatura", "Pedido", "Marionete"))
dfm$Year <- factor(dfm$Year)
  • Related