R图根据频率改变线厚度

hmmo2u0o  于 2023-10-13  发布在  其他
关注(0)|答案(3)|浏览(104)

**更新:**找到了一个针对R中plot()函数的粗略解决方案,但它会从更好的图中受益。有什么想法吗?这是另一个层次的绘图,但潜在的,向增加厚度的过渡可能是渐进的。

我有一个简单的R Dataframe 。

dft <- data.frame(line=c(rep("X1",4),rep("X2",4),rep("X3",4)),+ 
       time=rep(c("t1","t2","t3","t4"),3), value=c(0,1,1,1,0,0.5,1,1,0,0,1,1))

> dft
   line time value
1    X1   t1   0.0
2    X1   t2   1.0
3    X1   t3   1.0
4    X1   t4   1.0
5    X2   t1   0.0
6    X2   t2   0.5
7    X2   t3   1.0
8    X2   t4   1.0
9    X3   t1   0.0
10   X3   t2   0.0
11   X3   t3   1.0
12   X3   t4   1.0

我想把它画出来,当线重叠时,它们相对于有多少条线来说更粗。因此,对于value从1开始并在1结束的时刻,如果更多的线在同一时间点具有相同的过渡,则线将更粗。
同样的数据也可以表示为跃迁频率

transitions <- data.frame(line=character(), generation=character(), t0=numeric(),t1=numeric())
for (line in unique(dft$line)){
  for (number in 1:3)  {
    generation= c("t1","t2","t3","t4")[number]
    generation2= c("t1","t2","t3","t4")[number+1]
    transitions <- rbind(transitions, data.frame(line=line, generation=generation, t0=dft[dft$line == line & dft$time == generation ,]$value, t1=dft[dft$line == line & dft$time == generation2 ,]$value))

  }
}

> transitions
  line generation  t0  t1
1   X1         t1 0.0 1.0
2   X1         t2 1.0 1.0
3   X1         t3 1.0 1.0
4   X2         t1 0.0 0.5
5   X2         t2 0.5 1.0
6   X2         t3 1.0 1.0
7   X3         t1 0.0 0.0
8   X3         t2 0.0 1.0
9   X3         t3 1.0 1.0

这听起来像是一个常见的问题。我确实找到了一些关于厚度如何变化的答案,但并不是真正基于频率。有人能给我指个正确的方向吗?谢谢你,谢谢

**更新:**最终,每一行(X1,X2,X3)都应该在经过时间t1:t4时进行跟踪,x轴为时间,y轴为值。就像下面的图片(用下面的初步解决方案生成)。也许R中有一些工具可以制作更好的图形。

euoag5mw

euoag5mw1#

这是一个通过改变线条透明度的快速绘图。

dft$x <- dft$time
levels(dft$x) <- 0:3
dft$x <- as.numeric(dft$x)
ggplot(dft, aes(x, value, group=line)) + geom_line(size=1, alpha=0.15)
g9icjywg

g9icjywg2#

我想出了一个粗糙的解决方案,使用规则的情节。如果有人有一个解决方案,使一个更好的情节,例如。有了ggplot,我真的很乐意学习。也许ggplot中不同级别的透明度可以做到这一点。

df<-ddply(transitions,.(generation,t0,t1),nrow)
levels(df$generation) <- c(0,1,2,3)
df$generationnr <- as.numeric(as.character(df$generation))

plot(1:1, 1:1, lwd = 1, type = 'l', xlim = c(0,3), ylim = c(0,1))
for (item in 1:nrow(df))
  lines(c(df$generationnr[item],(df$generationnr[item]+1)),+
              c(df$t0[item],df$t1[item]),lwd=df$V1[item] )

使用更真实的数据,这个粗糙的解决方案变得有点不稳定,线宽难以感知。

ybzsozfc

ybzsozfc3#

我也被这个问题绊倒了。我用ggplot用频率作为线段的宽度来解决它。

dft <- data.frame(
  line = c(rep("X1", 4), rep("X2", 4), rep("X3", 4)), 
  time = rep(c("t1","t2","t3","t4"), 3), 
  value = c(0,1,1,1,0,0.5,1,1,0,0,1,1))

# you need a data frame with each transition and the frequency for it
dft_wide <- dft %>% pivot_wider( names_from = "time", values_from = "value")
# which columns are the different time transitions
t <- 2:5
t_seq <- paste(t, t+1, sep = ":")[-length(t)]
timeseq <- 1:4

# add the frequency for each transition
freqtable <- data.frame()
for (i in 1:length(t_seq)){
  temp <- eval(parse(text = paste0("dft_wide[", t_seq[[i]],"]"))) %>% group_by_all %>% count()
  names(temp) <- c("from", "to", "n")
  freqtable <- rbind.data.frame(freqtable, 
                                cbind.data.frame(temp, 
                                                 trans = t_seq[[i]],
                                                 tstart = timeseq[[i]], 
                                                 tend = timeseq[[i+1]]))
}

#draw the transition as separate segments and use the frequency as line width 
freqtable %>%
  ggplot(aes ( x = tstart, xend = tend, y = from, yend = to ))+
  geom_segment(aes(lwd = n))


如果您只有两个时间点,则更简单:

dft_2 <- data.frame(t1 = c(0,1,0,0,2, 1, 1), t2 = c(1,1,1,2,1,1,1))

data.frame(table(dft_2$t1, dft_2$t2)) %>%
  mutate(transition = paste(Var1, Var2))%>%
  pivot_longer(cols = c(Var1, Var2), names_to = "x", values_to = "y")%>%
  filter(Freq != 0 & !grepl("NA", transition )) %>%
  ggplot(aes ( x = x, y = y, group = transition ))+
    geom_point()+
    geom_line(aes(lwd = Freq, ))

如果这被认为是“一个更好的情节”,这是个人的判断。

相关问题