gpt4 book ai didi

r - 如何在不考虑线尺寸的情况下保持线型间距恒定

转载 作者:行者123 更新时间:2023-12-03 16:08:18 25 4
gpt4 key购买 nike

当大小不同时,我一直试图在ggplot2或grid中绘制线段间距相等的线。但是,我还没有成功,所以请您帮忙。
在下面的示例中,如何在线段大小不同的情况下使线段之间的绝对间距相等?
我想避免制作自定义的makeContent.myclass方法来自己控制。

library(ggplot2)
library(grid)

df <- data.frame(
x = c(1:2, 1:2),
y = c(1:2, 2:1),
size = c(1,1,10,10)
)

# In ggplot2
ggplot(df, aes(x, y, size = size, group = size)) +
geom_line(linetype = 2)

# In grid
lines <- polylineGrob(
x = scales::rescale(df$x),
y = scales::rescale(df$y),
id = c(1,1,2,2),
gp = gpar(lty = 2, lwd = c(1, 10))
)

grid.newpage(); grid.draw(lines)

我想要一些与以下插图画家创作的作品相似的作品。请注意,红色线段的长度相等。
enter image description here
有任何想法吗?谢谢阅读!

最佳答案

这可能不是您在寻找Teunbrand的目的,但我想您可以将线条转换为一系列沿线条等距分布的细多边形多边形。
此函数采用一系列x和y坐标,并返回虚线(作为单个treeGrob)。根据您的示例,它以归一化的npc坐标返回它。您可以完全控制线宽,划线长度和中断长度(尽管不是图案)以及颜色。恐怕这些单位有些随意,这与生产标准相差甚远,但这是相当有效的:

segmentify <- function(x, y, linewidth = 1, dash_len = 1, 
break_len = 1, col = "black")
{

linewidth <- 0.002 * linewidth
dash_len <- 0.01 * dash_len
break_len <- 0.04 * break_len

if(length(y) != length(x))
stop("x and y must be the same length")
if(!is.numeric(x) | !is.numeric(y))
stop("x and y must be numeric vectors")
if(length(x) < 2)
stop("Insufficient x, y pairs to make line.")

x <- scales::rescale(x)
y <- scales::rescale(y)

n_dashes <- 0
skip_len <- break_len + dash_len

df <- list()
for(i in seq_along(x)[-1])
{
x_diff <- x[i] - x[i - 1]
y_diff <- y[i] - y[i - 1]
seg_len <- sqrt(x_diff^2 + y_diff^2)
seg_prop <- skip_len / seg_len
dist_from_start <- n_dashes * skip_len
prop_start <- dist_from_start/seg_len
x_start <- x[i-1] + prop_start * x_diff
y_len <- y_diff * seg_prop
x_len <- x_diff * seg_prop
y_start <- y[i-1] + prop_start * y_diff
n_breaks <- (seg_len - dist_from_start)/skip_len
n_dashes <- (n_dashes + n_breaks) %% 1
n_breaks <- floor(n_breaks)

if(n_breaks)
{
df[[length( df) + 1]] <- data.frame(
x = seq(x_start, x[i], by = x_len),
y = seq(y_start, y[i], by = y_len)
)
df[[length( df)]]$theta <-
atan(rep(y_diff/x_diff, length( df[[length( df)]]$x)))
}
}

df <- do.call(rbind, df)
df$x1 <- df$x + sin( df$theta) * linewidth + cos(df$theta) * dash_len
df$x2 <- df$x + sin( df$theta) * linewidth - cos(df$theta) * dash_len
df$x3 <- df$x - sin( df$theta) * linewidth - cos(df$theta) * dash_len
df$x4 <- df$x - sin( df$theta) * linewidth + cos(df$theta) * dash_len

df$y1 <- df$y - cos( df$theta) * linewidth + sin(df$theta) * dash_len
df$y2 <- df$y - cos( df$theta) * linewidth - sin(df$theta) * dash_len
df$y3 <- df$y + cos( df$theta) * linewidth - sin(df$theta) * dash_len
df$y4 <- df$y + cos( df$theta) * linewidth + sin(df$theta) * dash_len

do.call(grid::grobTree, lapply(seq(nrow(df)), function(i) {
grid::polygonGrob(c(df$x1[i], df$x2[i], df$x3[i], df$x4[i]),
c(df$y1[i], df$y2[i], df$y3[i], df$y4[i]),
gp = gpar(col = "#00000000", lwd = 0, fill = col))
}))

}
使用起来相当简单:
set.seed(2)

x <- 1:10
y <- rnorm(10)

grid::grid.newpage()
grid::grid.draw(segmentify(x, y))
enter image description here
在不影响间距的情况下更改线宽就像这样:
grid::grid.newpage()
grid::grid.draw(segmentify(x, y, linewidth = 3))
enter image description here
您可以像这样控制间距和颜色:
grid::grid.newpage()
grid::grid.draw(segmentify(x, y, linewidth = 2, break_len = 0.5, col = "forestgreen"))
enter image description here

关于r - 如何在不考虑线尺寸的情况下保持线型间距恒定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63061601/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com