【问题标题】:drawing circle in R在R中绘制圆圈
【发布时间】:2014-04-11 12:31:38
【问题描述】:

我不知道为什么下面的代码没有给我完整的圆圈,而只给出了其中的一部分。此外,我不知道如何在以 (0,0) 为中心且 r=1 和 a=2 的正方形内显示圆上或圆外的点。

library("plotrix")
n<-1000
plot.new()
frame()
x<-runif(n,-1,1)
y<-runif(n,-1,1)
for (i in 1:n) { plot(x[i],y[i])}
draw.circle(0,0,1,nv=1000,border=NULL,col=NA,lty=1,lwd=1)

这是输出

所以我将它固定为以下,当我有 100 个点时,图表如下所示。为什么没有显示完整的圆圈?

plot(x,y)
draw.circle(0,0,1,nv=1000,border=NULL,col=NA,lty=1,lwd=1)

感谢费尔南多,我修复了绘图,现在它看起来像这样,但我希望 x 的范围为(-1 到 1),就像 y 一样。 xlim 没有工作。你知道怎么回事吗?

magnitude = function(x, y) {
  stopifnot(isTRUE(all.equal(length(x),length(y))))
  return (sqrt(x^2 + y^2))
}
library("plotrix")
monte.carlo.pi<-function(n,draw=FALSE)
{
  circle.points<-0
  square.points<-0
  x<-runif(n,-1,1)
  y<-runif(n,-1,1)
  for (i in 1:n)
  {
    #if ((x[i])^2 + (y[i])^2 <=1)
    if (magnitude(x[i],y[i])<=1)
    {
      circle.points<-circle.points+1
      square.points<-square.points+1
    } else
    {
      square.points<-square.points+1
    }
  }
  if (draw==TRUE)
  {
    plot.new()
    frame()
    plot(x,y,asp=1,xlim=c(-1,1),ylim=c(-1,1))
    draw.circle(0,0,1,nv=1000,border=NULL,col=NA,lty=1,lwd=1)
    rect(-1,-1,1,1)
    return(4*circle.points / square.points)
  }
}

然后像下面这样调用函数:

monte.carlo.pi(100,T)

当前情节如下:

【问题讨论】:

  • 您只绘制最后一点,尝试不使用 for 循环的 plot(x, y)。
  • 我不确定,但试试plot(x, y, asp = 1)。如果出错,请检查此stackoverflow.com/questions/5411796/…。
  • @Fernando 你能看看更新后的问题吗?
  • 好的,我去看看。
  • 对我来说 xlim 有效,但如果我使用 RStudio 的“缩放”按钮,x 轴会扩展(可能是 RStudio 的一个错误,我不确定)。

标签: r plot


【解决方案1】:

如果您希望圆圈在用户看来实际上像一个圆圈,那么费尔南多的回答很好。这个答案包括在数据维度中画一个圆。

如果您的 x 轴和 y 轴缩放相同,例如, 如果您将纵横比设置为 1 (asp = 1),那么这两种方法是等效的。

# initialize a plot
plot(c(-1, 1), c(-1, 1), type = "n")

# prepare "circle data"
radius = 1
center_x = 0
center_y = 0
theta = seq(0, 2 * pi, length = 200) # angles for drawing points around the circle

# draw the circle
lines(x = radius * cos(theta) + center_x, y = radius * sin(theta) + center_y)

【讨论】:

  • 这是一个很好的提醒,在创建圆所涉及的数学中。
  • +1 关于数据和视觉坐标的区别。我想知道是否有更直接的方法可以在数据坐标中绘制圆。
  • 当然,只需添加x = h + radius*cos(theta), y = k + radius*sin(theta) 以绘制以(h, k) 为中心的圆
  • 实际上解释theta 会很有用,嗨@MichaelChirico:P
【解决方案2】:

正如 Gregor 已经指出的,画圆时必须区分 x 和 y 是否具有相同的比例。 如果 x 和 y 具有相同的比例,我更喜欢使用symbols 来在 R 中画一个圆。它无需指定顶点就可以做到这一点,并且不需要额外的库。

n <- 1000
set.seed(0)
x <- runif(n, -1, 1)
y <- runif(n, -1, 1)

#x and y have the same scale -> Circle
plot(x, y, asp=1)
symbols(x=0, y=0, circles=1, inches=F, add=T)

#In case x and y don't have the same scale -> Ellipse
#Use Gregor's Answer
plot(x,y)
radius <- 1
theta <- seq(0, 2 * pi, length = 200)
lines(x = radius * cos(theta), y = radius * sin(theta))

#Using plotrix
library("plotrix")
plot(x, y, asp=1)
draw.circle(x=0, y=0, radius=1)

plot(x,y)
draw.ellipse(x=0, y=0, a=1, b=1)

【讨论】:

    【解决方案3】:

    你需要指定asp = 1:

    x = runif(100, -1, 1)
    y = runif(100, -1, 1)
    plot(x, y, asp = 1, xlim = c(-1, 1))
    draw.circle(0, 0, 1, nv = 1000, border = NULL, col = NA, lty = 1, lwd = 1)
    

    编辑:顺便说一句,您可以让您的蒙特卡洛函数更高效:

    mc.pi = function(n) {
    
      x = runif(n, -1, 1)
      y = runif(n, -1, 1)
      pin = sum(ifelse(sqrt(x^2 + y^2 <= 1), 1, 0))
      4 * pin/n
    }
    

    【讨论】:

    • 我想你想要sqrt(x^2 + y^2) &lt;= 1 而不是sqrt(x^2 + y^2 &lt;= 1)。话虽如此,您可以摆脱 ifelse 而只是做sum(x^2 + y^2 &lt;= 1) - 我也摆脱了平方根,因为 if sqrt(x)
    猜你喜欢
    • 2012-09-19
    • 1970-01-01
    • 2015-10-20
    • 1970-01-01
    • 1970-01-01
    • 2015-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多