这个问题还有其他变体,例如:
- R: place geom_text() relative to plot borders rather than fixed position on the plot
- ggplot2 annotate layer position in R
- Position ggplot text in each corner
在我看来,这些并不能解决一般问题。第一个简单地预先计算 x 和 y 范围,以便可以使用比例。后两个使用“技巧”,可以通过 +/- Inf
将文本定位在给定的角落。
我认为以下两项改进将有助于实现更通用的解决方案:
- 允许通过相对定位任意定位标签
- 适用于通过
dplyr
动态计算的变量(排除预先计算范围/比率)
示例数据:
data.frame(
x = runif(100, min = sample(0:50, 1), max = sample(50:1000, 1)),
y = runif(100, min = sample(0:1000, 1), max = sample(1000:10000, 1))
) %>%
mutate(z = x + y) %>%
# code here to plot and put an annotation at e.g. x = 0.95, y = 0.1, relative to plot limits
最佳答案
我今天一直在努力解决这个问题,并利用一些有关如何从 ggplot()
调用中访问数据的额外知识,对现有答案进行了可能的改进。
我发现(参见 1 和 2 ),通过将 ggplot 调用包含在 {}
中并传递 .
作为数据参数,可以继续在整个通话过程中引用 .
。这使得:
pos_x <- 0.95
pos_y <- 0.1
data.frame(
x = runif(100, min = sample(0:50, 1), max = sample(50:1000, 1)),
y = runif(100, min = sample(0:1000, 1), max = sample(1000:10000, 1))
) %>%
mutate(z = x + y) %>% {
ggplot(., aes(x = x, y = z)) + geom_point() +
annotate(geom = "text", label = "some label",
x = min(.$x) + pos_x * diff(range(.$x)),
y = min(.$z) + pos_y * diff(range(.$z)),
hjust = 1, vjust = 1) +
scale_x_continuous(limits = range(.$x)) +
scale_y_continuous(limits = range(.$z))
}
您可以重新运行它并观察绘图标签保持固定,即使 x/y 轴范围发生显着变化。对于一些改进机会:
- 轴下限随数据而变化,因此如果
min(.$y)
太高,仅使用y = number_close_to_zero*max(.$y)
可能存在风险高的。为此,我手动指定了轴限制 - 同样,由于这个原因,如果您只执行
pos_x_rel * max(.$x)
,则绘图之间的位置并不准确,因此我使用min(.$x) + diff (范围(.$x))
改为 hjust
和vjust
不是自动的;它们需要根据所需的标签位置进行调整- 如果能够自动获取用于 x/y 的变量,而不是必须使用列名称,那就太好了。换句话说,如果我想更改为
aes(..., y = y)
,我不必将.$z
的实例更改为.$y
.
关于ggplot中相对定位文本注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73575801/