我想将样本大小值与绘图上的点相关联。我可以使用
geom_text
将数字定位在点附近,但这很混乱。将它们沿着地块的外边缘排列起来会更干净。
例如,我有:
df=data.frame(y=c("cat1","cat2","cat3"),x=c(12,10,14),n=c(5,15,20))
ggplot(df,aes(x=x,y=y,label=n))+geom_point()+geom_text(size=8,hjust=-0.5)
产生这个图:
我更喜欢这样的东西:
我知道我可以创建第二个图并使用
grid.arrange
(就像这篇文章),但确定 textGrobs 的间距与 y 轴对齐会很乏味。有没有更简单的方法来做到这一点?谢谢!
这对于 ggplot2 3.0.0 现在很简单,因为现在可以通过在坐标函数(例如
clip = 'off'
或 coord_cartesian(clip = 'off')
)中使用 coord_fixed(clip = 'off')
参数来禁用绘图中的裁剪。下面是一个例子。
# Generate data
df <- data.frame(y=c("cat1","cat2","cat3"),
x=c(12,10,14),
n=c(5,15,20))
# Create the plot
ggplot(df,aes(x=x,y=y,label=n)) +
geom_point()+
geom_text(x = 14.25, # Set the position of the text to always be at '14.25'
hjust = 0,
size = 8) +
coord_cartesian(xlim = c(10, 14), # This focuses the x-axis on the range of interest
clip = 'off') + # This keeps the labels from disappearing
theme(plot.margin = unit(c(1,3,1,1), "lines")) # This widens the right margin
您不需要绘制第二幅图。您可以使用
annotation_custom
将对象定位在绘图区域内部或外部的任何位置。 grobs 的定位是根据数据坐标进行的。假设“5”、“10”、“15”与“cat1”、“cat2”、“cat3”对齐,则考虑了 textGrobs 的垂直定位 - 三个 textGrobs 的 y 坐标由三个数据点的 y 坐标。默认情况下,ggplot2
将对象剪切到绘图区域,但可以覆盖剪切。相关边际需要扩大,为暴徒腾出空间。以下(使用 ggplot2 0.9.2)给出了与第二个图类似的图:
library (ggplot2)
library(grid)
df=data.frame(y=c("cat1","cat2","cat3"),x=c(12,10,14),n=c(5,15,20))
p <- ggplot(df, aes(x,y)) + geom_point() + # Base plot
theme(plot.margin = unit(c(1,3,1,1), "lines")) # Make room for the grob
for (i in 1:length(df$n)) {
p <- p + annotation_custom(
grob = textGrob(label = df$n[i], hjust = 0, gp = gpar(cex = 1.5)),
ymin = df$y[i], # Vertical position of the textGrob
ymax = df$y[i],
xmin = 14.3, # Note: The grobs are positioned outside the plot area
xmax = 14.3)
}
# Code to override clipping
gt <- ggplot_gtable(ggplot_build(p))
gt$layout$clip[gt$layout$name == "panel"] <- "off"
grid.draw(gt)
基于
grid
的更简单解决方案
require(grid)
df = data.frame(y = c("cat1", "cat2", "cat3"), x = c(12, 10, 14), n = c(5, 15, 20))
p <- ggplot(df, aes(x, y)) + geom_point() + # Base plot
theme(plot.margin = unit(c(1, 3, 1, 1), "lines"))
p
grid.text("20", x = unit(0.91, "npc"), y = unit(0.80, "npc"))
grid.text("15", x = unit(0.91, "npc"), y = unit(0.56, "npc"))
grid.text("5", x = unit(0.91, "npc"), y = unit(0.31, "npc"))
另一种选择可以使用
annotate
中的 ggplot2
,这与使用 geom_text
几乎相同:
library(ggplot2)
df=data.frame(y=c("cat1","cat2","cat3"),x=c(12,10,14),n=c(5,15,20))
ggplot(df,aes(x=x,y=y)) +
geom_point() +
annotate("text", x = max(df$x) + 0.5, y = df$y, label = df$n, size = 8) +
coord_cartesian(xlim = c(min(df$x), max(df$x)), clip = "off") +
theme(plot.margin = unit(c(1,3,1,1), "lines"))
由 reprex 包于 2022 年 8 月 14 日创建(v2.0.1)
这个特定示例可能是 ggh4x::guide_axis_manual
的情况# remotes::install_github("teunbrand/ggh4x")
library(ggplot2)
df <- data.frame(y=c("cat1","cat2","cat3"), x=c(12,10,14), n=c(5,15,20))
ggplot(df, aes(x=x, y=y)) +
geom_point() +
guides(y.sec=ggh4x::guide_axis_manual(title = element_blank(), breaks = df$y, labels = paste0("n=",df$n)))
创建于 2023-08-24,使用 reprex v2.0.2
另一个选项在精神上与@bschneidr的方法类似,但仅使用普通
ggplot2
,即使用所谓的辅助轴技巧,这意味着使用辅助轴或重复轴来添加注释。
但是,在离散比例的情况下,这会稍微复杂一些,因为离散比例不允许使用辅助轴。因此,我们必须首先使用例如将离散 y 轴变量转换为数字来切换到连续尺度。
as.numeric(factor(...))
。
library(ggplot2)
df$y_num <- as.numeric(factor(df$y))
ggplot(df, aes(x = x, y = y_num, label = n)) +
geom_point() +
scale_y_continuous(
breaks = unique(df$y_num),
labels = df$y,
expand = c(0, .6),
sec.axis = dup_axis(
breaks = unique(df$y_num),
labels = paste0("n = ", df$n)
)
) +
theme(
axis.text.y.right = element_text(size = 8 * .pt),
axis.ticks.y.right = element_blank(),
axis.title.y.right = element_blank()
)