I am new to R and have managed to make a multiple line figure in ggplot. Along the x axis I have 5 time points that are discrete measures. I would like the latter half of the lineplot to be dashed (see attached image), could anybody help me edit my current code to achieve this please? Any help would be greatly appreciated. Thank you in advance!
ggplot(longdata, aes(x = Time, y = Strength, colour = Group)) +
stat_summary(fun = mean,
geom = "point",)+
stat_summary(fun = mean,
geom = "line",
aes(group = Group), size =1,
show.legend = FALSE) +
geom = "errorbar",
width = .1, alpha = 0.3) +
xlab("Testing Timepoint") +
ylab("Isometric Strength (N.m)") +
bbtheme +
scale_colour_manual(name = "Group",
labels = c("Once-weekly", "Twice-weekly"),
values = c("red1", "navyblue")) +
expand_limits(y = 0)
here is a suggested approach. It is suggested you post your dataset or an example dataset for future questions to make it easier to provide a solution to your question. Pasting the output of dput(your.data.frame)
is one of the best ways to share a data frame here.
With that being said, here's an example dataset. We'll draw a line plot with it.
df <- data.frame(x=1:10, y=1:10)
p <- ggplot(df, aes(x,y)) + theme_bw()
p + geom_line()
Truly amazing. Let's say you want to split that line so that it's a dotted line after x=5, and solid before x=5. You can either:
Make another column in the dataset, and map the aesthetics of linetype
on that column (this is the preferred option), or
Set a statement in-line to map the aesthetics of linetype
. Less preferred, but also works.
We'll do #2 above, since it's straightforward enough. Something like this can work:
p + geom_line(aes(linetype=eval(x>5)))
Crap. It "worked", but you now have a gap. ggplot
is plotting the line between points, so if a point is included in one set it's not in another. I drew a solid line between x=1 and x=4, then a dotted line between x=5 and x=10. We wanted it to draw a solid line between x=1 and x=5 and then a dotted line between x=5 and x=10. You see the problem now? We needed x=5 to be included in both sets.
The solution here is that we need two calls to geom_line
. There might be another way, but this is the way I would do it:
p + geom_line(data=subset(df, x<=5), linetype=1) +
geom_line(data=subset(df, x>=5), linetype=2)
That worked. Now if you want to add a legend with some labels, you need to specify "I want to add a legend for linetype" to ggplot
. You do that by including linetype=
within aes()
for each of the geom_line
calls. You can then specify aspects of that legend manually through scale_linetype_manual
. Like this:
p + geom_line(data=subset(df, x<=5), aes(linetype='solid line')) +
geom_line(data=subset(df, x>=5), aes(linetype='dotted line')) +
scale_linetype_manual('type of line', values=c(2,1))
After your note, I'll incorporate what u/jpsmith included in their response here too, which is how to deal with non-numeric x axes. As @jpsmith indicated, you need to use stat_summary
there, since geom_line
will complain if you attempt to use it instead. Ensure that your x-axis values are a factor first, then extract levels(longdata$Time)
. You may first want to be sure levels(longdata$Time)
is in the correct order, but it appears from the plot you show that it is. It may then be worthwhile to prepare the inclusion points for each type of line, being sure to include "Post" in both sets:
solid.line.points <- c('Pre', 'Mid', 'Post')
dashed.line.points <- c('Post', 'Mid.detraining', 'Post.detraining')
Then, using stat_summary
, something like as @jpsmith posted. Note some key changes though, as applied to your case:
stat_summary(data=subset(df,Time %in% solid.line.points),
fun=mean, geom="line",
inherit.aes=FALSE, aes(x=Time, y=Strength, linetype='solid line')) +
stat_summary(data=subset(df,Time %in% dashed.line.points),
fun=mean, geom="line",
inherit.aes=FALSE, aes(x=Time, y=Strength, linetype='dashed line'))
You need to apply a group=
aesthetic, and I believe the group you use in your longdata
dataset may not work here... or it might, not sure. This is why I suggest overriding the aesthetics in both stat_summary
calls and specifying group=
for each one. If you get issues drawing the lines, you may have to specify group=1
for one and group=2
for another (I have not tried it, since I don't have your dataset). See the answer on this question in SO for some notes on using geom_line
with a discrete x axis and the note about the group=
aesthetic.
Also note that I set fun=mean
. I am assuming you are plotting a line between the mean
of your set of points... but you would better know what you want to plot there to ensure you map the correct y values.
Building off of what @chemdork123 proposed, but accounting for your non-numeric X axis, you could use stat_summary (you also need to add a group=1
in the aes()
.
library(ggplot2)
df <- data.frame(x=LETTERS[1:10], y=1:10)
ggplot(df, aes(x,y, group=1)) +
stat_summary(data=subset(df,x %in% c("E","F","G","H","I","J")), fun.y=sum, geom="line", aes(linetype='solid line')) +
stat_summary(data=subset(df,x %in% c("A","B","C","D","E")), fun.y=sum, geom="line", aes(linetype='dashed line'))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With