【问题标题】:R: Creating graphs where the nodes are imagesR:创建节点是图像的图形
【发布时间】:2011-02-12 01:20:48
【问题描述】:

我正在尝试创建一个图(图论中的图、节点和边等),其中每个节点都由文件中的图像表示(最好是某种光栅格式)。我查看了 RGraphviz 包,但不幸的是 shapefill 属性是“当前不受支持”。

我还查看了 iGraph,但浏览文档时我似乎找不到任何关于在图表中使用图像的信息。

有没有人在使用 R 生成的图表中使用图像文件的经验?

【问题讨论】:

    标签: image r graph


    【解决方案1】:

    有一些方法可以手动执行此操作,因为您可以在 R 中读取和绘制图像(这里我使用 rimage),并且图形通常也绘制在 x-y 平面上。您几乎可以使用igraph 来处理您想要在R 中处理图形的任何事情,另一种方法是使用我自己的包qgraph,它也可以用来绘制各种类型的图形。

    在这两个包中,节点的位置是在一个矩阵中指定/给出的,每个节点有两列和一行,表示 x 和 y 位置。两个包还绘制在 -1 到 1 的水平和垂直区域。因此,使用该布局矩阵,我们可以使用 rasterImage 在正确的位置绘制图像。

    我将从无向图(无箭头)开始。

    首先我加载一张图片:

    # Load rimage library:
    library('rimage')
    
    # Read the image:
    data(logo)
    img <- imagematrix(logo)
    

    并对要使用的图进行采样(使用邻接矩阵):

    # Sample an adjacency matrix:
    set.seed(1)
    adj <- matrix(sample(0:1,10^2,T,prob=c(0.8,0.2)),10,10)
    

    然后在qgraph:

    library('qgraph')
    
    # Run qgraph (plot the graph) and save the layout:
    L <- qgraph(adj,borders=FALSE,vsize=0,labels=F,directed=F)$layout
    
    # Plot images:
    apply(L,1,function(x)rasterImage(img,x[1]-0.1,x[2]-0.1,x[1]+0.1,x[2]+0.1))
    

    看起来像这样:

    igraph 中,您首先需要进行布局。此布局还需要重新缩放以适应 -1 到 1 的绘图区域(这由 igraph 本身在绘图函数中完成):

    library('igraph')
    
    # Make the graph
    G <- graph.adjacency(adj,mode="undirected")
    
    # Create fixed layout:
    set.seed(1)
    L <- layout.fruchterman.reingold(G)
    
    # Rescale the layout to -1 to 1
    L[,1]=(L[,1]-min(L[,1]))/(max(L[,1])-min(L[,1]))*2-1
    L[,2]=(L[,2]-min(L[,2]))/(max(L[,2])-min(L[,2]))*2-1
    
    # Plot:
    plot(G,layout=L,vertex.size=0,vertex.frame.color="#00000000",vertex.label="")
    
    # Set images:
    apply(L,1,function(x)rasterImage(img,x[1]-0.1,x[2]-0.1,x[1]+0.1,x[2]+0.1))
    

    现在,如果您想要有向图,那就不那么简单了,因为箭头需要指向图像的边缘。最好的方法是使用图像大小的不可见方形节点。为此,您需要摆弄qgraph 中的vsize 参数或igraph 中的vertex.size 参数。 (如果你愿意,我可以查找它的确切代码,但这不是微不足道的)。

    qgraph:

    L <- qgraph(adj,borders=FALSE,vsize=10,labels=F,shape="square",color="#00000000")$layout
    
    apply(L,1,function(x)rasterImage(img,x[1]-0.1,x[2]-0.1,x[1]+0.1,x[2]+0.1))
    

    igraph:

    G <- graph.adjacency(adj)
    
    set.seed(1)
    L <- layout.fruchterman.reingold(G)
    
    L[,1]=(L[,1]-min(L[,1]))/(max(L[,1])-min(L[,1]))*2-1
    L[,2]=(L[,2]-min(L[,2]))/(max(L[,2])-min(L[,2]))*2-1
    
    plot(G,layout=L,vertex.size=17,vertex.shape="square",vertex.color="#00000000",vertex.frame.color="#00000000",vertex.label="")
    
    apply(L,1,function(x)rasterImage(img,x[1]-0.1,x[2]-0.1,x[1]+0.1,x[2]+0.1))
    

    2013 年更新:

    请注意 rimage 不再在 CRAN 上,但您可以使用 pngReadImages 库。我刚刚更新了qgraph 以包含更容易做到这一点的功能。看这个例子:

    # Download R logo:
    download.file("http://cran.r-project.org/Rlogo.jpg", file <- tempfile(fileext = ".jpg"), 
        mode = "wb")
    
    # Sample an adjacency matrix:
    set.seed(1)
    adj <- matrix(sample(0:1, 10^2, TRUE, prob = c(0.8, 0.2)), 10, 10)
    
    # Run qgraph:
    qgraph(adj, images = file, labels = FALSE, borders = FALSE)
    

    这需要qgraph 1.2 版才能工作。

    【讨论】:

    • 可爱的答案。 SO 提问者还想要什么?
    【解决方案2】:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-02
    • 2016-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多