如何用负r在极坐标中绘制点?

时间:2019-07-15 01:45:21

标签: r ggplot2

我试图在极坐标(r,theta)中绘制两个点,其中r是距中心的距离,theta是角度。

当前解决方案不起作用,因为我没有轴的唯一“原点”。使用coord_plane时,y的原点是圆的中心,但x的原点似乎是每个半径的中心。

我想做的是在一个系统中进行绘制,该系统中以下示例中的两个点相对于原点是对称的。

library(ggplot2)
ggplot(data.frame(r = c(-100, 100) , theta = c(1, 1)),
       aes(x = r, y= theta)) +
  geom_text(aes(label = paste(round(r, 1),',', round(theta, 1)))) +
  coord_polar(theta = 'y',
              direction = -1,
              start = -pi/2) +
  scale_y_continuous(limits = c(0, 2*pi),
                     breaks = c(0, pi/2, pi, 3*pi/2 ),
                     labels = c('0', 'pi/2', 'pi', '3/2pi'))

enter image description here

3 个答案:

答案 0 :(得分:4)

我不完全了解您的最终目标是什么,但是可能的问题在于,如果您希望r代表到原点的距离,那么它就不能为负。 ggplot2使用coord_polar()所做的只是使整个笛卡尔平面遵循极坐标变形。这导致“零”实际上是“径向”坐标的下限。如果您手动更改其限制,则可以清楚地看到它:

library(ggplot2)
ggplot(data.frame(r = c(-100, 100) , theta = c(1, 1)),
       aes(x = r, y= theta)) +
  geom_text(aes(label = paste(round(r, 1),',', round(theta, 1)))) +
  coord_polar(theta = 'y',
              direction = -1,
              start = -pi/2) +
  scale_y_continuous(limits = c(0, 2*pi),
                     breaks = c(0, pi/2, pi, 3*pi/2 ),
                     labels = c('0', 'pi/2', 'pi', '3/2pi')) +
  scale_x_continuous(limits = c(-200, NA))

我不知道您所说的“关于原点对称”是什么意思,但是可以吗?

library(ggplot2)
ggplot(data.frame(r = c(100, 100) , theta = c(1, 1 + pi)),
       aes(x = r, y= theta)) +
  geom_text(aes(label = paste(round(r, 1),',', round(theta, 1)))) +
  coord_polar(theta = 'y',
              direction = -1,
              start = -pi/2) +
  scale_y_continuous(limits = c(0, 2*pi),
                     breaks = c(0, pi/2, pi, 3*pi/2 ),
                     labels = c('0', 'pi/2', 'pi', '3/2pi')) +
  scale_x_continuous(limits = c(0, NA))

reprex package(v0.3.0)于2019-07-16创建

答案 1 :(得分:3)

将Elio Campitelli的答案作为函数进行调整,您可以使用类似以下内容的方法:

plot_polar_signed <- function(r, theta) {
  data2 <- data.frame(r2 = abs(r),
             theta2 = theta + ifelse(r < 0, pi, 0))
  ggplot(data2, aes(x = r2, y = theta2)) +
    geom_text(aes(label = paste(round(r, 1),',', round(theta, 1)))) +
    coord_polar(theta = 'y',
                direction = -1,
                start = -pi/2) +
    scale_y_continuous(limits = c(0, 2*pi),
                       breaks = c(0, pi/2, pi, 3*pi/2 ),
                       labels = c('0', 'pi/2', 'pi', '3/2pi'))

}

plot_polar_signed(r = c(-100, 100), theta = c(1, 1))

enter image description here

答案 2 :(得分:0)

在极坐标中未定义带有r < 0的点,因为r是距中心的距离。否则,即使将theta设置在r != 0中,(0, 2pi)的每个点也会有两组坐标。

因此,您实际上是想在扩展的极坐标系中进行绘制,其中允许负r(r, theta)(-r, theta + pi)是相同的点。

我建议使用从系统到规范极坐标的映射。

canonical <- function(r, theta) {
  if (r >= 0) {
    c(r = r, theta = theta %% (2*pi))
  } else {
    c(r = -r, theta = (theta + pi) %% (2*pi))
  }
}

或更短并向量化:

canonical <- function(r, theta) {
  list(r = abs(r), 
       theta = (theta + ifelse(r < 0, pi, 0)) %% (2 * pi))
}

这将使有效极坐标保持不变(除非将theta放在(0, 2pi)中(如果尚未将其移入),并将具有r < 0的点转换为有效极坐标。

canonical(1, 0)
# untouched 

canonical(-1, 0)
# becomes (1, pi)

优点是您可以在转换后使用ggplot中的所有标准极性函数。

library(ggplot2)

df <- data.frame(r = c(-100, -50, 0, 50, 100) , theta = rep(1, 5))
df_polar <- as.data.frame(canonical(df$r, df$theta))

ggplot(df_polar,
       aes(x = r, y = theta)) +
  geom_text(aes(label = paste(round(r, 1),',', round(theta, 1)))) +
  coord_polar(theta = 'y') +
  scale_y_continuous(limits = c(0, 2*pi),
                     breaks = c(0, pi/2, pi, 3*pi/2 ),
                     labels = c('0', 'pi/2', 'pi', '3/2pi'))

Results with polar coordinates

同一脉络中的另一个选择是将极坐标转换为直角坐标,以便于绘制直线。映射是x = r*cos(theta)y=r*sin(theta),有趣的是,由于cos(theta+pi) = -cos(theta)sin也对负r有效。