Wolfram mathematica 创建图表的技巧

Wolfram mathematica 创建图表的技巧,wolfram-mathematica,graph-drawing,Wolfram Mathematica,Graph Drawing,我想以编程方式创建这样的图表 (来源:) 我想我应该使用带有顶点坐标的GraphPlot、顶点渲染函数和边渲染函数来绘制图形。我应该使用什么颜色的斜面背景 编辑 主要使用Simon的想法,这里有一个简化的“不那么健壮”的版本,我最终使用了它 Needs["GraphUtilities`"]; GraphPlotHighlight[edges_, verts_, color_] := Module[{}, vpos = Position[VertexList[edges], Alternat

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

我想我应该使用带有顶点坐标的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}] 需要[“笔力”]; GraphPlot Highlight[边,顶点,颜色]:=模块[{}, vpos=位置[VertexList[边],可选项@@verts]; 坐标=提取[图形坐标[边],VPO]; (*添加.002,因为当线段几乎共线时端盖消失*) [coords,First[coords]+.002]的附录; 显示[图形[{颜色、帽形[“圆形”]、连接形[“圆形”], 厚度[.2],直线[coords],多边形[coords]}, GraphPlot[边缘],图像大小->150] ] 设置选项[GraphPlot, VertexRenderingFunction->({White,EdgeForm[Black],Disk[#,.15], 黑色,文本[#2,#1]}&), EdgeRenderingFunction->({黑色,线条[#]}&]; 边=图形数据[{“网格”,{3,3}},“边”]; 颜色={浅蓝色、浅绿色、浅红色、浅品红}; VSET={8,5,2},{7,5,8},{9,6,3},{8,1,2}; MapThread[GraphPlotHighlight[edges,#1,#2]&,{vsets,colors}]

(来源:)

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

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

JoinForm[“Round”]将使线段的连接圆化

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

考虑 foo=GraphPlot[{a->b,a->c,b->d,b->e,b->f,c->e,e->f}, 顶点渲染功能-> ({白色,边形[黑色],磁盘[#,.1],黑色,文本[#2,#1]}&)] 展示[ 图形[{ RGB颜色[0.6,0.8,1,1], 多边形[foo[[1,1,1,1,1,1,{2,5,6,2}]], 接缝形式[“圆形”],厚度[0.2], 行[foo[[1,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}将线关闭回其起点。)


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

概括一下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: 可以在以下位置找到此代码的清理版本:

编辑#2: 正如在下面的注释中所讨论的,my
edge
必须匹配的模式是带有可选标签的edge规则列表。这比
GraphPlot
函数(以及上述版本)所使用的功能略逊一筹,该功能还允许在
工具提示中包装边缘规则

为了找到
GraphPlot
使用的确切模式,我反复使用
Unprotect[fn];ClearAttributes[fn,ReadProtected];信息[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}]

我认为我的
边:{((->124;)(列表工具提示)[[u->,124;]…}
模式是等效的,更简洁…

你如何使用它只高亮显示顶点的子集?你是如何制作问题中使用的图形的?在网上找到的。我怀疑这是用一些乳胶包装完成的Wolfram在9:15左右谈到了一个“突出显示图形功能”——也许它将在下一个版本中内置?有趣的是……顺便说一句,看起来TechCon演示笔记本已经发布了(虽然不是Wolfram的)——你想用“边缘”来匹配什么模式?由
GraphPlot
生成的
GraphicsComplex
中顶点的顺序只是它们在
边中出现的顺序。我的
verts=…
只是一种按照顶点出现的顺序获取顶点列表的丑陋方式,这样我就知道从
g
提取哪些坐标并传递给
Graphics
命令。如果
VertexLabeling->False
那么GraphPlot就不会保留任何关于哪个顶点是哪个的信息。ic…看起来你可以通过VertexList/GraphCoordinates解决这个问题。我实际上是在问边:函数定义中的模式。例如,它匹配{3->4,4->5,{6->7,2}}@Yaroslav,我不知道VertexList,这要整洁得多。至于模式,这与GraphPlot在绘制边列表时使用的模式相同(与邻接矩阵相反)。@Yaroslav 3步(对混乱表示抱歉…(1)
取消保护[GraphPlot];ClearAttributes[GraphPlot,ReadProtected];信息[GraphPlot]
(2)
取消保护[Network
GraphPlotDump
Private
RuleListGraphQ];ClearAttributes[Network
GraphPlotDump
Private
RuleListGraphQ,ReadProtected];信息[Network
GraphPlotDump
Private
RuleListGraphQ]`(3)
Unprotect[Network
GraphPlot
RuleListGraphQ];ClearAttributes[Network
GraphPlot
RuleListGraphQ,ReadProtected];信息[Network
GraphPlot
RuleListGraphQ]
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}]