在极坐标图上绘制曲线

时间:2018-09-07 12:49:05

标签: r ggplot2 line polar-coordinates

我正在尝试创建一个图形,该图形绘制点,标签和连接给定起点和终点位置的点的线。然后将其转换为极坐标图。我可以绘制点,标签和线,但是我的问题是将图表转换为极坐标时。我同时使用了geom_curvegeom_segment.

在使用geom_curve时出现错误,因为未为非线性坐标实现geom_curve。因此,我能得到的最远的是: Geom_Curve with No Polar

在使用geom_segment时,它更接近我想要的效果,但是它沿着ciilce的圆周画出了线,考虑到我如何通过坐标,这是有意义的。这是一张照片: Geom_Segment with Polar

我基本上需要geom_curve作为极坐标,但是我一直找不到。我希望圆的内侧的线是弯曲的,会有一些重叠,但是无论如何建议间距还是不错的,还是会受到欢迎。

数据:

k<-18 
ct<-12
q<-6
x_vector1<-seq(1,k,1) 
x_vector2<-seq(1,3,1) 
x_vector3<-seq(k-2,k,1) 
x_vector<-c(x_vector1,x_vector2,x_vector3)

n<-9 ## sets first level radius 
radius1<-rep(n,k) 
b<-13 ## sets second level radius 
radius2<-rep(b,q) 
radius<-c(radius1,radius2)

name<-c('Alice','Bob','Charlie','D','E','F','G','H','I','J','K','L',
        'M','N','O','Peter','Quin','Roger','Alice2','Bob2','Charlie2',
        'Peter2','Quin2','Roger2') 

dframe<-data.frame(x_vector,radius,name)
dframe$label_radius<-dframe$radius+1 

from<-c('Alice2','Bob','Charlie','D','E','Alice2','Charlie2','Charlie',
        'I','J','K','L','M','N','O','Peter','Quin','Alice') 

to<-c('Alice','Alice','Alice','Alice','Alice','Bob',
      'Bob','Bob','Bob','Charlie','Charlie','Peter',
      'Peter','Quin','Quin','Quin','Roger','Roger') 

amt<-c(3,8,8,8,6,2,2,4,2,4,8,1,10,5,9,5,2,1) 

linethick<-c(0.34,0.91,0.91,0.91,0.68,0.23,0.23,0.45,0.23,0.45,
             0.91,0.11,1.14,0.57,1.02,0.57,0.23,0.11) 

to_x<-c(1,1,1,1,1,2,2,2,2,3,3,16,16,17,17,17,18,18) 

to_rad<-c(9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9) 

from_x<-c(1,2,3,4,5,1,3,3,9,10,11,12,13,14,15,16,17,1) 

from_rad<-c(13,9,9,9,9,13,13,9,9,9,9,9,9,9,9,9,9,9) 

stats<-data.frame(from,to,amt,linethick,to_x,to_rad,from_x,from_rad)


p<-ggplot()+

  geom_point(data=dframe,aes(x=x_vector,y=radius),size=3,shape=19)+
  geom_text(data=dframe,aes(x=x_vector,y=label_radius,label=name))+   
  geom_segment(data=stats,aes(x=from_x,y=from_rad,xend=to_x,yend=to_rad, color=to), ## I need arrows starting at TO and going to FROM. ##
               arrow=arrow(angle=15,ends='first',length=unit(0.03,'npc'), type='closed'))+
     ## transform into polar coordinates   coord_polar(theta='x',start=0,direction=-1)
     ## sets up the scale to display from 0 to 7   scale_y_continuous(limits=c(0,14))+
     ## Used to 'push' the points so all 'k' show up.   expand_limits(x=0) p

2 个答案:

答案 0 :(得分:2)

正如其他人所评论的那样,您可以通过自己计算笛卡尔坐标来模拟coord_polar()产生的所需位置。即:

x = radius * cos(theta)
y = radius * sin(theta)
# where theta is the angle in radians

操纵2个数据帧:

dframe2 <- dframe %>%
  mutate(x_vector = as.integer(factor(x_vector))) %>%
  mutate(theta = x_vector / n_distinct(x_vector) * 2 * pi + pi / 2) %>%
  mutate(x = radius * cos(theta),
         y = radius * sin(theta),
         y.label = label_radius * sin(theta),
         name = as.character(name))

stats2 <- stats %>%
  select(from, to, amt, linethick) %>%
  mutate_at(vars(from, to), as.character) %>%
  left_join(dframe2 %>% select(name, x, y), 
            by = c("from" = "name")) %>%
  rename(x.start = x, y.start = y) %>%
  left_join(dframe2 %>% select(name, x, y),
            by = c("to" = "name")) %>%
  rename(x.end = x, y.end = y)

使用geom_curve()进行绘图:

# standardize plot range in all directions
plot.range <- max(abs(c(dframe2$x, dframe2$y, dframe2$y.label))) * 1.1

p <- dframe2 %>%
  ggplot(aes(x = x, y = y)) +
  geom_point() +
  geom_text(aes(y = y.label, label = name)) +

  # use 2 geom_curve() layers with different curvatures, such that all segments align
  # inwards inside the circle
  geom_curve(data = stats2 %>% filter(x.start > 0),
             aes(x = x.start, y = y.start, 
                 xend = x.end, yend = y.end, 
                 color = to),
             curvature = -0.3,
             arrow = arrow(angle=15, ends='first',
                           length=unit(0.03,'npc'),
                           type='closed')) +
  geom_curve(data = stats2 %>% filter(x.start <= 0),
             aes(x = x.start, y = y.start,
                 xend = x.end, yend = y.end,
                 color = to),
             curvature = 0.3,
             arrow = arrow(angle=15, ends='first',
                           length=unit(0.03,'npc'),
                           type='closed')) +
  expand_limits(x = c(-plot.range, plot.range),
                y = c(-plot.range, plot.range)) +
  coord_equal() +
  theme_void()

p

plot w/o grid lines

如果您想要极性网格线,也可以使用geom_spoke()ggfortify软件包的geom_circle()来模仿它们:

library(ggforce)

p + 

  geom_spoke(data = data.frame(x = 0,
                               y = 0,
                               angle = pi * seq(from = 0, 
                                                to = 2, 
                                                length.out = 9), # number of spokes + 1
                               radius = plot.range),
             aes(x = x, y = y, angle = angle, radius = radius),
             inherit.aes = FALSE, 
             color = "grey") +

  geom_circle(data = data.frame(x0 = 0, 
                                y0 = 0, 
                                r = seq(from = 0, 
                                        to = plot.range, 
                                        length.out = 4)), # number of concentric circles + 1
              aes(x0 = x0, y0 = y0, r = r), 
              inherit.aes = FALSE,
              color = "grey", fill = NA)

(注意:如果您确实需要这些伪网格线,请在其他geom层之前 绘制它们。)

plot w grid lines

答案 1 :(得分:0)

您必须在ggplot2中做所有事情吗?

如果没有,那么一种选择是创建带有点的图(可能使用ggplot2,或者仅使用直线网格图形,甚至可能使用基本图形),然后推到适当的视口并使用xsplines在点之间添加曲线(有关使用xspline的基本示例,请参见以下答案:Is there a way to make nice "flow maps" or "line area" graphs in R?

如果坚持使用ggplot2进行所有操作,则可能需要创建自己的geom函数,以极坐标图的形式绘制曲线。