我想知道是否有人可以帮我在R中用多个箭头绘制线条,如下所示:
---> ---> ---> --->
提前致谢!
答案 0 :(得分:5)
基于对原始问题的澄清,我认为应该考虑一般性答案
计算由(x,y)点指定的断裂曲线的总长度
分开中间段以确保箭头之间的曲线长度相等
处理细微的细节,例如初始“阶段”,终点,箭头是否应该跟着一个薄的空间等等。
下面粗略地抨击它。
arrowLine <- function(x, y, N=10, ...){
lengths <- c(0, sqrt(diff(x)^2 + diff(y)^2))
l <- cumsum(lengths)
tl <- l[length(l)]
el <- seq(0, to=tl, length=N+1)[-1]
plot(x, y, t="l", ...)
for(ii in el){
int <- findInterval(ii, l)
xx <- x[int:(int+1)]
yy <- y[int:(int+1)]
## points(xx,yy, col="grey", cex=0.5)
dx <- diff(xx)
dy <- diff(yy)
new.length <- ii - l[int]
segment.length <- lengths[int+1]
ratio <- new.length / segment.length
xend <- x[int] + ratio * dx
yend <- y[int] + ratio * dy
points(xend,yend, col="white", pch=19)
arrows(x[int], y[int], xend, yend, length=0.1)
}
}
set.seed(123)
x = sort(c(0, runif(200, 0,2* pi), 2*pi))
y=sin(x)
arrowLine(x, y, N=20)
答案 1 :(得分:3)
有一种偷偷摸摸的方式可以做到这一点,而不必绘制一堆线段或箭头
从上面的x
和y
数据开始:
plot(x, y, t='l')
然后使用一些预制例程计算从x[1]
,y[1]
到x[2]
,y[2]
等的局部斜率。将斜率转换为以度为单位的角度,然后(调用斜率矢量angslopes
)
text(x, y, labels=">", srt=angslopes) # throws error
抱歉,这不起作用,因为据我所知,srt
必须是单个值。所以:
diflen <- length(x)-1
sapply(1:diflen, function(xind) text(x[xind+1], y[xind+1], labels='>', cex=2.5, srt=angslopes[xind]))
格子包中可能有更简单的方法。
这种方法具有美观的优点,允许您通过par(cex)
指定箭头大小以及颜色 - 可能与线条颜色不同,甚至沿曲线变化。
答案 2 :(得分:2)
正如约兰所说,arrows
x=cos( seq(0, pi, by=pi/8) )
y=sin( seq(0, pi, by=pi/8))
plot(1,1, ylim=range(y), xlim=range(x))
arrows(x[-length(x)],y[-length(y)], x[-1],y[-1])
如果要绘制具有相等长度规格的直线多箭头曲线,请使用此函数:
multarrows <- function(x0,y0, x1,y1,n_arr, ...) {x<- seq(x0,x1, length=n_arr+1)
y<-seq(y0,y1, length=n_arr+1)
arrows(x[-length(x)],y[-length(y)], x[-1],y[-1], ...) }
plot(0,0, xlim=c(0,2), ylim=c(0,11)); multarrows(0,0, 1,10, 10)
答案 3 :(得分:2)
Simulair to DWin这就是我提出的:
arrowLine <- function(x0,y0,x1,y1,nArrow=1,...)
{
lines(c(x0,x1),c(y0,y1),...)
Ax=seq(x0,x1,length=nArrow+1)
Ay=seq(y0,y1,length=nArrow+1)
for (i in 1:nArrow)
{
arrows(Ax[i],Ay[i],Ax[i+1],Ay[i+1],...)
}
}
基本上它与一行中的几个箭头重叠,但确实得到了所需的结果(我假设是直线):
plot(0:1,0:1)
arrowLine(0,0,1,1,4)
真正棘手的部分是让箭头到达点的边缘而不是中心。这需要吗?
答案 4 :(得分:1)
我想我会在这里添加一个基本的R解决方案,该解决方案会将箭头计算为分段。有创建新图或向现有图添加箭头的版本。较长的段分为较短的段:
add_arrows <- function(x, y, ...)
{
# Ensure equal lengthed vectors
min_len <- min(length(x), length(y))
x <- x[seq(min_len)]
y <- y[seq(min_len)]
# Calculate y:x ratio
yx_ratio <- 3*(max(y) - min(y)) / (max(x) - min(x))
# Create start and end points
x1 <- x[-length(x)]
y1 <- y[-length(y)]
x2 <- x[-1]
y2 <- y[-1]
# Length and angle of line segments
theta <- atan((y2 - y1)/(x2 - x1))
seg_lengths <- sqrt((x2 - x1)^2 + (y2 - y1)^2)
# Break long segments into shorter segments
long <- which(seg_lengths > (2 * min(seg_lengths)))
if(length(long) > 0)
{
n_segs <- floor(seg_lengths[long] / (1.5 * min(seg_lengths)))
for(i in seq_along(long))
{
xs <- x1[long[i]] + (0:n_segs[i]) * (x2[long[i]] - x1[long[i]]) / n_segs[i]
ys <- y1[long[i]] + (0:n_segs[i]) * (y2[long[i]] - y1[long[i]]) / n_segs[i]
x1 <- c(x1, xs[-length(xs)])
x2 <- c(x2, xs[-1])
y1 <- c(y1, ys[-length(ys)])
y2 <- c(y2, ys[-1])
theta <- c(theta, rep(theta[long[i]], length(xs) - 1))
}
x1 <- x1[-long]; x2 <- x2[-long]; y1 <- y1[-long]; y2 <- y2[-long];
theta <- theta[-long]
}
# Arrow head length and width
len <- sqrt((max(y) - min(y))^2 + (max(x) - min(x))^2)/ 20
wid <- len * 0.1
# Calculate arrow heads
zx <- x2 - len * cos(theta) * sign(x2 - x1)
zy <- y2 - len * sin(theta) * sign(x2 - x1)
ax1 <- zx + wid * sin(theta) * sign(x2 - x1)
ax2 <- zx - wid * sin(theta) * sign(x2 - x1)
ay1 <- zy - wid * cos(theta) * sign(x2 - x1) * yx_ratio
ay2 <- zy + wid * cos(theta) * sign(x2 - x1) * yx_ratio
df <- data.frame(x1 = x1 + 0.1 * (x2 - x1),
y1 = y1 + 0.1 * (y2 - y1),
x2 = x2 - 0.5 * len * cos(theta) * sign(x2 - x1),
y2 = y2 - 0.5 * len * sin(theta) * sign(x2 - x1),
ax1 = ax1, ay1 = ay1, ax2 = ax2, ay2 = ay2)
# Draw segments
segments(df$x1, df$y1, df$x2, df$y2, col = "red", lwd = 2)
segments(df$x2, df$y2, df$ax1, df$ay1, col = "red", lwd = 2)
segments(df$x2, df$y2, df$ax2, df$ay2, col = "red", lwd = 2)
}
这允许您绘制箭头作为绘制的基础:
plot_arrows <- function(x, y, ...)
{
plot(x, y, col = "white", ...)
add_arrows(x, y, ...)
}
所以现在您可以这样做:
set.seed(69)
x <- 1:10
y <- sample(10)
plot(x, y)
add_arrows(x, y)
由reprex package(v0.3.0)于2020-02-29创建