mikejwilliamson
mikejwilliamson

Reputation: 35

Adding text to axis labels in ggplot

I have plotted a graph from the following table.

        BoatPhs      fit        se    lower    upper
1         Before 3.685875 0.3287521 3.038621 4.333130
2   After0-20NTA 3.317189 0.6254079 2.085872 4.548506
3   After0-20TAA 5.579384 0.5696270 4.457890 6.700878
4   After0-20TAP 3.932360 0.4304098 3.084960 4.779760
5  After20-40NTA 4.522714 0.7771793 2.992586 6.052842
6  After20-40TAA 4.505207 0.5500699 3.422217 5.588196
7  After20-40TAP 3.602183 0.3880538 2.838174 4.366192
8    ApproachNTA 4.039599 0.5688482 2.919638 5.159560
9    ApproachTAA 4.421112 0.5176408 3.401969 5.440255
10   ApproachTAP 4.497809 0.3978328 3.714547 5.281071

The boat phase is the x axis and fit is plotted on the y. At the moment I have the axis ticks as Before, ApproachNTA, ApproachTAA, ApproachTAP, After0-20NTA etc.

I initially rotated these labels by 90 degrees so they were better to see, but didn't like the look of it. I've currently renamed the labels (using the code below) so that what is now displayed on the axis ticks is "Before NTA TAA TAP NTA TAA TAP NTA TAA TAP" on the x axis.

I was hoping to add some text in order to group the labels. Such as "Approach" under the first group of NTA TAA TAP, "After0-20" under the second and "After20-40" under the third, but I'm not sure how to do it outside of the plot. Tried with the annotate function but it only allows text within the plot area.

Any help would be much appreciated.

Cheers

# Speed plot
Spdplot <- ggplot(y, aes(x=BoatPhs, y=fit, colour=BP, ymax=max(fit)*1.05)) + 
  geom_point(position = position_dodge(width = 0.5, height = 0), size = 4) + 
  geom_errorbar(aes(ymin=fit-se, ymax=fit+se), position = position_dodge(width = 0.5, height = 0), width = 0.5, size = 0.75) +
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), 
        panel.background = element_blank(), axis.line = element_line(colour = "black"))


  #run Spdplot
Spdplot




#sets x values in results order + relables x + y axes
Spdplot + scale_x_discrete(limits=c("Before","ApproachNTA","ApproachTAA","ApproachTAP","After0-20NTA","After0-20TAA","After0-20TAP", "After20-40NTA","After20-40TAA","After20-40TAP"),
                           labels=c("Before" = "Before" ,"ApproachNTA"  ="NTA","ApproachTAA" = "TAA","ApproachTAP" = "TAP",
                                    "After0-20NTA" = "NTA","After0-20TAA" = "TAA","After0-20TAP" = "TAP",
                                    "After20-40NTA" = "NTA","After20-40TAA" = "TAA","After20-40TAP" = "TAP")) + 
  xlab("Boat phase") + ylab("Group travel speed (km/hr)") + 
  annotate("text", x=6, y=6.2, label="***", size = 6) +
  annotate("text", x=4, y=4.95, label="*", size = 6) + 
  theme(axis.title.x = element_text(face="bold", size = 16, vjust= -0.5), axis.title.y = element_text(face="bold", size = 16, vjust= 1), 
        axis.text.x = element_text(size=14, face="bold"), axis.text.y = element_text(face="bold", size=14), legend.text=element_text(size=14)) +
  theme(legend.title = element_blank()) + 
  scale_colour_manual(values=c("#3399FF","#FF0000","#33CC33","#000000"), 
                      breaks=c("Before", "Approach", "After0-20", "After20-40"),
                      labels=c("Before", "Approach", "After0-20", "After20-40"))

enter image description here

Upvotes: 3

Views: 7905

Answers (1)

nograpes
nograpes

Reputation: 18323

A lot of the fussing around you are doing with annotate and the manual labeling in scale_x_discrete can be avoided if you give ggplot the data it needs. Here I recreate your dataset, and then add the essential pieces of information for your plot.

# Recreate your data
y <- read.table(textConnection('BoatPhs      fit        se    lower    upper
1         Before 3.685875 0.3287521 3.038621 4.333130
2   After0-20NTA 3.317189 0.6254079 2.085872 4.548506
3   After0-20TAA 5.579384 0.5696270 4.457890 6.700878
4   After0-20TAP 3.932360 0.4304098 3.084960 4.779760
5  After20-40NTA 4.522714 0.7771793 2.992586 6.052842
6  After20-40TAA 4.505207 0.5500699 3.422217 5.588196
7  After20-40TAP 3.602183 0.3880538 2.838174 4.366192
8    ApproachNTA 4.039599 0.5688482 2.919638 5.159560
9    ApproachTAA 4.421112 0.5176408 3.401969 5.440255
10   ApproachTAP 4.497809 0.3978328 3.714547 5.281071'))

# Separate the boat phase from the time period     
y$boat.phase <- gsub('.*(NTA|TAA|TAP)','\\1',y$BoatPhs)
y$period <- gsub('(.*)(NTA|TAA|TAP)','\\1',y$BoatPhs)

# Give the time period an ordering.
y$period <- factor(y$period, 
                   levels = c("Before", "Approach", "After0-20", "After20-40"), 
                   ordered=TRUE)

# Add the stars manually, but these could be calculated programatically.
y$stars <- c('', '', '***', '', '', '', '', '', '', '*')

Now when you use ggplot, you can pass the stars as aesthetics, and you won't have to label anything manually. To "group" your x axis labels, you can use facets:

ggplot(y, aes(x=boat.phase, y=fit, ymax=fit+se, ymin=fit-se)) + 
  geom_point() + geom_errorbar(width = 0.5, size = 0.75) + 
  geom_text(aes(y=fit+se+0.1, label=stars), size=6) +
  facet_grid( ~ period, scales="free_x", space="free_x") +
  xlab("Boat phase") + ylab("Group travel speed (km/hr)") + 
  theme_bw()

enter image description here

Colouring would be redundant here, but if you like it is possible to add it in. I also add in your custom theme in the next example.

ggplot(y, aes(x=boat.phase, y=fit, ymax=fit+se, ymin=fit-se, colour=period)) + 
  geom_point() + geom_errorbar(width = 0.5, size = 0.75) + 
  geom_text(aes(y=fit+se+0.1, label=stars), size=6) +
  facet_grid( ~ period, scales="free_x", space="free_x") +
  xlab("Boat phase") + ylab("Group travel speed (km/hr)") + 
  scale_colour_manual(values=c("#000000", "#33CC33", "#3399FF","#FF0000")) +
  theme(axis.title = element_text(face="bold", size = 16),
        axis.title.x = element_text(vjust= -0.5), 
        axis.title.y = element_text(vjust= 1), 
        axis.text = element_text(size=14, face="bold"),
        panel.grid = element_blank(), 
        panel.background = element_blank(), 
        axis.line = element_line(colour = "black"))  

enter image description here

Upvotes: 6

Related Questions