我是 R 的新手,并且设法在 ggplot 中制作了一个多线图。沿着 x 轴,我有 5 个时间点,它们是离散度量。我想要虚线的后半部分(见附图),有人可以帮我编辑我当前的代码来实现这一点吗?任何帮助将不胜感激。先感谢您!

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)
Run Code Online (Sandbox Code Playgroud)
这是一个建议的方法。建议您发布您的数据集或示例数据集以供将来提出问题,以便更轻松地为您的问题提供解决方案。粘贴 的输出dput(your.data.frame)是在此处共享数据框的最佳方式之一。
话虽如此,这是一个示例数据集。我们将用它画一个线图。
df <- data.frame(x=1:10, y=1:10)
p <- ggplot(df, aes(x,y)) + theme_bw()
p + geom_line()
Run Code Online (Sandbox Code Playgroud)
真的很棒。假设您想分割那条线,使其在 x=5 之后成为虚线,在 x=5 之前成为实线。您可以:
在数据集中创建另一列,并映射该linetype列上的美学(这是首选选项),或
设置内嵌语句以映射linetype. 不太受欢迎,但也有效。
我们将做上面的#2,因为它足够简单。这样的事情可以工作:
p + geom_line(aes(linetype=eval(x>5)))
Run Code Online (Sandbox Code Playgroud)
废话。它“有效”,但你现在有一个差距。 ggplot正在绘制点之间的线,所以如果一个点包含在一个集合中,它就不在另一个集合中。我在 x=1 和 x=4 之间画了一条实线,然后在 x=5 和 x=10 之间画了一条虚线。我们希望它在 x=1 和 x=5 之间画一条实线,然后在 x=5 和 x=10 之间画一条虚线。你现在看到问题了吗? 我们需要将 x=5 包含在两个集合中。
这里的解决方案是我们需要两次调用geom_line. 可能还有另一种方式,但这是我的方式:
p + geom_line(data=subset(df, x<=5), linetype=1) +
geom_line(data=subset(df, x>=5), linetype=2)
Run Code Online (Sandbox Code Playgroud)
那奏效了。现在,如果要添加带有一些标签的图例,则需要将“我想为线型添加图例”指定为ggplot. 您可以通过linetype=在aes()每个geom_line调用中包含内来做到这一点。然后,您可以通过 手动指定该图例的各个方面scale_linetype_manual。像这样:
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))
Run Code Online (Sandbox Code Playgroud)
在你的笔记之后,我也会在他们的回复中加入u/jpsmith包含的内容,这是如何处理非数字 x 轴。正如@jpsmith 指出的,你需要在stat_summary那里使用,因为geom_line如果你尝试使用它会抱怨。首先确保您的 x 轴值是一个因子,然后提取levels(longdata$Time). 您可能首先想确定levels(longdata$Time)顺序是否正确,但从您显示的图中可以看出它是正确的。然后为每种类型的线准备包含点可能是值得的,确保在两个集合中都包含“Post”:
solid.line.points <- c('Pre', 'Mid', 'Post')
dashed.line.points <- c('Post', 'Mid.detraining', 'Post.detraining')
Run Code Online (Sandbox Code Playgroud)
然后,使用stat_summary,类似于@jpsmith 发布的内容。但请注意一些关键更改,适用于您的情况:
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'))
Run Code Online (Sandbox Code Playgroud)
您需要应用group=美学,我相信您在longdata数据集中使用的组在这里可能不起作用……或者可能,不确定。这就是为什么我建议在两个stat_summary调用中覆盖美学并group=为每个调用指定。如果您在绘制线条时遇到问题,您可能必须指定group=1一个和group=2另一个(我没有尝试过,因为我没有您的数据集)。 有关使用geom_line离散 x 轴的一些说明以及有关group=美学的说明,请参阅 SO 中关于此问题的答案。
另请注意,我设置了fun=mean. 我假设你在mean你的一组点之间绘制一条线......但你最好知道你想在那里绘制什么以确保你映射正确的 y 值。