用额外的刻度和标签注释 ggplot
Annotate ggplot with an extra tick and label
你能帮我注释一个ggplot2散点图吗?
到典型的散点图(黑色):
df <- data.frame(x=seq(1:100), y=sort(rexp(100, 2), decreasing = T))
ggplot(df, aes(x=x, y=y)) + geom_point()
我想以额外勾号和自定义标签(红色)的形式添加注释:
示例图片:
以下内容将为您提供 xyz 标签及其上方的一条线,您可能需要调整 x 和 y 位置才能将其准确地放在您想要的位置。
ggplot(df, aes(x=x, y=y)) + geom_point() + annotate(x=27, y=0, label="xyz", color="red") +annotate(x=27, ymin=-1, ymax=1, color="red")
更多信息 here 如果需要。
四种解法。
首先使用 scale_x_continuous
添加附加元素,然后使用 theme
自定义新文本和刻度线(加上一些额外的调整)。
第二个使用 annotate_custom
创建新的 grob:文本 grob 和行 grob。 grob 的位置在数据坐标中。结果是,如果 y-axis 的限制发生变化,则 grob 的定位也会发生变化。因此,y-axis 在下面的示例中是固定的。此外,annotation_custom
正试图在绘图面板之外绘图。默认情况下,绘图面板的裁剪处于打开状态。它需要被关闭。
第三个是第二个的变体(并借鉴了 中的代码)。 grobs 的默认坐标系是 'npc',因此在构建 grobs 时将 grobs 垂直定位。使用 annotation_custom
的 grobs 定位使用数据坐标,因此将 grobs 水平定位在 annotation_custom
中。因此,与第二种解决方案不同,该解决方案中 grobs 的定位与 y 值的范围无关。
第四个使用viewports
。它建立了一个更方便的单位系统来定位文本和刻度线。 x方向,位置使用数据坐标;在 y 方向,位置使用 "npc" 坐标。因此,在这个解决方案中,grobs 的定位也独立于 y 值的范围。
第一个解
## scale_x_continuous then adjust colour for additional element
## in the x-axis text and ticks
library(ggplot2)
df <- data.frame(x=seq(1:100), y=sort(rexp(100, 2), decreasing = T))
p = ggplot(df, aes(x=x, y=y)) + geom_point() +
scale_x_continuous(breaks = c(0,25,30,50,75,100), labels = c("0","25","xyz","50","75","100")) +
theme(axis.text.x = element_text(color = c("black", "black", "red", "black", "black", "black")),
axis.ticks.x = element_line(color = c("black", "black", "red", "black", "black", "black"),
size = c(.5,.5,1,.5,.5,.5)))
# y-axis to match x-axis
p = p + theme(axis.text.y = element_text(color = "black"),
axis.ticks.y = element_line(color = "black"))
# Remove the extra grid line
p = p + theme(panel.grid.minor = element_blank(),
panel.grid.major.x = element_line(color = c("white", "white", NA, "white", "white", "white")))
p
第二种解法
## annotation_custom then turn off clipping
library(ggplot2)
library(grid)
df <- data.frame(x=seq(1:100), y=sort(rexp(100, 2), decreasing = T))
p = ggplot(df, aes(x=x, y=y)) + geom_point() +
scale_y_continuous(limits = c(0, 4)) +
annotation_custom(textGrob("xyz", gp = gpar(col = "red")),
xmin=30, xmax=30,ymin=-.4, ymax=-.4) +
annotation_custom(segmentsGrob(gp = gpar(col = "red", lwd = 2)),
xmin=30, xmax=30,ymin=-.25, ymax=-.15)
g = ggplotGrob(p)
g$layout$clip[g$layout$name=="panel"] <- "off"
grid.draw(g)
第三个解决方案
library(ggplot2)
library(grid)
df <- data.frame(x=seq(1:100), y=sort(rexp(100, 2), decreasing = T))
p = ggplot(df, aes(x=x, y=y)) + geom_point()
gtext = textGrob("xyz", y = -.05, gp = gpar(col = "red"))
gline = linesGrob(y = c(-.02, .02), gp = gpar(col = "red", lwd = 2))
p = p + annotation_custom(gtext, xmin=30, xmax=30, ymin=-Inf, ymax=Inf) +
annotation_custom(gline, xmin=30, xmax=30, ymin=-Inf, ymax=Inf)
g = ggplotGrob(p)
g$layout$clip[g$layout$name=="panel"] <- "off"
grid.draw(g)
第四种解法
更新到 ggplot2 v3.0.0
## Viewports
library(ggplot2)
library(grid)
df <- data.frame(x=seq(1:100), y=sort(rexp(100, 2), decreasing = T))
(p = ggplot(df, aes(x=x, y=y)) + geom_point())
# Search for the plot panel using regular expressions
Tree = as.character(current.vpTree())
pos = gregexpr("\[panel.*?\]", Tree)
match = unlist(regmatches(Tree, pos))
match = gsub("^\[(panel.*?)\]$", "\1", match) # remove square brackets
downViewport(match)
#######
# Or find the plot panel yourself
# current.vpTree() # Find the plot panel
# downViewport("panel.6-4-6-4")
#####
# Get the limits of the ggplot's x-scale, including the expansion.
x.axis.limits = ggplot_build(p)$layout$panel_params[[1]][["x.range"]]
# Set up units in the plot panel so that the x-axis units are, in effect, "native",
# but y-axis units are, in effect, "npc".
pushViewport(dataViewport(yscale = c(0, 1), xscale = x.axis.limits, clip = "off"))
grid.text("xyz", x = 30, y = -.05, just = "center", gp = gpar(col = "red"), default.units = "native")
grid.lines(x = 30, y = c(.02, -.02), gp = gpar(col = "red", lwd = 2), default.units = "native")
upViewport(0)
你能帮我注释一个ggplot2散点图吗?
到典型的散点图(黑色):
df <- data.frame(x=seq(1:100), y=sort(rexp(100, 2), decreasing = T))
ggplot(df, aes(x=x, y=y)) + geom_point()
我想以额外勾号和自定义标签(红色)的形式添加注释:
示例图片:
以下内容将为您提供 xyz 标签及其上方的一条线,您可能需要调整 x 和 y 位置才能将其准确地放在您想要的位置。
ggplot(df, aes(x=x, y=y)) + geom_point() + annotate(x=27, y=0, label="xyz", color="red") +annotate(x=27, ymin=-1, ymax=1, color="red")
更多信息 here 如果需要。
四种解法。
首先使用 scale_x_continuous
添加附加元素,然后使用 theme
自定义新文本和刻度线(加上一些额外的调整)。
第二个使用 annotate_custom
创建新的 grob:文本 grob 和行 grob。 grob 的位置在数据坐标中。结果是,如果 y-axis 的限制发生变化,则 grob 的定位也会发生变化。因此,y-axis 在下面的示例中是固定的。此外,annotation_custom
正试图在绘图面板之外绘图。默认情况下,绘图面板的裁剪处于打开状态。它需要被关闭。
第三个是第二个的变体(并借鉴了 annotation_custom
的 grobs 定位使用数据坐标,因此将 grobs 水平定位在 annotation_custom
中。因此,与第二种解决方案不同,该解决方案中 grobs 的定位与 y 值的范围无关。
第四个使用viewports
。它建立了一个更方便的单位系统来定位文本和刻度线。 x方向,位置使用数据坐标;在 y 方向,位置使用 "npc" 坐标。因此,在这个解决方案中,grobs 的定位也独立于 y 值的范围。
第一个解
## scale_x_continuous then adjust colour for additional element
## in the x-axis text and ticks
library(ggplot2)
df <- data.frame(x=seq(1:100), y=sort(rexp(100, 2), decreasing = T))
p = ggplot(df, aes(x=x, y=y)) + geom_point() +
scale_x_continuous(breaks = c(0,25,30,50,75,100), labels = c("0","25","xyz","50","75","100")) +
theme(axis.text.x = element_text(color = c("black", "black", "red", "black", "black", "black")),
axis.ticks.x = element_line(color = c("black", "black", "red", "black", "black", "black"),
size = c(.5,.5,1,.5,.5,.5)))
# y-axis to match x-axis
p = p + theme(axis.text.y = element_text(color = "black"),
axis.ticks.y = element_line(color = "black"))
# Remove the extra grid line
p = p + theme(panel.grid.minor = element_blank(),
panel.grid.major.x = element_line(color = c("white", "white", NA, "white", "white", "white")))
p
第二种解法
## annotation_custom then turn off clipping
library(ggplot2)
library(grid)
df <- data.frame(x=seq(1:100), y=sort(rexp(100, 2), decreasing = T))
p = ggplot(df, aes(x=x, y=y)) + geom_point() +
scale_y_continuous(limits = c(0, 4)) +
annotation_custom(textGrob("xyz", gp = gpar(col = "red")),
xmin=30, xmax=30,ymin=-.4, ymax=-.4) +
annotation_custom(segmentsGrob(gp = gpar(col = "red", lwd = 2)),
xmin=30, xmax=30,ymin=-.25, ymax=-.15)
g = ggplotGrob(p)
g$layout$clip[g$layout$name=="panel"] <- "off"
grid.draw(g)
第三个解决方案
library(ggplot2)
library(grid)
df <- data.frame(x=seq(1:100), y=sort(rexp(100, 2), decreasing = T))
p = ggplot(df, aes(x=x, y=y)) + geom_point()
gtext = textGrob("xyz", y = -.05, gp = gpar(col = "red"))
gline = linesGrob(y = c(-.02, .02), gp = gpar(col = "red", lwd = 2))
p = p + annotation_custom(gtext, xmin=30, xmax=30, ymin=-Inf, ymax=Inf) +
annotation_custom(gline, xmin=30, xmax=30, ymin=-Inf, ymax=Inf)
g = ggplotGrob(p)
g$layout$clip[g$layout$name=="panel"] <- "off"
grid.draw(g)
第四种解法
更新到 ggplot2 v3.0.0
## Viewports
library(ggplot2)
library(grid)
df <- data.frame(x=seq(1:100), y=sort(rexp(100, 2), decreasing = T))
(p = ggplot(df, aes(x=x, y=y)) + geom_point())
# Search for the plot panel using regular expressions
Tree = as.character(current.vpTree())
pos = gregexpr("\[panel.*?\]", Tree)
match = unlist(regmatches(Tree, pos))
match = gsub("^\[(panel.*?)\]$", "\1", match) # remove square brackets
downViewport(match)
#######
# Or find the plot panel yourself
# current.vpTree() # Find the plot panel
# downViewport("panel.6-4-6-4")
#####
# Get the limits of the ggplot's x-scale, including the expansion.
x.axis.limits = ggplot_build(p)$layout$panel_params[[1]][["x.range"]]
# Set up units in the plot panel so that the x-axis units are, in effect, "native",
# but y-axis units are, in effect, "npc".
pushViewport(dataViewport(yscale = c(0, 1), xscale = x.axis.limits, clip = "off"))
grid.text("xyz", x = 30, y = -.05, just = "center", gp = gpar(col = "red"), default.units = "native")
grid.lines(x = 30, y = c(.02, -.02), gp = gpar(col = "red", lwd = 2), default.units = "native")
upViewport(0)