E_H
E_H

Reputation: 231

Can you put labels between horizontal bars?

I am plotting a horizontal, stacked bar chart. The labels for my bars are very long. Is there a way I can put them above their corresponding bar? Otherwise, the space on my page is not used well, the plot will be displayed very small. Here is my code and plot:

I'd like to put "Zivildienst" and "Katastrophenschutz" above the bars, not to the left of them.

I'd like to put "Zivildienst" and "Katastrophenschutz" above the bars, not to the left of them.

data3 <- data.frame(System=rep(c('Zivildienst', 'Katastrophenschutz'), each=5),
                    Einstellung=rep(c('Sehr unwahrscheinich','Eher unwahrscheinlich','Weiss nicht','Eher wahrscheinlich','Sehr wahrscheinlich'), times=2),
                    Anzahl=c(131, 142, 283, 421, 981, 54, 140, 490, 418, 856))
level_order <- c('Zivildienst', 'Katastrophenschutz') 


# Get the levels for "Einstellung" in the required order
data3$Einstellung = factor(data3$Einstellung, levels = c('Weiss nicht','Sehr unwahrscheinich','Eher unwahrscheinlich','Eher wahrscheinlich','Sehr wahrscheinlich'))
data3 = arrange(data3, System, desc(Einstellung))

# Calculate the percentages
data3 = ddply(data3, .(System), transform, percent = Anzahl/sum(Anzahl) * 100)

# Format the labels and calculate their positions
data3 = ddply(data3, .(System), transform, pos = (cumsum(Anzahl) - 0.5 * Anzahl))
data3$label = paste0(sprintf("%.0f", data3$percent), "%")

cbPalette <- c("#999999", "#2A7AD4", "#5C96D7", "#D3A253", "#D48F1D")

# Plot
ggplot(data3, aes(x = factor(System), y = Anzahl, fill = Einstellung)) +
  geom_bar(stat = "identity", width = .3) +
  geom_text(aes(y = pos, label = label), size = 4) +
  theme(panel.background = element_blank(),
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        axis.title.y = element_blank(),
        aspect.ratio = .3) +
  scale_fill_manual(values=cbPalette)+
  coord_flip()+
  ggtitle("Werden Sie sich für die Alternative entscheiden?", subtitle = "2000 Männer befragt") + labs(x = NULL)

Upvotes: 2

Views: 394

Answers (2)

zx8754
zx8754

Reputation: 56149

Using facet:

#fix the order of factors
data3$System <- factor(data3$System, levels = c("Zivildienst", "Katastrophenschutz"))

#plot with facets
ggplot(data3, aes(x = System, y = Anzahl, fill = Einstellung)) +
  geom_bar(stat = "identity") +
  geom_text(aes(y = pos, label = label), size = 4) +
  coord_flip() +
  facet_wrap(vars(System), ncol = 1, scales = "free_y") +
  scale_x_discrete(expand = c(0, 0)) +            # make bar "fuller"
  scale_y_continuous(expand = c(0, 0)) +          # make bar "fuller"
  scale_fill_manual(values = cbPalette) +
  ggtitle("Werden Sie sich für die Alternative entscheiden?", 
          subtitle = "2000 Männer befragt") + 
  theme(panel.background = element_blank(),
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        axis.title.y = element_blank(),
        aspect.ratio = .3,
        axis.text.y = element_blank(),
        axis.ticks.y = element_blank(),
        strip.background = element_rect(fill = NA),# remove facet strip background
        strip.text = element_text(hjust = 0)       # left align the facet strip text
        )

enter image description here

Upvotes: 4

Allan Cameron
Allan Cameron

Reputation: 173803

You would need to do this by removing the axis text and adding custom labels with geom_text

ggplot(data3, aes(x = factor(System), y = Anzahl, fill = Einstellung)) +
  geom_bar(stat = "identity", width = .3) +
  geom_text(aes(y = pos, label = label), size = 4) +
  geom_text(aes(y = 0, label = System, x = factor(System)), size = 5,
            hjust = 0, nudge_x = 0.3, check_overlap = TRUE) +
  theme(panel.background = element_blank(),
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        axis.title.y = element_blank(),
        aspect.ratio = .3) +
  scale_fill_manual(values=cbPalette)+
  coord_flip()+
  ggtitle("Werden Sie sich für die Alternative entscheiden?", 
          subtitle = "2000 Männer befragt") + 
  labs(x = NULL) +
  theme(axis.text.y = element_blank(),
        axis.ticks.y = element_blank())

enter image description here

Upvotes: 5

Related Questions