【问题标题】:tips for creating Graph diagrams创建图表的技巧
【发布时间】:2010-11-03 21:11:19
【问题描述】:

我想以编程方式创建这样的图表
(来源:yaroslavvb.com

我想我应该将 GraphPlot 与 VertexCoordinateRules、VertexRenderingFunction 和 EdgeRenderingFunction 一起用于图形。我应该为彩色斜面背景使用什么?

编辑 主要使用西蒙的想法,这是我最终使用的简化的“不太健壮”的版本

需要["GraphUtilities`"]; GraphPlotHighlight[edges_, verts_, color_] := Module[{}, vpos = Position[VertexList[edges], Alternatives @@ verts]; coords = Extract[GraphCoordinates[edges], vpos]; (* 添加 .002,因为当段几乎共线时,端盖消失 *) AppendTo[coords, First[coords] + .002]; Show[Graphics[{color, CapForm["Round"], JoinForm["Round"], 厚度[.2],线[坐标],多边形[坐标]}], GraphPlot[边],ImageSize -> 150] ] SetOptions[GraphPlot, VertexRenderingFunction -> ({White, EdgeForm[Black], Disk[#, .15], 黑色,文本[#2,#1]} &), EdgeRenderingFunction -> ({Black, Line[#]} &)]; 边缘 = GraphData[{"Grid", {3, 3}}, "EdgeRules"]; 颜色 = {LightBlue,LightGreen,LightRed,LightMagenta}; vsets = {{8, 5, 2}, {7, 5, 8}, {9, 6, 3}, {8, 1, 2}}; MapThread[GraphPlotHighlight[edges, #1, #2] &, {vsets, colors}]


(来源:yaroslavvb.com

【问题讨论】:

标签: wolfram-mathematica graph-drawing


【解决方案1】:

概括一下 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}];

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

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]} &)]


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

编辑#2: 正如下面的 cmets 所讨论的,我的 edges 必须匹配的模式是带有可选标签的 边缘规则 列表。这比GraphPlot 函数(以及上面gist 中的版本)使用的稍微不通用,其中边缘规则 也允许包装在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}]

我认为我的edges:{((_ -> _) | (List|Tooltip)[_ -> _, _])..} 模式是等效的,更简洁......

【讨论】:

  • 你想用“edges”模式匹配什么?
  • GraphicsComplex中由GraphPlot生成的顶点的顺序就是它们在edges中出现的顺序。我的verts=... 只是按照它们出现的顺序获取顶点列表的一种丑陋方式,以便我知道要从g 中提取哪些坐标并传递给Graphics 命令。这是因为如果 VertexLabeling->False 然后 GraphPlot 不会保留关于哪个顶点是哪个顶点的任何信息,这是一个必要的事实。
  • ic...看来您可以使用 VertexList/GraphCoordinates 解决这个问题。我实际上是在询问边缘:函数定义中的模式。例如,它匹配 {3 -> 4, 4 -> 5, {6 -> 7, 2}}
  • @Yaroslav 我不知道 VertexList —— 那更简洁。至于模式,这与 GraphPlot 在绘制边列表时使用的模式相同(与邻接矩阵相反)。
  • @Yaroslav 3 步(抱歉搞砸了...) (1)Unprotect[GraphPlot];ClearAttributes[GraphPlot,ReadProtected];Information[GraphPlot] (2)Unprotect[NetworkGraphPlotDumpPrivateRuleListGraphQ];ClearAttributes[NetworkGraphPlotDumpPrivateRuleListGraphQ,ReadProtected];Information[Network GraphPlotDumpPrivateRuleListGraphQ]` (3)Unprotect[NetworkGraphPlotRuleListGraphQ];ClearAttributes[NetworkGraphPlotRuleListGraphQ,ReadProtected];Information[NetworkGraphPlotRuleListGraphQ]
【解决方案2】:

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

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]}]

对于更复杂的示例(如右数第二个),我建议使用顶点坐标绘制多边形,然后用封顶线跟踪多边形的边缘。我找不到将斜边直接添加到多边形的方法。跟踪多边形的周长时,您需要将第一个顶点的坐标添加到线段的末端,该线段构成了多边形的完整周长。此外,线条有两个单独的图形指令 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]}]

【讨论】:

  • 如何使用它只突出显示顶点的一个子集?
【解决方案3】:

JoinForm["Round"] 将对线段的连接进行四舍五入。

您需要在彩色区域的顶点中心周围填充一个多边形,然后使用JoinForm["Round"], ..., Line[{...}] 来获得圆角。

考虑

foo = GraphPlot[{a -> b, a -> c, b -> d, b -> e, b -> f, c -> e, e -> f}, 顶点渲染函数 -> ({White, EdgeForm[Black], Disk[#, .1], Black, Text[#2, #1]} &)] 显示[ 图形[{ RGBColor[0.6, 0.8, 1, 1], 多边形[foo[[1, 1, 1, 1, 1, {2, 5, 6, 2}]]], JoinForm["Round"], 厚度[0.2], 行[foo[[1, 1, 1, 1, 1, {2, 5, 6, 2}]]] }], 富 ]

其中 foo[[1,1,1,1,1]] 是顶点中心列表, {2,5,6} 拉出 {b,e,f} 顶点。 ({2,5,6,2} 将线从起点关闭。)

还有很多美化的空间,但我认为这涵盖了你上面没有提到的成分。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-26
    • 1970-01-01
    • 1970-01-01
    • 2018-05-26
    • 1970-01-01
    • 2021-02-07
    • 2016-08-30
    相关资源
    最近更新 更多