Removing extraneous axis spline after adding labels to the ends of bars on ggbarplot

40 views Asked by At

I have a dataframe like this:

 Group Total  Type Count Percentage
1  Group1   166 type1    65      39.20
2  Group1   166 type2    13       7.83
3  Group1   166 type3    73      44.00
4  Group1   166 type4     3       1.81
5  Group1   166 type5     0       0.00
6  Group1   166 type6    12       7.23
7  Group2    53 type1    16      30.20
8  Group2    53 type2     2       3.77
9  Group2    53 type3    33      62.30
10 Group2    53 type4     0       0.00
11 Group2    53 type5     0       0.00
12 Group2    53 type6     2       3.77

the data frame:

df <- data.frame(
  Group = rep(c("Group1", "Group2"), each = 6L),
  Total = rep(c(166, 53), each = 6L),
  Type = factor(rep(c("type1", "type2", "type3", "type4", "type5", "type6"), 2)),
  Count = c(65, 13, 73, 3, 0, 12, 16, 2, 33, 0, 0, 2),
  Percentage = c(39.2, 7.83, 44, 1.81, 0, 7.23, 30.2, 3.77, 62.3, 0, 0, 3.77)
)

I would like to create a data frame with labels at the ends of the bars but there is trailing axis line, how can I remove this extraneous axis line after the 100% tick mark?

enter image description here

Here is my code:

library(ggpubr)
g <- ggbarplot(df, x='Group', y='Percentage',
               fill='Type', ylab=FALSE,
               order=rev(c('Group1', 'Group2'))) + 
  scale_fill_manual(values=ggsci::pal_aaas('default', 1)(6)) +
  geom_text(data=unique(df[, c('Group', 'Total')]), 
            aes(x=Group, y=115, label=paste0('n = ', Total)), 
            color="black", hjust=1, size=4) +
  theme(plot.margin = unit(c(1,3,1,1), "lines"), 
        axis.ticks.y = element_blank()) +
  scale_y_continuous(expand=c(0, 0), breaks=seq(0, 100, 10)) +
  coord_flip()
2

There are 2 answers

0
Allan Cameron On BEST ANSWER

You need to set hard ylim inside coord_flip, but turn clip = 'off' and increase your right-hand margin to allow the labels to fit:

ggbarplot(df, x = 'Group', y = 'Percentage', fill = 'Type', ylab = FALSE,
          order = rev(c('Group1', 'Group2'))) + 
  geom_text(data = unique(df[, c('Group', 'Total')]), 
            aes(x = Group, y = 115, label = paste0('n = ', Total)), 
            color = "black", hjust = 1, size = 4) +
  scale_fill_manual(values = ggsci::pal_aaas('default', 1)(6)) +
  scale_y_continuous(expand = c(0, 0), breaks = seq(0, 100, 10)) +
  coord_flip(clip = 'off', ylim = c(0, 100)) +
  theme(plot.margin = unit(c(1, 6, 1, 1), "lines"), 
        axis.ticks.y = element_blank())

enter image description here

2
stefan On

Allan's approach is definitely the more pragmatic and faster one. (:

But a second option would be to make use of the secondary axis trick, i.e. add the labels via a secondary axis. However, besides some data wrangling this requires to create your plot from scratch using ggplot2 and to use a continuous y scale (as a discrete does not allow for a secondary axis):

library(ggplot2)
library(ggpubr)
library(dplyr, warn = FALSE)

df <- df |>
  mutate(
    Group_num = as.numeric(factor(Group,
      levels = rev(c("Group1", "Group2"))
    ))
  )

dat_labels <- df |>
  distinct(Group, Group_num, Total) |>
  arrange(Group_num)

ggplot(df, aes(Percentage, Group_num, fill = Type)) +
  geom_col(orientation = "y", color = "black") +
  scale_fill_manual(
    values = ggsci::pal_aaas("default", 1)(6)
  ) +
  theme(
    plot.margin = unit(c(1, 3, 1, 1), "lines"),
    axis.ticks.y = element_blank()
  ) +
  scale_y_continuous(
    breaks = dat_labels$Group_num,
    labels = dat_labels$Group,
    sec.axis = dup_axis(
      labels = paste0("n = ", dat_labels$Total)
    )
  ) +
  scale_x_continuous(
    expand = c(0, 0), breaks = seq(0, 100, 10)
  ) +
  ggpubr::theme_pubr() +
  theme(
    axis.line.y.right = element_blank(),
    axis.ticks.y.right = element_blank()
  ) +
  labs(y = NULL)

enter image description here