r - 在极坐标图上绘制曲线

标签 r ggplot2 line polar-coordinates

我正在尝试创建一个图表,绘制点、标签以及连接给定开始和结束位置的点的线。然后将其转换为极坐标图。我可以绘制点、标签和线条,但我的问题是当我将图表转换为极坐标时。我使用了geom_curvegeom_segment。

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

在使用geom_segment时,我让它更接近我想要的效果,但它沿着圆的圆周绘制线条,考虑到我如何通过坐标,这是有意义的。这是一张照片: 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

最佳答案

正如其他人所评论的,您可以通过在笛卡尔坐标中自行计算来模仿由 coord_pold() 生成的所需位置。即:

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)

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

plot w grid lines

关于r - 在极坐标图上绘制曲线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52222939/

相关文章:

重新编码 '[.data.table'

r - 如何在 heatmap.2() 中为原始数据分配色阶

netbeans - PhpStorm 中的多行移动和复制

line - TextWrangler 和行高亮

line - 样条曲线和直线之间的交点

r - 在 dplyr 中连接两个文本列

r - 当 aes 大小相同时,geom_point 形状大小不同

r - 线型间距和大小的确切尺寸

r - ggplot2 & facet_wrap - 消除小平面之间的垂直距离

r - 如何在段的开头添加标签到geom_segment?