Wolfram mathematica 在保留原始布局特征的情况下,进行小修改后重新布局图形

Wolfram mathematica 在保留原始布局特征的情况下,进行小修改后重新布局图形,wolfram-mathematica,mathematica-8,graph-visualization,Wolfram Mathematica,Mathematica 8,Graph Visualization,在Mathematica 8中,有没有一种简单的方法可以完成以下操作 构造一个图形,并使用一些图形布局显示它 稍微修改图形(例如,添加或删除边或顶点) 从原始布局开始重新计算布局,使对象的“形状”或多或少得到保留。例如,从先前布局的坐标开始重新运行spring electric布局算法 如果图形在两次显示之间没有更改,则布局也不应更改(或仅更改很少)。使用新的图形或图形批的显示都是可以接受的 编辑:本质上,我需要类似图形的类似布局。我总是通过修改一个现有的图来获得类似的图,这个图可能已经布置好了

在Mathematica 8中,有没有一种简单的方法可以完成以下操作

  • 构造一个图形,并使用一些图形布局显示它
  • 稍微修改图形(例如,添加或删除边或顶点)
  • 从原始布局开始重新计算布局,使对象的“形状”或多或少得到保留。例如,从先前布局的坐标开始重新运行spring electric布局算法
  • 如果图形在两次显示之间没有更改,则布局也不应更改(或仅更改很少)。使用新的
    图形
    图形批
    的显示都是可以接受的

    编辑:本质上,我需要类似图形的类似布局。我总是通过修改一个现有的图来获得类似的图,这个图可能已经布置好了,但是任何通用的解决方案都是可以接受的


    编辑2:这里有一个例子,说明这种东西在哪里有用。转到并单击“在浏览器中运行”(需要Java)。单击设置,然后单击执行。你可以看到图表的演变。如果我们在Mathematica中这样做,那么每一个连续的图形看起来都会完全不同,很难看出它是同一个正在演化的图形。在一些应用程序中,能够将图形的微小更改可视化是非常有用的。但如果进行了多次连续更改,则必须重新计算布局,仅淡入或高亮显示边缘是不够的。同样,这只是一个例子:我不想用Mathematica来制作图形动画,也不想把这个巨大组件的出现形象化。

    您可能需要检查这个选项是否有助于解决图形的问题

    我用一个示例图检查了
    ComponentLayout
    PackingLayout
    的所有可能值组合(
    graph0
    graph1
    ,在下面的代码中,它是
    graph0
    ,去掉了一条边)。某些组合看起来对您的目的更有用(删除边时图形布局的更改更少。我发现

    "ComponentLayout" -> "CircularEmbedding"
    "ComponentLayout" -> "LayeredDrawing"
    "ComponentLayout" -> "SpiralEmbedding"
    
    最好保留布局

    显示所有组合的代码为

    In[5]:= Quit
    In[12]:= $COMPONENTLAYOUTS={(*Automatic,None,*)"CircularEmbedding","HighDimensionalEmbedding","LayeredDrawing","LinearEmbedding","RadialEmbedding","RandomEmbedding","SpiralEmbedding","SpringElectricalEmbedding","SpringEmbedding"};
    $PACKINGLAYOUTS={"ClosestPacking","ClosestPackingCenter","Layered","LayeredLeft","LayeredTop","NestedGrid"};
    layoutopt[c_,p_]:=GraphLayout-> {"ComponentLayout"->$COMPONENTLAYOUTS[[ c]],"PackingLayout"-> $PACKINGLAYOUTS[[p]]};
    In[4]:= words=DictionaryLookup["*zz"];
    In[5]:= graph0=Flatten[Map[(Thread[#\[DirectedEdge]DeleteCases[Nearest[words,#,3],#]])&,words]];
    i=RandomInteger[{1,Length[graph0]}];
    graph0[[i]]
    graph1=Drop[graph0,{i}];
    Out[7]= tizz\[DirectedEdge]fizz
    In[18]:= g0[i_,j_]:=Graph[graph0,VertexLabels->"Name",ImagePadding->20,ImageSize->200,layoutopt[i,j]];
    g1[i_,j_]:=Graph[graph1,VertexLabels->"Name",ImagePadding->20,ImageSize->200,layoutopt[i,j]]
    
    Column[Grid/@Table[
    {
    $COMPONENTLAYOUTS[[c]],
    $PACKINGLAYOUTS[[p]],
    g0[c,p],
    g1[c,p]
    },
    {c,1,Length[$COMPONENTLAYOUTS]},
    {p,1,Length[$PACKINGLAYOUTS]}
    ]]
    

    正如您所知,MMA中有几种图形格式。我们有Combinatica包格式、
    GraphPlot
    格式和M8
    graph
    格式

    图形地块
    您可以找到
    GraphPlot
    节点的坐标,如下所示

    GraphPlot[{1 -> 2, 2 -> 3, 3 -> 1, 3 -> 4}, DirectedEdges -> True,
               VertexLabeling -> True]
    

    此绘图可以手动操作。您仍然可以在其中找到旧坐标和新坐标:

    VertexCoordinateRules -> {{0.000196475, 0.}, {0.,0.847539}, 
                              {0.916405, 0.423865}, {2.03143, 0.42382}}
    

    可以使用修改后的坐标再次绘制绘图:

    GraphPlot[{1 -> 2, 2 -> 3, 3 -> 1, 3 -> 4}, DirectedEdges -> True,
              VertexLabeling -> True, newRules]
    
    updatedRules = VertexCoordinateRules -> 
                     Append[VertexCoordinateRules /. newRules, {1, 0}];
    GraphPlot[{1 -> 2, 2 -> 3, 3 -> 1, 3 -> 4, 1 -> 5, 5 -> 4}, 
               DirectedEdges -> True, VertexLabeling -> True, updatedRules]
    

    或者画一个新的图表

    GraphPlot[{1 -> 2, 2 -> 3, 3 -> 1, 3 -> 4, 1 -> 5, 5 -> 4}, 
              DirectedEdges -> True, VertexLabeling -> True]
    
    默认情况下如下所示:

    使用旧坐标:

    GraphPlot[{1 -> 2, 2 -> 3, 3 -> 1, 3 -> 4}, DirectedEdges -> True,
              VertexLabeling -> True, newRules]
    
    updatedRules = VertexCoordinateRules -> 
                     Append[VertexCoordinateRules /. newRules, {1, 0}];
    GraphPlot[{1 -> 2, 2 -> 3, 3 -> 1, 3 -> 4, 1 -> 5, 5 -> 4}, 
               DirectedEdges -> True, VertexLabeling -> True, updatedRules]
    


    图形

    我不认为你可以像操纵
    图形一样操纵
    图形
    ,但是你可以访问它的顶点坐标

    GraphData["AGraph"]
    

    拥有这些旧坐标是很好的,因为如果我们使用它的邻接矩阵重新创建这个图,它的布局会略有不同。这可以使用旧坐标来恢复

    GraphData["AGraph"]
    

    在MMA 8.0中,有两种修改图形的基本方法。第一种方法依赖于
    HighlightGraph
    ,特别是
    GraphHighlightStyle->“DehighlightHide”
    。第二种方法在该图形的未来变体中使用图形的顶点坐标

    我们将分别讨论删除和添加,因为它们涉及稍微不同的方法

    [p.S.:为了让答案更清楚,我在年对我的答案做了几次修改。]

    首先是一些数据:

    edges={1\[UndirectedEdge]8,1\[UndirectedEdge]11,1\[UndirectedEdge]18,1\[UndirectedEdge]19,1\[UndirectedEdge]21,1\[UndirectedEdge]25,1\[UndirectedEdge]26,1\[UndirectedEdge]34,1\[UndirectedEdge]37,1\[UndirectedEdge]38,4\[UndirectedEdge]11,4\[UndirectedEdge]12,4\[UndirectedEdge]26,4\[UndirectedEdge]27,4\[UndirectedEdge]47,4\[UndirectedEdge]56,4\[UndirectedEdge]57,4\[UndirectedEdge]96,4\[UndirectedEdge]117,5\[UndirectedEdge]11,5\[UndirectedEdge]18,7\[UndirectedEdge]21,7\[UndirectedEdge]25,7\[UndirectedEdge]34,7\[UndirectedEdge]55,7\[UndirectedEdge]76,8\[UndirectedEdge]11,26\[UndirectedEdge]29,26\[UndirectedEdge]49,26\[UndirectedEdge]52,26\[UndirectedEdge]111,27\[UndirectedEdge]28,27\[UndirectedEdge]51,42\[UndirectedEdge]47,49\[UndirectedEdge]97,51\[UndirectedEdge]96}
    
    以下是初始图表:

    g = Graph[edges, VertexLabels -> "Name", ImagePadding -> 10, 
    ImageSize -> 500]
    

    在不改变图形整体外观的情况下“删除”图形边缘。

    让我们开始删除位于图形中心的边(4,11)。
    remaingesandVertexts
    包含除边(4,11)之外的所有顶点和初始边

    让我们“删除”(即隐藏)边(4,11):

    如果我们真的去掉了边(4,11),图形的外观就会发生根本性的变化

     Graph[Complement[edges, {4 \[UndirectedEdge] 11}], 
       VertexLabels -> "Name", ImagePadding -> 10, ImageSize -> 500]
    

    在不改变图形整体外观的情况下“添加”图形边缘。

    添加一个图边稍微有点挑战性。有两种方法。这里使用的方法是反向的。首先以隐藏形式包含新边,然后再将其揭穿。带有隐藏“待添加”边的初始图的布局与带有“新”边的图的布局相似原因是:它们实际上是同一个图形:但是它们显示的边数不同

    g2 = Graph[Append[edges, 42 \[UndirectedEdge] 37], 
     VertexLabels -> "Name", ImagePadding -> 10, ImageSize -> 500]
    
    HighlightGraph[g2, 
       Join[Complement[EdgeList[g2], {42 \[UndirectedEdge] 37}], 
       VertexList[g2]], VertexLabels -> "Name", ImagePadding -> 10, 
       GraphHighlightStyle -> "DehighlightHide"]
    

    现在显示添加了“新边”的图形。

    这看起来与图1非常不同。但它似乎是图4的自然延伸

    动态添加新顶点和边

    还有另一种方法可以在保持整体外观的同时添加边(和顶点)。它的灵感来源于舍尔德在回复中所写的内容

    让我们为未来的顶点99保留点{0,0}。我们只需将该点添加到g2中的
    顶点坐标

    vc = VertexCoordinates -> 
      Append[AbsoluteOptions[g2, VertexCoordinates][[2]], {0, 0}]
    
    现在让我们看看它是什么样子。g3就是g2,有额外的顶点(999)和边(4,99)

    这个过程允许我们在前进的过程中添加新的边和顶点。但是需要一些尝试和错误来确保新的顶点位于合适的位置

    只添加另一条边(没有新的顶点)要容易得多:只需添加新边并使用上一个图中的
    VertexCoordinates


    您应该能够使用相同的方法(使用相同的
    顶点坐标
    )从图形中删除边。

    这充其量只是部分答案。此外,我正在使用Mma 7。

    vc = VertexCoordinates -> Append[AbsoluteOptions[g2, VertexCoordinates][[2]], {0, 0}]
    g3 = Graph[Append[EdgeList [g2], 4 \[UndirectedEdge] 999], vc, 
      VertexLabels -> "Name", ImagePadding -> 10, 
      GraphHighlightStyle -> "DehighlightHide", ImageSize -> 500]
    
    gr1 = {1 -> 2, 2 -> 3, 3 -> 4, 4 -> 5, 5 -> 6, 6 -> 1};
    gplot1 = GraphPlot[gr1, Method -> "CircularEmbedding", 
      VertexLabeling -> True]
    
    gr2 = {2 -> 3, 3 -> 4, 4 -> 5, 5 -> 6}
    
    Needs["GraphUtilities`"];
    
     gplot2 = 
     GraphPlot[SparseArray@Map[# -> 1 &, EdgeList[gr2]], 
      VertexLabeling -> True, 
      VertexCoordinateRules -> 
       Thread[VertexList[gr1] -> 
         First@Cases[gp1, GraphicsComplex[points_, __] :> points, 
           Infinity]]]