r ggplot2 在单方面注释点范围和段

r ggplot2 annotate pointrange and segment in single facet

我正在用 ggplot 创建一个包含以下数据的 3 面图

library(ggplot2)

test<-as.data.frame(c(1,2,3,4,1,2,3,4,1,2,3,4))
colnames(test)<-"e12"
test$e23<-c(NaN,NaN,NaN,NaN,2,3,4,5,2,3,4,5)
test$e34<-c(NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,3,4,5,6)
test$Age<-c(1,2,3,4,1,2,3,4,1,2,3,4)
test$facet<-c(1,1,1,1,2,2,2,2,3,3,3,3)

ggplot(test, aes(x=Age)) + 
  facet_grid( ~ facet) +
  geom_line(aes(y = e12), size=0.25, colour="red", linetype="dashed") +
  geom_point(aes(y = e12), size=2.5, shape=21, fill="red", colour=NA) +
  geom_line(aes(y = e23), size=0.25, colour="blue", linetype="dashed") +
  geom_point(aes(y = e23), size=2.5, shape=21, fill="blue", colour=NA) +
  geom_line(aes(y = e34), size=0.25, colour="green", linetype="dashed") +
  geom_point(aes(y = e34), size=2.5, shape=21, fill="green", colour=NA) +
  annotate("pointrange", x=3.05, y=6.1, ymin=6.1, ymax=6.1, colour="red", size=0.5) +
  annotate("segment", x=2.8, xend=3.4, y=6.1, yend=6.1, colour="red", size=0.5, linetype="dashed") +
  annotate("text", x=3.6, y=6.1, parse=T, label="e[1%;%2]", size=3.1, family="Calibri", colour="black") +
  theme(strip.text = element_text(face="bold", size=rel(1)),
        strip.background = element_rect(fill="white", colour="white", size=1)) +
  scale_x_continuous(limits=c(0.5,4.5), breaks=seq(1, 4, 1), minor_breaks=seq(1, 4, 1), expand = c(0, 0)) + 
  scale_y_continuous(limits=c(0,6.5), breaks=seq(0, 6.5, 1), minor_breaks=seq(0,6.5,0.2), expand = c(0, 0))

然而,这带来了 2 个问题:

  1. 我希望注释(点范围、段和文本)只出现在一个方面。我已经看到如何创建一个数据框来仅在单个方面注释文本,但想知道这是否适用于段和点范围。

  2. 文本应为 e1;2,下标为 1;2 - 尽管将“;”在 plotmath 中导致错误。

要完全按照您的意愿制作绘图可能很困难,但通常最好不要过多地处理 ggplot 的细节。所以我可以告诉你如何制作下面的情节:

您使用 gpgplot 的方式不是(据我所知)打算使用的方式。您正在为要绘制的每一行编写命令。但 ggplot 的思想是将所有数据放入一个数据框中,然后将数据框中的列映射到图形元素。您可能会发现以下资源有帮助:ggplot2 page and Cookbook for R,您可以在其中找到大量使用 ggplot2 的好示例。

因此,第一步是准备数据,以便绘制绘图。假设 test 定义为您的示例,以下代码将适当地格式化数据:

library(reshape2)
plot.test <- melt(test,id=c("Age","facet"))
plot.test <- subset(plot.test,!is.na(value))

查看 plot.testmelt 的文档以更好地理解此步骤。第一行将数据放在不同的形状中。不是每条曲线一列(e_12、e_23、e_34),而是一列包含所有值和一列指示该值属于哪条曲线。然后第二行丢弃所有不需要的未定义值。

现在数据已经准备好了,可以制作如下图:

e.labs <- c(expression(e["1;2"]),expression(e["2;3"]),expression(e["3;4"]))

ggplot(plot.test,aes(x=Age,y=value,colour=variable)) +
  facet_grid(.~facet) +
  geom_line(size=0.25, linetype="dashed") + 
  geom_point(size=2.5) + 
  theme(strip.text = element_text(face="bold", size=rel(1)),
        strip.background = element_rect(fill="white", colour="white", size=1),
        legend.position=c(0.93,0.15)) +
  scale_colour_discrete(labels=e.labs)

如您所见,geom_linegeom_point 都只需要调用一次。数据映射在 ggplot 命令内部完成。它说变量 Age 应该用作 x-axis 和变量 value (其中包含来自原始数据框的列 e_12 等的数据)应该用作 y-axis。 variable 列表示数据是来自 e_12e_23 还是 e_34 列,用于设置不同的颜色。由于点和线的这些映射相同,因此可以在 ggplot() 中全局定义它们,而不是在 geom_ 函数中定义。

如果您正确使用 ggplot,即通过将列分配给图形 objects,将自动生成图例。该代码仅包含两个语句来自定义图例:scale_colour_discrete 用于更改图例中的标签,legend.position inside theme 用于根据您的要求在图上移动图例。

如果您还想用有意义的内容替换 y-axis 标签和图例标题,可以使用 labs 函数。只需将以下内容添加到您的绘图中

+ labs(y="my y label",colour="my legend title")

我懒得把你对 x- 和 y-axis 的自定义包括在内,因为你似乎已经知道如何做到这一点。