带ggplot2的二分网络图 [英] Bipartite network graph with ggplot2

查看:213
本文介绍了带ggplot2的二分网络图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下数据框:

  structure(list(X1 = structure(c(1L,1L,1L, 1L,1L,1L,1L,1L,
2L,2L,2L,2L,2L,2L,2L,2L,2L,2L,3L,3L,3L,3L,4L,4L, 4L,4L,4L,5L,5L,5L,5L,5L,5L,5L,5L,5L,5L,6L,6L,6L
),标签= c(1,2 (1L,6L,8L,10L,12L,13L,3L,4L,3L,3L,4L,5L,6L) 1L,6L,
7L,9L,10L,12L,13L,3L,4L,5L,10L,12L,13L,4L,1L,
6L,12L,13L,3L,1L,6L, 7L,8L,10L,11L,12L,13L,2L,
3L,11L,12L,13L),标签= c(I1,I10,I11,I12,
I13,I2,I3,I4,I5,I6,I7,I8,I9),class =factor)),.Names = c(X1,
X2),row.names = c(NA,-40L),class =data.frame)

其中X1是人员编号,X2是人员所属的组。一个人可以在不同的群体中。
现在我想从每个人到他所属的每个组画一条线。用 plot()我解决了这个问题:

  plot(0 ,xlim = c(0,1),ylim = c(0,1),type =n,axes = FALSE,xlab =,ylab =)

factor.to .int< - function(f){
(as.integer(f)-1)/(length(levels(f)) - 1)
}

段(factor.to.int(data $ X1),0,factor.to.int(data $ X2),1,col = data $ X1)
axis(1,at = seq(0,1,by = 1 /(length(level(data $ X1))-1)),labels = levels(data $ X1))
axis(3,at = seq(0,1,by = 1 /水平(数据$ X2)) - 1)),标签=水平(数据$ X2))

结果如下所示:



感谢您的帮助!

解决方案

通过使用 geom_segment(),可以得到一个简单的 ggplot2 就像您对基本图形版本所做的那样转换数据。我还使用了ggplot2中的一些更高级的自定义选项,包括一个可以说是更加精美的版本。

 #使用ggplot2版本0.9.2.1 
库(ggplot2)

dat $ x1_norm = rangeTransform(as.integer(dat $ X1))
dat $ x2_norm = rangeTransform(as.integer(dat $ X2))

dat $ y1 = 0
dat $ y2 = 1

#简单版本。
p1 = ggplot(dat,aes(x = x1_norm,xend = x2_norm,y = y1,yend = y2,color = X1))+
geom_segment(size = 1.2)+
scale_colour_brewer (palette =Set1,name =Person)

ggsave(plot = p1,filename =plot_1.png,height = 3.5,width = 6)

 #花式版本。 
#创建单独的data.frames以手动指定轴刻度和轴文本。
axis_1 = data.frame(x = rangeTransform(as.integer(unique(dat $ X1))),
y = 0,label = as.character(unique(dat $ X1)))
$ b $ axis_2 = data.frame(x = rangeTransform(as.integer(unique(dat $ X2))),
y = 1,label = as.character(unique(dat $ X2)))

p2 = ggplot(data = dat)+
theme_bw()+
theme(axis.title = element_blank())+
theme(axis.text = element_blank())+
theme(axis.ticks = element_blank())+
theme(panel.grid = element_blank())+
geom_segment(aes(x = x1_norm,xend = x2_norm ,y = y1,yend = y2,color = X1),
size = 1.2)+
geom_segment(x = 0,xend = 1,y = 0,yend = 0,size = 0.7)+
geom_segment(x = 0,xend = 1,y = 1,yend = 1,size = 0.7)+
scale_colour_brewer(palette =Set1,name =Person)+
scale_y_continuous(limits = c(-0.2,1.2),expand = c(0,0))+
geom_segment(data = axis_1,aes(x = x,xend = x,y = y,yend = y- 0.025),size = 0.7)+
geom_segment(data = axis_2,aes(x = x,xend = x,y = y,yend = y + 0.025),size = 0.7)+
geom_text(data = axis_1,aes(label = label,x = x,y =
ges_text(data = axis_2,aes(label = label,x = x,y = y + 0.075))

ggsave(plot = p2,filename = plot_2.png,height = 3.5,width = 6)


I have the following data frame:

structure(list(X1 = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 4L, 4L, 
4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L
), .Label = c("1", "2", "3", "4", "5", "6"), class = "factor"), 
    X2 = structure(c(1L, 6L, 8L, 10L, 12L, 13L, 3L, 4L, 1L, 6L, 
    7L, 9L, 10L, 12L, 13L, 3L, 4L, 5L, 10L, 12L, 13L, 4L, 1L, 
    6L, 12L, 13L, 3L, 1L, 6L, 7L, 8L, 10L, 11L, 12L, 13L, 2L, 
    3L, 11L, 12L, 13L), .Label = c("I1", "I10", "I11", "I12", 
    "I13", "I2", "I3", "I4", "I5", "I6", "I7", "I8", "I9"), class = "factor")), .Names = c("X1", 
"X2"), row.names = c(NA, -40L), class = "data.frame")

Where in X1 is the person number and in X2 the group to which the person belongs to. One person can be in different groups. Now I want to draw a line from each person to each group he belongs to. With plot() I solved it this way:

plot(0, xlim=c(0,1), ylim=c(0,1), type="n", axes=FALSE, xlab="", ylab="")

factor.to.int <- function(f) {
  (as.integer(f) - 1) / (length(levels(f)) - 1)
}

segments(factor.to.int(data$X1), 0, factor.to.int(data$X2), 1, col=data$X1)
axis(1, at = seq(0, 1, by = 1 / (length(levels(data$X1)) - 1)), labels = levels(data$X1))
axis(3, at = seq(0, 1, by = 1 / (length(levels(data$X2)) - 1)), labels = levels(data$X2))

The result looks like this:

Now I wondering how I can do this with ggplot2?

Thanks for your help!

解决方案

A simple ggplot2 version of your graph is possible by using geom_segment() and transforming the data much like you did for the base graphics version. I've also included an arguably more polished version, using some of the more advanced customization options in ggplot2.

# Using ggplot2 version 0.9.2.1
library(ggplot2)

dat$x1_norm = rangeTransform(as.integer(dat$X1))
dat$x2_norm = rangeTransform(as.integer(dat$X2))

dat$y1 = 0
dat$y2 = 1

# Simple version.
p1 = ggplot(dat, aes(x=x1_norm, xend=x2_norm, y=y1, yend=y2, colour=X1)) +
     geom_segment(size=1.2) +
     scale_colour_brewer(palette="Set1", name="Person")

ggsave(plot=p1, filename="plot_1.png", height=3.5, width=6)

# Fancy version.
# Create separate data.frames to manually specify axis ticks and axis text.
axis_1 = data.frame(x=rangeTransform(as.integer(unique(dat$X1))),
                    y=0, label=as.character(unique(dat$X1)))

axis_2 = data.frame(x=rangeTransform(as.integer(unique(dat$X2))),
                    y=1, label=as.character(unique(dat$X2)))

p2 = ggplot(data=dat) +
     theme_bw() +
     theme(axis.title=element_blank()) +
     theme(axis.text=element_blank()) +
     theme(axis.ticks=element_blank()) +
     theme(panel.grid=element_blank()) +
     geom_segment(aes(x=x1_norm, xend=x2_norm, y=y1, yend=y2, colour=X1),
                  size=1.2) +
     geom_segment(x=0, xend=1, y=0, yend=0, size=0.7) +
     geom_segment(x=0, xend=1, y=1, yend=1, size=0.7) +
     scale_colour_brewer(palette="Set1", name="Person") +
     scale_y_continuous(limits=c(-0.2, 1.2), expand=c(0, 0)) +
     geom_segment(data=axis_1, aes(x=x, xend=x, y=y, yend=y-0.025), size=0.7) +
     geom_segment(data=axis_2, aes(x=x, xend=x, y=y, yend=y+0.025), size=0.7) +
     geom_text(data=axis_1, aes(label=label, x=x, y=y - 0.075)) +
     geom_text(data=axis_2, aes(label=label, x=x, y=y + 0.075))

ggsave(plot=p2, filename="plot_2.png", height=3.5, width=6)

这篇关于带ggplot2的二分网络图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆