使用ggplot
,我想从segment
到另一个curve
绘制path
,point
或arrow
,其中包括df <- data.frame(x1=10, x2=5, y1=10, y2=5)
ggplot(df) +
geom_point(aes(x=x1, y=y1)) +
geom_point(aes(x=x2, y=y2)) +
geom_segment(aes(x=x1, y=y1, xend=x2, yend=y2),
arrow = arrow())
。我的问题是我想将线连接到点的“边缘”而不是中心,这样无论点的大小如何,箭头都是可见的。
例如,以下代码没问题:
ggplot(df) +
geom_point(aes(x=x1, y=y1)) +
geom_point(aes(x=x2, y=y2), size=20) +
geom_segment(aes(x=x1, y=y1, xend=x2, yend=y2),
arrow = arrow())
但是,如果我将这些点设得很大,那么箭头就会变得模糊不清:
size
如何调整线条,使箭头的尖端始终与点的边缘相交?
我已经尝试调整行终点的坐标,但SELECT *
FROM jsonb_array_elements_text($$["tag1","tag2","xtag1","ytag1"]$$::jsonb)
WHERE value LIKE 't%';
value
-------
tag1
tag2
(2 rows)
美学与坐标本身的比例不同(讨论here),因此很难知道如何更改以一般化的方式坐标。最相关的类似问题是this,但答案并不能解决我的问题。谢谢!
答案 0 :(得分:1)
就个人而言,我会寻求手动解决方案:
library(ggplot2)
plot.arr <- function(df, pointsiz=2, pointsiz.scale.factor=100){
## calculate weights to adjust for aspect ratio
norm2 <- function(v) sqrt(sum(v^2))
w <- c(diff(range(df[ ,c("x1","x2")])), diff(range(df[ ,c("y1","y2")])))
w <- w/norm2(w)
## use "elliptical" norm to account for different scales on x vs. y axes
norm2w <- function(v) sqrt(sum((v/w)^2))
## compute normalized direction vectors, using "elliptical" norm
direc <- do.call("rbind",lapply(1:nrow(df), function(i) {
vec <- with(df[i, ], c(dx=x2-x1, dy=y2-y1))
data.frame(as.list(vec/norm2w(vec)))
}))
## "shift back" endpoints:
## translate endpoints towards startpoints by a fixed length;
## translation direction is given by the normalized vectors;
## translation length is proportional to the overall size of the plot
## along both x and y directions
## pointsiz.scale.factor can be decreased/increased for larger/smaller pointsizes
epsil <- direc * diff(range(df)) / pointsiz.scale.factor
df$xend2 <- df$x2 - epsil$dx
df$yend2 <- df$y2 - epsil$dy
g <- ggplot(df) +
geom_point(aes(x=x1, y=y1), size=pointsiz) +
geom_point(aes(x=x2, y=y2), size=pointsiz) +
geom_segment(aes(x=x1, y=y1, xend=xend2, yend=yend2),
arrow = arrow())
print(g)
}
set.seed(124)
##n.arr <- 1
n.arr <- 3
df <- data.frame(x1=10+rnorm(n.arr,10,400),
x2=5 +rnorm(n.arr,1),
y1=10+rnorm(n.arr,0,5),
y2=5 +rnorm(n.arr,2))
plot.arr(df)
df <- data.frame(x1=10+rnorm(n.arr,1000,4000),
x2=5 +rnorm(n.arr,1),
y1=10+rnorm(n.arr,0,5),
y2=5 +rnorm(n.arr,2))
plot.arr(df)
df <- data.frame(x1=10+rnorm(n.arr,3,4),
x2=5 +rnorm(n.arr,1),
y1=10+rnorm(n.arr,0,5),
y2=5 +rnorm(n.arr,2))
plot.arr(df, pointsiz=4, pointsiz.scale.factor=50)
关于你在下面评论中的(优秀)问题:理想情况下,要正确地解决这个问题,可以执行嵌入在&#34;本地ggplot&#34;中的计算。设置,而不是明确的&#34;手册&#34;以上程序。这可能是可能的,但它需要更深层次的Paul-Murrell知识,我绝对不具备这些知识。具体来说:在上面的第三个图之后我尝试了
ggsave("test1.pdf", width=6, height=6)
ggsave("test2.pdf", width=16, height=6)
使用较大的宽度会产生拉伸箭头点和端点之间距离的副作用,因为三个箭头或多或少水平对齐;在目视检查pdf文件后,除了手动调整pointsiz.scale.factor
之外,我认为没有其他选择。唉,这绝对不是&#34;原生ggplot&#34;:它是蛮力的,后验的试错;然而,如果pdf的纵横比是预先确定的 - 新的纵横比需要新的试错法估计,它可以显示在线性个人时间内收敛。当使用更大的点数时,类似的评论仍然存在:为了找到箭头点和点边缘之间视觉上令人愉悦的距离,我认为除了反复试验之外别无选择。这是手工方法的局限......