【问题标题】:Is there an R function to draw a solid circle with a radius in user coordinates是否有一个 R 函数可以在用户坐标中绘制一个半径为实心圆
【发布时间】:2019-06-24 16:07:47
【问题描述】:

是否可以在“用户”坐标中绘制具有半径的实心圆?

我尝试了以下方法:

多边形: 我不想使用它们,因为我需要生成的 svg 中的真实圆圈。

细分

segments(x, y, x, y, lwd=px, lend=0)

对于分段,问题是我找不到在“用户”坐标中指定分段的方法。

结果图最后导出为 PDF。

更新 我绘制了一个包含很多元素的图表,并且元素具有不同的宽度。元素的宽度取决于 x 轴的宽度。如果我不使用用户坐标,则 PDF 中的结果与 x 轴无关。

多边形是圆的近似值,如果我使用它们,结果例如PDF很大,性能不好,内存占用很高。我在一张图上画了 10,000 个以上的圆圈。

我使用以下代码来描述性能问题:

circle <- function(x, y, r, col) {
  edgeCount <- 50
  intervals <- (1:edgeCount) / edgeCount * 2 * pi
  for(i in 1:length(x)) {
    polygon(r[i]*sin(intervals) + x[i], r[i]*cos(intervals) + y[i], col=col[i],border=NA)
  }
}

【问题讨论】:

  • 什么是“泛滥的圈子”,什么是“用户单位”?
  • 这是在 base 还是 grid/ggplot 中?或者是其他东西?然后你提出svg,你是如何保存它的,用grDevices::svg()或其他方式?您是否需要将圆圈显示在 R 和 svg 的绘图窗口中,或者将其添加到 svg 文件中就足够了?如果您添加一些示例代码来设置绘图并保存它,那么这将是一个更好的问题,以便任何想要回答的人都有一个起点......
  • @JohnColeman “用户单位”或“用户坐标”是区别于“数据单位”或“数据坐标”的常用术语。无论绘图的数据纵横比如何,用户单位中的圆在用户看来都像一个圆,而如果纵横比不是 1,数据单位中的圆可能看起来像一个椭圆。
  • 我使用base,但如果可行,我可以使用grid或ggplot。
  • 另外,您是否尝试过这些可能重复的解决方案? plot - drawing circle in R,推荐plotrix::draw.circledraw a circle in ggplot2

标签: r


【解决方案1】:

如果您对使用spSpatialLine 对象的包装器感到满意,您可以尝试oceanmap 包,它有一个非常有用的函数SpatialCircle()。它本质上是通过seq() 构建一个圆,并针对您的中心点坐标 x 和 y 以及您的半径 r 进行调整。它仍然是一组线段(所以不是一条曲线),但使用起来非常简单。

结果:

代码:

非常简单:

# Load libraries.
library(oceanmap)

# Generate plot window and data.
set.seed(1702)
plot.new()
plot.window(xlim = c(0, 20), ylim = c(0, 10), 
            asp = 1, xaxs = "i",  yaxs = "i")
axis(1)
axis(2)
box()


n <- 1000
x <- runif(n, 0, 20)
y <- runif(n, 0, 10)

for (i in 1:n) { 

    circle <- SpatialCircle(x = x[i], y = y[i], r = 0.1, n = 1000)
    lines(circle)

}

这也适用于 ggplot2 与一些数据争吵。


附录:空间圆的精度

如果您想查看 SpatialCircle() 函数中的 n(精度)的真正含义,请尝试以下操作:

nrow(circle@lines[[1]]@Lines[[1]]@coords)
结果:
[1] 1000

这意味着该对象有 1,000 个坐标对(x 和 y),可以通过这些坐标对绘制一条线。此外,这条线将有 999 个不同的线段,因为第一个和最后一个坐标对总是相同的。证明:

all.equal(circle@lines[[1]]@Lines[[1]]@coords[1, ],
          circle@lines[[1]]@Lines[[1]]@coords[1000, ])
结果:
[1] TRUE

【讨论】:

    【解决方案2】:

    如果我自己在 Gregor2 的帮助下找到了一个解决方案,这确实将我带到了图书馆“网格”。

    library(grid)
    #draw frame using normal plot
    plot(0, 0, cex=0)
    
    margins <- par("mar")
    
    #1: bottom 2:left 3:top 4:right
    mb <- unit(margins[1], "lines")
    ml <- unit(margins[2], "lines")
    
    mt <- unit(margins[3], "lines")
    mr <- unit(margins[4], "lines")
    
    #create viewport equivalent to margins in par
    pushViewport(viewport(x = ml, y = mb, width = unit(1, "npc") - ml - mr, height = unit(1, "npc") - mb - mt, just=c("left", "bottom"), clip=TRUE))
    
    #draw circle in npc units (easily convertable to user units using grconvertX)
    grid.draw(circleGrob(x=0.5, y=0.5, r=0.5, default.units="npc", gp=gpar(col="blue", fill="blue")))
    
    popViewport()
    

    【讨论】:

      猜你喜欢
      • 2021-04-19
      • 2016-06-10
      • 2014-05-30
      • 1970-01-01
      • 2021-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多