Wokkel
Wokkel

Reputation: 339

Show class count in bar chart only when the bars are drawn

I would like to show the number of instances per bar in my geom_bar output. More specifically, if one bar is not showing (because its value = 0), the number of instances shouldn't be drawn as well. Using geom_text() doesn't get the job done, at least not with my line of code. Note that the posts of the stacked bar chart do not apply in this case.

Here's some data:

df <- data.frame(classes = rep(c("Class_A","Class_B","Class_C","Class_D"),
                               each=3),
                 clusters = rep(1:3),
                 score_1 = sample(0:4,4, replace = F), 
                 score_2 = sample(0:4,4, replace = F), 
                 score_3 = sample(0:4,4, replace = F), 
                 count = sample(1:200, 12,replace = T))

Here's some code I've been using so far

ggplot(df, aes(classes, score_1)) +
  geom_bar(stat = "identity", position =  position_dodge(width = 0.4), 
           aes(fill = clusters)) +
  labs(title = "Median per cluster of Score_1",
       x="some text", y=element_blank()) +
  theme_bw() + theme(text = element_text(size=10),
                     axis.text.x = element_text(angle=90, hjust=1)) +
  geom_text(aes(label = count))

And here's the output on the LHS while my desired result should look like the RHS. I don't care whether the text is in or above the bars.

LHS: Current output. RHS: Desired output.

Answer

As a final result, with the help from Grant, this is the final result:

ggplot(df, aes(classes, score_1)) +
  geom_bar(stat = "identity", position =  position_dodge(width = 0.4), 
           aes(fill = clusters)) +
  geom_text(aes(label = count2, group = clusters), position = position_dodge(width = 0.4), 
       vjust = -.08, hjust = 0.6, size = 3) +
  labs(title = "Median per cluster of Score_1",
       x="some text", y=element_blank()) +
  theme_bw() + theme(text = element_text(size=10),
       axis.text.x = element_text(angle=90, hjust=1))

By adding the group = clusters the position can be manipulated more effectively with hjust and vjust.

Upvotes: 0

Views: 156

Answers (1)

Grant
Grant

Reputation: 356

To not show the counts for bars of height 0, you can make a new column that's blank if the score_1 variable is 0 and display that in the graph.

df$count2 = ifelse(df$score_1 != 0, df$count, "")

To position the text nearer to the bars, you can use the same position argument of geom_text() that you did for geom_bar() (in this case position_dodge(width = 0.4)). Setting vjust to something like 2 will move it down a little too.

Here's my code for the graph:

ggplot(df, aes(classes, score_1)) + 
    geom_bar(stat = "identity", position = position_dodge(width = 0.4), aes(fill = factor(clusters))) + 
    geom_text(aes(label = count2), position = position_dodge2(0.4), vjust = 2) + 
    labs(title = "Median per cluster of Score_1", x="some text", y=element_blank()) + 
    theme_bw() + 
    theme(text = element_text(size=10), axis.text.x = element_text(angle=90, hjust=1)) 

I also had a little different output until I added changed it to fill = factor(clusters).

Here's a link to the graph (using slightly different data): Graph that omits labels when y = 0 and positions text with the bars.

Upvotes: 1

Related Questions