矢量化:使用geom_path绘制多个轮廓

时间:2017-01-05 19:28:32

标签: r ggplot2

我正在编写代码来创建多个轮廓数据集。我的步骤是:

  1. 使用

    生成原始数据

    T<-runif()

  2. 编写函数来描述由参数函数描述的轮廓:

    • x<-function(t)
    • y<-function(t)
  3. 将实数x,y的向量转换为复数x + 1i*y

  4. 对数据应用复杂函数,例如

    sin

  5. 将实部和虚部提取为实数组

    fx, fy

  6. 绘制对`

    geom_path(x=fx,y=fy)

  7. 使用颜色矢量对其进行颜色编码

  8. 每次我想要绘制轮廓时,我都在重复使用代码,但我想对其进行矢量化,以便最大限度地减少代码的重复。我怎么能这样做?

    以下是一个例子:

      #Create data
    
      #the parameter:
      T<-sort(runif(100,min=-1, max=1))
    
    
      #x(t), y(t)
      xt.hor<-function(t,c){
        return(c)
      }
      yt<-function(t,scale){
        return (scale*t)
      }
    
    
      X1<-mapply(xt.hor,T,c=-10)
      # X2, X3, X4
      X5<-mapply(xt.hor,T,c=10)
    
      YHor<-mapply(yt,T,scale=10)
    
      df1<-data.frame(x1=X1,
                      #x2,x3,x4,
                      x5=X5,yh=YHor)
    
    
      #convert to complex numbers:
    
      toComplex<-function(x,y){complex(real=x,imaginary=y)}
    
      z1<-mapply(toComplex,df1$x1,y=df1$yh)
      #z2, z3, z4
      z5<-mapply(toComplex,df1$x5,y=df1$yh)
    
      fz1<-sapply(z1,sin)
      #fz2,fz3,fz4
      fz5<-sapply(z5,sin)
    
      fx1<-sapply(fz1,Re)
      #fx2,fx3,fx4
      fx5<-sapply(fz5,Re)
    
      fy1<-sapply(fz1,Im)
      #fy2,fy3,fy4
      fy5<-sapply(fz5,Im)
    
      df2<-data.frame(fx1=fx1,fy1=fy1,
                      #curve2, curve 3, curve 4
                      fx5=fx5,fy5=fy5)
    
      RedOrgVector<-c('#fd8d3c','#fc4e2a','#e31a1c','#bd0026','#800026')
    
      p <- ggplot(data = df2)
    
      p+xlim(c(-10,10))+ylim(c(-10,10))+
        geom_path(x=fx1,y=fy1,size=.75,color=RedOrgVector[1],linetype=1)+
        #curve2, curve3, curve4
        geom_path(x=fx5,y=fy5,size=.75,color=RedOrgVector[5],linetype=1)
    

1 个答案:

答案 0 :(得分:2)

以下是使用tidyverse的方法。您的大多数代码都可以压缩成一个函数,只需构建并将提供的数据转换为ggplot2喜欢的格式。

generate_curve函数就是这样做的。获取输入向量和参数(c,比例和曲线编号,n)并返回x,y和曲线编号的tibble(奇特的数据框)。

如何获得多条曲线是通过生成多个输入向量(通过rerun并使用purrrmapplygenerate_curve函数映射到每个向量。情况我使用purr中的pmap_df,它将函数映射到输入列表并返回数据框。

library(tidyverse)

generate_curve <- function(data, c, scale, n) {

  tibble(X = c,
         YHor = scale*data,
         z = complex(real = X, imaginary = YHor),
         fz = sin(z),
         fx = Re(fz),
         fy = Im(fz)) %>% 
    select(fx, fy) %>% 
    mutate(row = row_number()) %>% 
    gather(group, value, -row) %>% 
    extract(group, "var", regex = "f(\\w)") %>% 
    spread(var, value) %>% 
    mutate(curve = n) %>% 
    select(-row)
}

list <- rerun(4, sort(runif(100, min = -1, max = 1)))
cs <- c(10,5,-5,-10)
scale <- rep(10,4)
length <- seq_along(list)

curves <- pmap_df(list(list,cs,scale,length), generate_curve)

RedOrgVector <- c('#fd8d3c','#fc4e2a','#e31a1c','#bd0026','#800026')

ggplot(curves, aes(x = x, y = y, group = factor(curve))) +
  geom_path(aes(color = factor(curve)), linetype = 1) +
  scale_color_manual(values = setNames(RedOrgVector, c(1:5))) +
  xlim(c(-10,10)) +
  ylim(c(-10,10))

enter image description here