2010-11-03 33 views
14

Tôi muốn lập trình tạo sơ đồ như thế này http://yaroslavvb.com/upload/junction-tree-decomposition.pnglời khuyên cho việc tạo sơ đồ Graph

Tôi tưởng tượng tôi nên sử dụng GraphPlot với VertexCoordinateRules, VertexRenderingFunction và EdgeRenderingFunction cho đồ thị. Tôi nên sử dụng gì cho các nền có màu vát?

Sửa Sử dụng những ý tưởng chủ yếu của Simon, đây là một phiên bản "ít mạnh mẽ" đơn giản tôi đã kết thúc bằng

 
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

+0

Sơn? : D Chỉ là một trò đùa –

+0

Làm thế nào bạn làm cho các đồ thị được sử dụng trong câu hỏi của bạn? – Simon

+0

Tìm thấy chúng trên web. Tôi nghi ngờ nó đã được thực hiện với một số gói Latex –

Trả lời

11

câu trả lời generalising Samsdram của một chút, tôi nhận được

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

Một số mã trên có thể được thực hiện mạnh mẽ hơn một chút, nhưng nó hoạt động:

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

Mathematica graphics


EDIT # 1: Phiên bản đã xóa của mã này có thể được tìm thấy tại http://gist.github.com/663438

EDIT # 2: Như đã thảo luận trong các ý kiến ​​dưới đây, mô hình mà edges của tôi phải phù hợp là một danh sách các quy tắc cạnh với nhãn tùy chọn. Điều này hơi kém chung so với những gì được sử dụng bởi chức năng GraphPlot (và theo phiên bản ở trên gist) trong đó các quy tắc cạnh cạnh cũng được phép được gói trong một Tooltip.

Để tìm mô hình chính xác được sử dụng bởi GraphPlot tôi liên tục sử dụng Unprotect[fn];ClearAttributes[fn,ReadProtected];Information[fn] nơi fn là đối tượng quan tâm cho đến khi tôi phát hiện ra rằng nó được sử dụng như sau (làm sạch) chức năng:

Network`GraphPlot`RuleListGraphQ[x_] := 
    ListQ[x] && Length[x] > 0 && 
    [email protected]@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}] 

Tôi nghĩ rằng mô hình edges:{((_ -> _) | (List|Tooltip)[_ -> _, _])..} của tôi tương đương và ngắn gọn hơn ...

+0

những gì bạn đang cố gắng để phù hợp với mô hình "cạnh"? –

+0

Thứ tự của các đỉnh trong 'GraphicsComplex' được tạo bởi' GraphPlot' đơn giản là thứ tự chúng xuất hiện trong 'cạnh'. 'Verts = ...' của tôi chỉ là một cách xấu xí để lấy danh sách các đỉnh đó theo thứ tự chúng xuất hiện để tôi biết tọa độ nào cần trích xuất từ ​​'g' và chuyển tới lệnh' Graphics'. Đó là một kludge cần thiết bởi thực tế là nếu 'VertexLabeling-> False' thì GraphPlot không giữ bất kỳ thông tin nào về đỉnh nào. – Simon

+0

ic ... có vẻ như bạn có thể làm việc đó với VertexList/GraphCoordinates. Tôi đã thực sự hỏi về các cạnh: mẫu trong định nghĩa hàm. Ví dụ: nó khớp với {3 -> 4, 4 -> 5, {6 -> 7, 2}} –

5

Đối với ví dụ đơn giản, nơi bạn chỉ kết nối hai nút (như của bạn ví dụ ở bên phải), bạn có thể vẽ các đường thẳng với các điểm kết thúc được giới hạn như thế này.

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

Mathematica graphics

Đối với ví dụ phức tạp hơn (như thứ hai từ bên phải) Tôi muốn giới thiệu cách vẽ một đa giác bằng cách sử dụng đỉnh phối và sau đó truy tìm các cạnh của đa giác với một đường giới hạn. Tôi không thể tìm cách thêm cạnh vát trực tiếp vào đa giác. Khi truy tìm chu vi của đa giác, bạn cần phải thêm tọa độ của đỉnh đầu tiên vào cuối đoạn đường mà đường thẳng tạo ra chu vi hoàn chỉnh của đa giác. Ngoài ra, có hai chỉ thị đồ họa riêng biệt cho các dòng CapForm, điều này cho biết có nên bẻ cong các đầu của dòng và JoinForm hay không, điều này cho biết có nên bevel các điểm trung gian của dòng không.

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

Mathematica graphics

+0

Làm cách nào để bạn chỉ đánh dấu một tập con của các đỉnh bằng cách sử dụng? – Simon

4

JoinForm [ "Round"] sẽ làm tròn tham gia của đoạn thẳng.

Bạn sẽ muốn có một đa giác được điền xung quanh các tâm của các đỉnh trong vùng màu, sau đó là JoinForm["Round"], ..., Line[{...}] để có các góc được làm tròn.

Cân nhắc

 
foo = GraphPlot[{a -> b, a -> c, b -> d, b -> e, b -> f, c -> e, e -> f}, 
    VertexRenderingFunction -> 
    ({White, EdgeForm[Black], Disk[#, .1], Black, Text[#2, #1]} &)] 
Show[ 
    Graphics[{ 
     RGBColor[0.6, 0.8, 1, 1], 
     Polygon[foo[[1, 1, 1, 1, 1, {2, 5, 6, 2}]]], 
     JoinForm["Round"], Thickness[0.2], 
     Line[foo[[1, 1, 1, 1, 1, {2, 5, 6, 2}]]] 
    }], 
    foo 
] 
Mathematica graphics

nơi foo [[1,1,1,1,1]] là danh sách các trung tâm đỉnh và {2,5,6} kéo ra {b, e, f } đỉnh. ({2,5,6,2} đóng dòng lại tại điểm bắt đầu của nó.)

Có nhiều chỗ để làm đẹp, nhưng tôi nghĩ điều này bao gồm thành phần bạn không đề cập ở trên.

Các vấn đề liên quan