Reputation: 35
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"))
Upvotes: 3
Views: 7905
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()
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"))
Upvotes: 6