创建图表的技巧

Yar*_*tov 14 wolfram-mathematica graph-drawing

我想以编程方式创建这样的图表 http://yaroslavvb.com/upload/junction-tree-decomposition.png

我想我应该使用带有VertexCoordinateRules,VertexRenderingFunction和EdgeRenderingFunction的GraphPlot作为图形.我应该使用什么彩色斜面背景?

编辑 主要使用Simon的想法,这是我最终使用的简化的"不太健壮"的版本

Needs["GraphUtilities`"];
GraphPlotHighlight[edges_, verts_, color_] := Module[{},
  vpos = Position[VertexList[edges], Alternatives @@ verts];
  coords = Extract[GraphCoordinates[edges], vpos];
  (* add .002 because end-cap disappears when segments are almost colinear *)  
  AppendTo[coords, First[coords] + .002];
  Show[Graphics[{color, CapForm["Round"], JoinForm["Round"], 
     Thickness[.2], Line[coords], Polygon[coords]}],
   GraphPlot[edges], ImageSize -> 150]
  ]

SetOptions[GraphPlot, 
  VertexRenderingFunction -> ({White, EdgeForm[Black], Disk[#, .15], 
      Black, Text[#2, #1]} &), 
  EdgeRenderingFunction -> ({Black, Line[#]} &)];
edges = GraphData[{"Grid", {3, 3}}, "EdgeRules"];
colors = {LightBlue, LightGreen, LightRed, LightMagenta};
vsets = {{8, 5, 2}, {7, 5, 8}, {9, 6, 3}, {8, 1, 2}};
MapThread[GraphPlotHighlight[edges, #1, #2] &, {vsets, colors}]

http://yaroslavvb.com/upload/mathematica-graphs.png

Sim*_*mon 11

我得到了推论Samsdram的答案

GraphPlotHighlight[edges:{((_->_)|{_->_,_})..},hl:{___}:{},opts:OptionsPattern[]]:=Module[{verts,coords,g,sub},
  verts=Flatten[edges/.Rule->List]//.{a___,b_,c___,b_,d___}:>{a,b,c,d};
  g=GraphPlot[edges,FilterRules[{opts}, Options[GraphPlot]]];
  coords=VertexCoordinateRules/.Cases[g,HoldPattern[VertexCoordinateRules->_],2];
  sub=Flatten[Position[verts,_?(MemberQ[hl,#]&)]];
  coords=coords[[sub]];     
  Show[Graphics[{OptionValue[HighlightColor],CapForm["Round"],JoinForm["Round"],Thickness[OptionValue[HighlightThickness]],Line[AppendTo[coords,First[coords]]],Polygon[coords]}],g]
]
Protect[HighlightColor,HighlightThickness];
Options[GraphPlotHighlight]=Join[Options[GraphPlot],{HighlightColor->LightBlue,HighlightThickness->.15}];
Run Code Online (Sandbox Code Playgroud)

上面的一些代码可以更加健壮,但它可以工作:

GraphPlotHighlight[{b->c,a->b,c->a,e->c},{b,c,e},VertexLabeling->True,HighlightColor->LightRed,HighlightThickness->.1,VertexRenderingFunction -> ({White, EdgeForm[Black], Disk[#, .06], 
Black, Text[#2, #1]} &)]
Run Code Online (Sandbox Code Playgroud)

Mathematica图形


编辑#1:此代码的清理版本可在http://gist.github.com/663438找到

编辑#2:正如下面的评论中所讨论的,我edges必须匹配的模式是带有可选标签的边缘规则列表.这略微不如GraphPlot函数(以及上述要点中的版本)所使用的一般,其中边缘规则也允许包含在a中Tooltip.

为了找到GraphPlot我重复使用的确切模式,感兴趣的对象Unprotect[fn];ClearAttributes[fn,ReadProtected];Information[fn]在哪里fn,直到我发现它使用了以下(清理)函数:

Network`GraphPlot`RuleListGraphQ[x_] := 
  ListQ[x] && Length[x] > 0 && 
    And@@Map[Head[#1] === Rule 
         || (ListQ[#1] && Length[#1] == 2 && Head[#1[[1]]] === Rule) 
         || (Head[#1] === Tooltip && Length[#1] == 2 && Head[#1[[1]]] === Rule)&, 
      x, {1}]
Run Code Online (Sandbox Code Playgroud)

我认为我的edges:{((_ -> _) | (List|Tooltip)[_ -> _, _])..}模式相同而且更简洁......

  • @Yaroslav 3个步骤(约混乱...对不起)(1)`撤消[GraphPlot]; ClearAttributes [GraphPlot,ReadProtected];信息[GraphPlot]`(2)`撤消[Network`GraphPlotDump`Private`RuleListGraphQ]; ClearAttributes [Network`GraphPlotDump`Private`RuleListGraphQ,ReadProtected];信息[Network`GraphPlotDump`Private`RuleListGraphQ]`(3)`撤消[Network`GraphPlot`RuleListGraphQ]; ClearAttributes [Network`GraphPlot`RuleListGraphQ,ReadProtected];信息[网络`GraphPlot`RuleListGraphQ]` (2认同)

Sam*_*ram 5

对于仅连接两个节点的简单示例(如最右侧的示例),您可以像这样绘制带有上限端点的线.

vertices = {a, b};
Coordinates = {{0, 0}, {1, 1}};
GraphPlot[{a -> b}, VertexLabeling -> True, 
 VertexCoordinateRules -> 
  MapThread[#1 -> #2 &, {vertices, Coordinates}], 
 Prolog -> {Blue, CapForm["Round"], Thickness[.1], Line[Coordinates]}]
Run Code Online (Sandbox Code Playgroud)

Mathematica图形

对于更复杂的示例(如右起第二个),我建议使用顶点坐标绘制多边形,然后使用带帽线跟踪多边形的边缘.我找不到直接向多边形添加斜边的方法.跟踪多边形的周长时,需要将第一个顶点的坐标添加到线段的末尾,该线条构成多边形的完整周长.另外,CapForm行有两个独立的图形指令,它们指示是否斜切线的末端,而JoinForm指示是否斜切线的中间点.

vertices = {a, b, c};
Coordinates = {{0, 0}, {1, 1}, {1, -1}};
GraphPlot[{a -> b, b -> c, c -> a}, VertexLabeling -> True, 
 VertexCoordinateRules -> 
  MapThread[#1 -> #2 &, {vertices, Coordinates}], 
 Prolog -> {Blue, CapForm["Round"], JoinForm["Round"], Thickness[.15],
    Line[AppendTo[Coordinates, First[Coordinates]]], 
   Polygon[Coordinates]}]
Run Code Online (Sandbox Code Playgroud)

Mathematica图形