lelia
lelia

Reputation: 11

Positioning Text In A Middle Of A Bar In ggplo2

I'm trying to label the different bars on my graph using ggplot2, I'm really not sure where I'm going wrong. The code is:

#import data
data.ave <- Sheet_2_ave_but_data

library(ggplot2)
library(RColorBrewer)
library(colorRamps)

#change the categories so that they're correct
data.ave$butterfly.species <- as.factor(data.ave$butterfly.species)
data.ave$plant.species <- as.factor(data.ave$plant.species)
data.ave$ave.num.of.visits <- as.numeric(data.ave$ave.num.of.visits)
summary(data.ave)

colourCount <- length(unique(mtcars$hp)) 
getPalette <- colorRampPalette(brewer.pal(9, "Set1"))
c <- ggplot(data.ave,aes(x = plant.species, y = ave.num.of.visits))
c <- c + geom_bar(stat = "identity", aes(fill = butterfly.species))
c <- c + scale_fill_manual( values = getPalette(colourCount))
c <- c + geom_text(aes(label = butterfly.species), 
                   position = position_stack(vjust = 0.5), size = 2)
c <- c + scale_y_continuous( breaks=seq(0,50,10))
c

The labels are just on top of on another.

The graph:

Graph of number of visits of different butterfly species, to different plants

The data can be found on this google sheets: https://docs.google.com/spreadsheets/d/1ALmD-3CFGngcVYKxIImVdU0MIDLC0AYsq9MTIMJiMu0/edit?usp=sharing

Upvotes: 1

Views: 473

Answers (1)

Andy Baxter
Andy Baxter

Reputation: 7626

A first problem is that ggplot is reordering the butterfly.species names alphabetically to put in the legend, whilst position_stack is retaining the order in the dataframe. To fix this you can rearrange your data file before constructing the plot using dplyr's arrange function (descending order):

library(dplyr)
data.ave <- data.ave %>% arrange(desc(butterfly.species))

Secondly, as noted by Jordo82, you have a lot of overlapping text, much of it corresponding to 0 values. You could filter these out (again using dplyr), and it would give a slightly tidier graph:

c <- data.ave %>% filter(ave.num.of.visits != 0) %>% ggplot(aes(x = plant.species, y = ave.num.of.visits))
c <- c + geom_bar(stat = "identity", aes(fill = butterfly.species))
c <- c + scale_fill_manual( values = getPalette(colourCount))
c <- c + geom_text(aes(label = butterfly.species), position = position_stack(vjust = 0.5), size = 2)
c <- c + scale_y_continuous( breaks=seq(0,50,10))
c

Giving this graph:

Butterfly plot without 0 value labels

To move some labels from on top of each other, you could use ggrepel::geom_text_repel:

data.ave<- dplyr::arrange(data.ave, desc(butterfly.species))
c <- data.ave %>% filter(ave.num.of.visits != 0) %>% ggplot(aes(x = plant.species, y = ave.num.of.visits))
c <- c + geom_bar(stat = "identity", aes(fill = butterfly.species))
c <- c + scale_fill_manual( values = getPalette(colourCount))
c <- c + geom_text_repel(aes(label = butterfly.species), position = position_stack(vjust = 0.5), direction="y", hjust=0.5, size = 2, box.padding=0.1)
c <- c + scale_y_continuous( breaks=seq(0,50,10))
c

Resulting in:

Butterfly plot with geom_text_repel

You can add min.segment.length to geom_text_repel to add or remove lines pointing to each part of the stack. Hope that helps!

Upvotes: 2

Related Questions