R中网络图的自定义线样式
我希望沿着直线的长度绘制一个带有箭头(或类似的V形)的定向网络图R中网络图的自定义线样式,r,graph,R,Graph,我希望沿着直线的长度绘制一个带有箭头(或类似的V形)的定向网络图 igraph库似乎使用基本的polygon函数,该函数接受lty来指定线型,但这些线型仅限于各种虚线 有没有办法制作定制符号(甚至使用pch中的三角形)以在R中形成一条线? 生成图形的最小代码: require(igraph) gr = graph_from_literal( A -+ B -+ C ) plot(gr,edge.curved=TRUE) 顺便说一句,我会很好地使用另一个网络分析库,如果它支持这一点。我问过gg
igraph
库似乎使用基本的polygon
函数,该函数接受lty
来指定线型,但这些线型仅限于各种虚线
有没有办法制作定制符号(甚至使用pch
中的三角形)以在R中形成一条线?
生成图形的最小代码:
require(igraph)
gr = graph_from_literal( A -+ B -+ C )
plot(gr,edge.curved=TRUE)
顺便说一句,我会很好地使用另一个网络分析库,如果它支持这一点。我问过
ggraph
的开发者,他说不能这样做。要使用igraph
来做这件事,我想你需要深入研究plot.igraph
函数,找出为顶点之间的曲线边生成贝塞尔曲线的位置,然后使用插值沿这些边获取点。有了这些信息,您可以沿图形边缘绘制箭头段
这里有一种不同的方法,它并不完全符合您的要求,但我希望能够满足您的需要。我将使用ggplot2
以及GGally
包中的ggnet2
函数,而不是igraph
基本的方法是获得每个图边端点的坐标,然后沿每个边插值点,在这里我们将绘制箭头段。请注意,边是直线,因为ggnet2
不支持曲线边
library(ggplot2)
library(GGally)
# Create an adjacency matrix that we'll turn into a network graph
m = matrix(c(0,1,0,0,
0,0,1,0,
1,0,0,1,
0,0,0,0), byrow=TRUE, nrow=4)
# Plot adjacency matrix as a directed network graph
set.seed(2)
p = ggnet2(network(m, directed=TRUE), label=TRUE, arrow.gap=0.03)
下面是图表的样子:
现在我们要沿每条边添加箭头。为此,我们首先需要找出每条边端点的坐标。我们可以使用ggplot\u build
从图形对象本身获得:
gg = ggplot_build(p)
图形数据存储在gg$data
中:
gg$data
在上面的输出中,我们可以看到,gg$data[[1]]
的前四列包含每条边端点的坐标(它们的顺序对于有向图是正确的)
现在我们有了每条边的端点,我们可以在两个端点之间插入点,在端点处我们将绘制带有箭头的线段。下面的函数处理这个问题。它获取每条边端点的数据帧,并返回对绘制n
箭头段的geom_段
(每条图形边一个)的调用列表。然后可以将geom_段调用列表直接添加到原始网络图中
# Function that interpolates points between each edge in the graph,
# puts those points in a data frame,
# and uses that data frame to return a call to geom_segment to add the arrow heads
add.arrows = function(data, n=10, arrow.length=0.1, col="grey50") {
lapply(1:nrow(data), function(i) {
# Get coordinates of edge end points
x = as.numeric(data[i,1:4])
# Interpolate between the end points and put result in a data frame
# n determines the number of interpolation points
xp=seq(x[1],x[2],length.out=n)
yp=approxfun(x[c(1,2)],x[c(3,4)])(seq(x[1],x[2],length.out=n))
df = data.frame(x=xp[-n], xend=xp[-1], y=yp[-n], yend=yp[-1])
# Create a ggplot2 geom_segment call with n arrow segments along a graph edge
geom_segment(data=df, aes(x=x,xend=xend,y=y,yend=yend), colour=col,
arrow=arrow(length=unit(arrow.length,"inches"), type="closed"))
})
}
现在,让我们运行函数将箭头添加到原始网络图中
p = p + add.arrows(gg$data[[1]], 15)
下面是图表的样子:
Cytoscape
和RCy3
库用于创建网络图
安装cytoscape版本3及更高版本。然后启动cytoscape GUI(图形用户界面)会话
本回答中使用的版本是cytoscape:3.4.0
和RCy3:1.5.2
操作系统:Windows-7
# load libraries
library('RCy3')
# create cytoscape connection
cy <- RCy3::CytoscapeConnection()
RCy3::deleteAllWindows(cy) # delete all windows in cytoscape
hideAllPanels(cy) # hide all panels
# create node and edge data and create graphNEL object
node.tbl <- data.frame(Node.Name = c('A', 'B', 'C'))
edge.tbl <- data.frame(Gene.1 = c('A', 'B'),
Gene.2 = c('B', 'C'))
g <- cyPlot(node.tbl, edge.tbl)
g
# A graphNEL graph with directed edges
# Number of Nodes = 3
# Number of Edges = 2
# create cytoscape window and display the graph
window_title <- 'example'
cw <- RCy3::CytoscapeWindow(window_title, graph=g, overwrite=FALSE)
RCy3::displayGraph(cw)
# set visual style and layout algorithm
vis_style <- 'Curved' # getVisualStyleNames(cw)[7]
RCy3::setVisualStyle(cw, vis_style)
RCy3::layoutNetwork(obj = cw, layout.name = "circular")
RCy3::layoutNetwork(obj = cw, layout.name = "kamada-kawai")
# get all edges
getAllEdges(cw)
# [1] "A (unspecified) B" "B (unspecified) C"
# get cytoscape supported line types
supported_styles <- getLineStyles (cw)
supported_styles
# [1] "EQUAL_DASH" "PARALLEL_LINES" "MARQUEE_DASH" "MARQUEE_EQUAL" "SOLID" "FORWARD_SLASH" "DASH_DOT" "MARQUEE_DASH_DOT"
# [9] "SEPARATE_ARROW" "VERTICAL_SLASH" "DOT" "BACKWARD_SLASH" "SINEWAVE" "ZIGZAG" "LONG_DASH" "CONTIGUOUS_ARROW"
# set edge line type
setEdgeLineStyleDirect(cw, "A (unspecified) B", supported_styles [16]) # "CONTIGUOUS_ARROW"
有关更多信息,请阅读?RCy3::setEdgeLineStyleDirect
另外,有关cytoscape边缘属性,请参见
安装RCy3:
# Install RCy3 - Interface between R and Cytoscape (through cyRest app)
library('devtools')
remove.packages("BiocInstaller")
source("https://bioconductor.org/biocLite.R")
biocLite("BiocGenerics")
biocLite("bitops")
install_github("tmuetze/Bioconductor_RCy3_the_new_RCytoscape")
与eipi的漂亮答案类似,您可以使用Rgraphviz来存储图形,它允许轻松提取节点和贝塞尔曲线位置,转换为ggplot(请参阅),然后添加箭头,就像eipi的答案一样。非常有创意,尽管我不确定是否会使用Cytoscape来实现这一目的。
setEdgeLineStyleDirect(cw, "A (unspecified) B", supported_styles [9]) # "SEPARATE_ARROW"
# save network as image in the current working directory
fitContent (cw)
setZoom(cw, getZoom(cw) - 1) # adjust the value from 1 to a desired number to prevent cropping of network diagram
saveImage(obj = cw,
file.name = 'example',
image.type = 'png',
h = 700)
# Install RCy3 - Interface between R and Cytoscape (through cyRest app)
library('devtools')
remove.packages("BiocInstaller")
source("https://bioconductor.org/biocLite.R")
biocLite("BiocGenerics")
biocLite("bitops")
install_github("tmuetze/Bioconductor_RCy3_the_new_RCytoscape")