Reputation: 427
I am trying to add a customized legend that labels the horizontal lines in my plot. I need the legend to state the following and also needs to be positioned out of the way of the blue lines that are plotted:
Acceptance Criteria:
Red line: "FoS = 1"
Orange line: "Anchor Uplift"
Steelblue line: "FoS = 2"
Green line: "FoS = 2.5"
Here is my R code. Thanks so much!!
## Plot all Hs values
colfunc <- colorRampPalette(c("cyan", "blue"))
plotColors <- colfunc(length(unique(data$Wave.Height)))
# Initialize plot
plot1 <- ggplot(data = hedron_1kt_180deg_1ft, aes(Wind.Speed, Total.Force)) +
geom_line(color = plotColors[1], size = 1) + xlab("Wind Speed [knots]") + ylab("Total Force [MT]") + ggtitle("Current Speed 1 knot / Head Seas") +
scale_x_continuous(breaks = c(10,20,30,40,50,60,70)) + coord_cartesian(xlim = c(10,75)) + theme_bw(base_size = 20) +
annotate("text", x = 73.5, y = max(hedron_1kt_180deg_1ft$Total.Force), label = "1 ft", size = 6)
# Add all other lines
plot1 <- plot1 + geom_line(data = hedron_1kt_180deg_1.75ft, aes(Wind.Speed, Total.Force), color = plotColors[2], size = 1) +
annotate("text", x = 73.5, y = max(hedron_1kt_180deg_1.75ft$Total.Force), label = "1.75 ft", size = 6) +
geom_line(data = hedron_1kt_180deg_2.5ft, aes(Wind.Speed, Total.Force), color = plotColors[3], size = 1) +
annotate("text", x = 73.5, y = max(hedron_1kt_180deg_2.5ft$Total.Force), label = "2.5 ft", size = 6) +
geom_line(data = hedron_1kt_180deg_3.25ft, aes(Wind.Speed, Total.Force), color = plotColors[4], size = 1) +
annotate("text", x = 73.5, y = max(hedron_1kt_180deg_3.25ft$Total.Force), label = "3.25 ft", size = 6) +
geom_line(data = hedron_1kt_180deg_4ft, aes(Wind.Speed, Total.Force), color = plotColors[5], size = 1) +
annotate("text", x = 73.5, y = max(hedron_1kt_180deg_4ft$Total.Force), label = "4 ft", size = 6) +
geom_line(data = hedron_1kt_180deg_4.75ft, aes(Wind.Speed, Total.Force), color = plotColors[6], size = 1) +
annotate("text", x = 73.5, y = max(hedron_1kt_180deg_4.75ft$Total.Force), label = "4.75 ft", size = 6) +
geom_line(data = hedron_1kt_180deg_5.5ft, aes(Wind.Speed, Total.Force), color = plotColors[7], size = 1) +
annotate("text", x = 73.5, y = max(hedron_1kt_180deg_5.5ft$Total.Force), label = "5.5 ft", size = 6) +
geom_line(data = hedron_1kt_180deg_6.25ft, aes(Wind.Speed, Total.Force), color = plotColors[8], size = 1) +
annotate("text", x = 73.5, y = max(hedron_1kt_180deg_6.25ft$Total.Force), label = "6.25 ft", size = 6) +
geom_line(data = hedron_1kt_180deg_7ft, aes(Wind.Speed, Total.Force), color = plotColors[9], size = 1) +
annotate("text", x = 73.5, y = max(hedron_1kt_180deg_7ft$Total.Force), label = "7 ft", size = 6) +
geom_line(data = hedron_1kt_180deg_7.75ft, aes(Wind.Speed, Total.Force), color = plotColors[10], size = 1) +
annotate("text", x = 73.5, y = max(hedron_1kt_180deg_7.75ft$Total.Force), label = "7.75 ft", size = 6) +
geom_line(data = hedron_1kt_180deg_8.5ft, aes(Wind.Speed, Total.Force), color = plotColors[11], size = 1) +
annotate("text", x = 73.5, y = max(hedron_1kt_180deg_8.5ft$Total.Force), label = "8.5 ft", size = 6) +
geom_line(data = hedron_1kt_180deg_9.25ft, aes(Wind.Speed, Total.Force), color = plotColors[12], size = 1) +
annotate("text", x = 73.5, y = max(hedron_1kt_180deg_9.25ft$Total.Force), label = "9.25 ft", size = 6) +
geom_line(data = hedron_1kt_180deg_10ft, aes(Wind.Speed, Total.Force), color = plotColors[13], size = 1) +
annotate("text", x = 73.5, y = max(hedron_1kt_180deg_10ft$Total.Force), label = "10 ft", size = 6) +
geom_hline(yintercept = 506, color = "red", size = 1) + geom_hline(yintercept = 202, color = "lawngreen", size = 1) +
geom_hline(yintercept = 253, color = "steelblue", size = 1) + geom_hline(yintercept = 432, color = "orange", size = 1)
# Save plot
png(filename = "Hedron-WD=40ft-Heading=180deg-Uc=1knot.png", width = 800, height = 600)
plot1
dev.off()
Here is a link to sample data. You just need to change the working directory for the code to work
https://www.dropbox.com/s/htfm3h9s2rcajd4/Hedron%20and%20Arapaho%20Forces.csv?dl=0
Upvotes: 1
Views: 945
Reputation: 93811
You can create a plot like this with a lot less effort by putting your data frame in "long" format and then using aesthetic mappings to get the colors and legends.
You haven't provided sample data, so here's an example with fake data:
## Create some fake data
# Fake data
dat = do.call(rbind,
lapply(seq(1,10, length.out=8), function(i) {
data.frame(level=i, x=1:100, y= 1:100 + 10*i)
}))
# Fake criteria lines
dat2 = data.frame(yint = c(40, 60, 149, 180),
slope=c(-0.01,-0.05,-0.1, -0.08), Criteria=LETTERS[1:4])
library(dplyr)
ggplot() +
geom_line(data=dat, aes(x,y, group=level),
colour=rep(hcl(210,100,seq(20,90,length.out=8)), each=100)) +
geom_text(data=dat %>% group_by(level) %>% filter(x==max(x)),
aes(label=round(level,2), x=x+1, y=y), hjust=0) +
geom_abline(data=dat2, aes(intercept=yint, slope=slope, color=Criteria)) +
theme_bw() +
scale_color_manual(values=c("red","orange","green","purple"))
Here's what's going on the code above:
dat
contains the data we want to plot. dat2
contains the data for the criteria lines for which we want to have a legend. Note that the data are in "long" format. For example, in dat
the level
column tells us to which grouping the x
and y
values belong.
geom_line
plots the data. By setting group=level
we get a separate line for each value of level
with just one call to geom_line
. Normally, we'd also add color=level
inside aes
to get a different color for each line. However, we want a legend for just the criteria lines, so we need to map colors to the data lines "by hand". That's what colour=rep(hcl(210,100,seq(20,90,length.out=8)), each=100)
does (note that it's outside of aes
).
geom_text
places the value labels at the right end of each curve. Note that we filter the data so that we keep only right-most (x,y) value for each level
, and we use that to place the text right next to each line.
geom_abline
plots the Criteria
lines. We use color=Criteria
inside aes
so that that the Criteria
lines are plotted in different colors and we get a color legend.
Here's what the graph looks like:
UPDATE: Here's another example with the data you posted. I loaded your data file into a data frame called df
. It looks like you subsetted your data, and I think the subset below is the same as the one in your question. Hopefully, you'll be able to generalize the examples below to whichever subset(s) you wish to include:
# Subset data
df.sub = df %>% filter(Barge.Name=="Hedron",
Heading==180,
Current.Speed==1,
Water.Depth==40)
ggplot(data = df.sub,
aes(Wind.Speed, Total.Force, group=Wave.Height, color=Wave.Height)) +
geom_line(size = 1) +
geom_text(data=df.sub %>% filter(Wind.Speed==max(Wind.Speed)),
aes(label=Wave.Height, y=Total.Force, x=Wind.Speed + 0.5), hjust=0) +
theme_bw() +
guides(color=FALSE)
You can also use faceting to include more variables in the visualization:
df.sub = df %>% filter(Current.Speed==1,
Water.Depth==40)
ggplot(data = df.sub,
aes(Wind.Speed, Total.Force, group=Wave.Height, color=Wave.Height)) +
geom_line(size = 1) +
geom_text(data=df.sub %>% filter(Wind.Speed==max(Wind.Speed)),
aes(label=Wave.Height, y=Total.Force, x=Wind.Speed + 0.5), hjust=0) +
theme_bw() +
guides(color=FALSE) +
facet_grid(Barge.Name ~ Heading) +
scale_x_continuous(limits=c(10,78))
Upvotes: 1