更改 GraphPlot 中的边路线以避免歧义

发布于 2024-10-01 01:12:13 字数 1481 浏览 3 评论 0原文

我有以下无向图

gr={1->2,1->3,1->6,1->7,2->4,3->4,4->5,5->6,5->7};

,我希望用 GraphPlot 以“钻石”格式绘制它。我按照概述执行此操作 下面(方法 1)给出以下内容:

alt text

问题在于这种表示具有欺骗性,因为两者之间没有边缘顶点 4 & 1, 或 1 & 5(边缘是从 4 到 5)。我希望更改边缘 {4,5} 的路线以获得如下所示的内容:

alt text

我这样做的方法是包括另一条边 {5,4},现在我可以使用 MultiedgeStyle 来“移动”有问题的边,然后通过定义 EdgeRenderingFunction 来删除添加的边,从而不显示有问题的线。 (方法 2,“解决方法”)。至少可以说,这很尴尬。有更好的办法吗? (这是我的第一个问题!)

方法1

gr={1->2,1->3,1->6,1->7,2->4,3->4,4->5,5->6,5->7};

vcr={1-> {2,0},2-> {1,1},3-> {1,-1},4-> {0,0},5-> {4,0},6-> {3,1},7-> {3,-1}};

GraphPlot[gr,VertexLabeling-> True, 
             DirectedEdges-> False,
             VertexCoordinateRules-> vcr, 
             ImageSize-> 250]

方法2(解决方法)

erf= (If[MemberQ[{{5,4}},#2], 
         { },      
         {Blue,Line[#1]}
        ]&);

gp[1] = 
       GraphPlot[
                 Join[{5->4},gr], 
                        VertexLabeling->True, 
                        DirectedEdges->False, 
                        VertexCoordinateRules->vcr, 
                        EdgeRenderingFunction->erf, 
                        MultiedgeStyle->.8, 
                        ImageSize->250
                        ]

I have the following undirected graph

gr={1->2,1->3,1->6,1->7,2->4,3->4,4->5,5->6,5->7};

which I wish to plot with GraphPlot in a 'diamond' format. I do this as outlined
below (Method 1) giving the following:

alt text

The problem is that this representation is deceptive, as there is no edge between vertices 4 & 1, or 1 & 5 (the edge is from 4 to 5). I wish to change the route of edge {4,5} to get something like the following:

alt text

I do this by including another edge, {5,4}, and I can now use MultiedgeStyle to 'move' the offending edge, and I then get rid of the added edge by defining an EdgeRenderingFunction, thus not showing the offending line. (Method 2,'Workaround'). This is awkward, to say the least. Is there a better way? (This is my first question!)

Method 1

gr={1->2,1->3,1->6,1->7,2->4,3->4,4->5,5->6,5->7};

vcr={1-> {2,0},2-> {1,1},3-> {1,-1},4-> {0,0},5-> {4,0},6-> {3,1},7-> {3,-1}};

GraphPlot[gr,VertexLabeling-> True, 
             DirectedEdges-> False,
             VertexCoordinateRules-> vcr, 
             ImageSize-> 250]

Method 2 (workaround)

erf= (If[MemberQ[{{5,4}},#2], 
         { },      
         {Blue,Line[#1]}
        ]&);

gp[1] = 
       GraphPlot[
                 Join[{5->4},gr], 
                        VertexLabeling->True, 
                        DirectedEdges->False, 
                        VertexCoordinateRules->vcr, 
                        EdgeRenderingFunction->erf, 
                        MultiedgeStyle->.8, 
                        ImageSize->250
                        ]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

老子叫无熙 2024-10-08 01:12:13

只是一个启动

下面检测是否有一条边“接触”不是其端点之一的顶点。

目前它仅适用于直线边缘。

该计划将其作为第一步,然后创建一个模拟边缘,如问题中发布的方法 2 所示。

使用我在此处发布的另一个答案。

Clear["Global`*"];
gr = {1 -> 2, 1 -> 3, 1 -> 6, 1 -> 7, 2 -> 4, 3 -> 4, 4 -> 5, 5 -> 6, 5 -> 7};
vcr = {1 -> {2, 0}, 2 -> {1, 1}, 3 -> {1, -1}, 4 -> {0, 0}, 
       5 -> {4, 0}, 6 -> {3, 1}, 7 -> {3, -1}};
a = InputForm@GraphPlot[gr, VertexLabeling -> True, DirectedEdges -> False, 
                       VertexCoordinateRules -> vcr, ImageSize -> 250] ;

distance[segmentEndPoints_, pt_] := Module[{c, d, param, start, end},
   start = segmentEndPoints[[1]];
   end = segmentEndPoints[[2]];
   param = ((pt - start).(end - start))/Norm[end - start]^2;
   Which[
    param < 0, EuclideanDistance[start, pt],
    param > 1, EuclideanDistance[end, pt],
    True, EuclideanDistance[pt, start + param (end - start)]
    ]
   ];

edgesSeq= Flatten[Cases[a//FullForm, Line[x_] -> x, Infinity], 1];

vertex=Flatten[
          Cases[a//FullForm,Rule[VertexCoordinateRules, x_] -> x,Infinity]
               ,1];

Off[General::pspec];
edgesPos = Replace[edgesSeq, {i_, j_} -> {vertex[[i]], vertex[[j]]}, 1];
On[General::pspec];

numberOfVertexInEdge = 
  Count[#, 0, 2] & /@ 
   Table[ Chop@distance[segments, vertices], {segments, edgesPos}, 
                                             {vertices, vertex}
        ];

If[Length@Select[numberOfVertexInEdge, # > 2 &] >  0, 
            "There are Edges crossing a Vertex", 
            "Graph OK"]

Just a kickstart

The following detects if there is an edge that "touches" a vertex that is not one of its endpoints.

It works only for straight line edges right now.

The plan is using it as a first step and then creating a mock edge as in the method 2 posted in the question.

Uses another answer I posted here.

Clear["Global`*"];
gr = {1 -> 2, 1 -> 3, 1 -> 6, 1 -> 7, 2 -> 4, 3 -> 4, 4 -> 5, 5 -> 6, 5 -> 7};
vcr = {1 -> {2, 0}, 2 -> {1, 1}, 3 -> {1, -1}, 4 -> {0, 0}, 
       5 -> {4, 0}, 6 -> {3, 1}, 7 -> {3, -1}};
a = InputForm@GraphPlot[gr, VertexLabeling -> True, DirectedEdges -> False, 
                       VertexCoordinateRules -> vcr, ImageSize -> 250] ;

distance[segmentEndPoints_, pt_] := Module[{c, d, param, start, end},
   start = segmentEndPoints[[1]];
   end = segmentEndPoints[[2]];
   param = ((pt - start).(end - start))/Norm[end - start]^2;
   Which[
    param < 0, EuclideanDistance[start, pt],
    param > 1, EuclideanDistance[end, pt],
    True, EuclideanDistance[pt, start + param (end - start)]
    ]
   ];

edgesSeq= Flatten[Cases[a//FullForm, Line[x_] -> x, Infinity], 1];

vertex=Flatten[
          Cases[a//FullForm,Rule[VertexCoordinateRules, x_] -> x,Infinity]
               ,1];

Off[General::pspec];
edgesPos = Replace[edgesSeq, {i_, j_} -> {vertex[[i]], vertex[[j]]}, 1];
On[General::pspec];

numberOfVertexInEdge = 
  Count[#, 0, 2] & /@ 
   Table[ Chop@distance[segments, vertices], {segments, edgesPos}, 
                                             {vertices, vertex}
        ];

If[Length@Select[numberOfVertexInEdge, # > 2 &] >  0, 
            "There are Edges crossing a Vertex", 
            "Graph OK"]
绝不服输 2024-10-08 01:12:13

这是一个更尴尬的解决方法:

Graphics[Annotation[GraphicsComplex[{{2., 0.}, {1., 1.}, 
          {1., -1.}, {3., 1.}, {3., -1.}, {0., 0.}, {4., 0.}, {0., 
     2.}, {4., 2.}}, 
        {{RGBColor[0.5, 0., 0.], Line[{{1, 2}, {1, 3}, {1, 4}, {1, 5}, 
                {2, 6}, {3, 6},  {7, 4}, {7, 5}, {6, 8}, {8, 9}, {9, 
        7}}]}, 
          {Text[Framed[1, {Background -> RGBColor[1, 1, 0.8], 
                  FrameStyle -> RGBColor[0.94, 0.85, 0.36], 
        FrameMargins -> 
                    Automatic}], 1], Text[Framed[2, 
                {Background -> RGBColor[1, 1, 0.8], FrameStyle -> 
                    RGBColor[0.94, 0.85, 0.36], 
        FrameMargins -> Automatic}], 2], 
            Text[Framed[3, {Background -> RGBColor[1, 1, 0.8], 
                  FrameStyle -> RGBColor[0.94, 0.85, 0.36], 
        FrameMargins -> 
                    Automatic}], 3], Text[Framed[6, 
                {Background -> RGBColor[1, 1, 0.8], FrameStyle -> 
                    RGBColor[0.94, 0.85, 0.36], 
        FrameMargins -> Automatic}], 4], 
            Text[Framed[7, {Background -> RGBColor[1, 1, 0.8], 
                  FrameStyle -> RGBColor[0.94, 0.85, 0.36], 
        FrameMargins -> 
                    Automatic}], 5], Text[Framed[4, 
                {Background -> RGBColor[1, 1, 0.8], FrameStyle -> 
                    RGBColor[0.94, 0.85, 0.36], 
        FrameMargins -> Automatic}], 6], 
            Text[Framed[5, {Background -> RGBColor[1, 1, 0.8], 
                  FrameStyle -> RGBColor[0.94, 0.85, 0.36], 
        FrameMargins -> 
                    Automatic}], 7]}}, {}], VertexCoordinateRules -> 
        {{2., 0.}, {1., 1.}, {1., -1.}, {3., 1.}, {3., -1.}, {0., 0.}, 
          {4., 0.}}], FrameTicks -> None, PlotRange -> All, 
    PlotRangePadding -> Scaled[0.1], AspectRatio -> Automatic, 
    ImageSize -> 250]

alt text

当然,我所做的是采用 FullForm 图形的图形并对其进行编辑。我向 GraphicsComplex 添加了几个点(即 {0., 2.}{4., 2.}),将在线中添加一些新的腿(即 {6, 8}, {8, 9}, {9, 7})并删除在顶点 4 和 5 之间绘制线的腿。

我不'并没有真正提供这个作为“解决方案”,但是比我有更多时间从事这方面工作的人应该能够编写一个函数来将 GraphicsComplex 操作为所需的形式。

Here's an even more awkward workaround:

Graphics[Annotation[GraphicsComplex[{{2., 0.}, {1., 1.}, 
          {1., -1.}, {3., 1.}, {3., -1.}, {0., 0.}, {4., 0.}, {0., 
     2.}, {4., 2.}}, 
        {{RGBColor[0.5, 0., 0.], Line[{{1, 2}, {1, 3}, {1, 4}, {1, 5}, 
                {2, 6}, {3, 6},  {7, 4}, {7, 5}, {6, 8}, {8, 9}, {9, 
        7}}]}, 
          {Text[Framed[1, {Background -> RGBColor[1, 1, 0.8], 
                  FrameStyle -> RGBColor[0.94, 0.85, 0.36], 
        FrameMargins -> 
                    Automatic}], 1], Text[Framed[2, 
                {Background -> RGBColor[1, 1, 0.8], FrameStyle -> 
                    RGBColor[0.94, 0.85, 0.36], 
        FrameMargins -> Automatic}], 2], 
            Text[Framed[3, {Background -> RGBColor[1, 1, 0.8], 
                  FrameStyle -> RGBColor[0.94, 0.85, 0.36], 
        FrameMargins -> 
                    Automatic}], 3], Text[Framed[6, 
                {Background -> RGBColor[1, 1, 0.8], FrameStyle -> 
                    RGBColor[0.94, 0.85, 0.36], 
        FrameMargins -> Automatic}], 4], 
            Text[Framed[7, {Background -> RGBColor[1, 1, 0.8], 
                  FrameStyle -> RGBColor[0.94, 0.85, 0.36], 
        FrameMargins -> 
                    Automatic}], 5], Text[Framed[4, 
                {Background -> RGBColor[1, 1, 0.8], FrameStyle -> 
                    RGBColor[0.94, 0.85, 0.36], 
        FrameMargins -> Automatic}], 6], 
            Text[Framed[5, {Background -> RGBColor[1, 1, 0.8], 
                  FrameStyle -> RGBColor[0.94, 0.85, 0.36], 
        FrameMargins -> 
                    Automatic}], 7]}}, {}], VertexCoordinateRules -> 
        {{2., 0.}, {1., 1.}, {1., -1.}, {3., 1.}, {3., -1.}, {0., 0.}, 
          {4., 0.}}], FrameTicks -> None, PlotRange -> All, 
    PlotRangePadding -> Scaled[0.1], AspectRatio -> Automatic, 
    ImageSize -> 250]

alt text

Of course, what I've done is taken the FullForm of the graphic of the graph and edited it. I added a couple of points to the GraphicsComplex (ie {0., 2.} and {4., 2.}), put some new legs into the line (ie {6, 8}, {8, 9}, {9, 7}) and deleted the leg which drew the line between vertices 4 and 5.

I don't really offer this as a 'solution' but someone with more time than I have to work on this should be able to write a function to manipulate the GraphicsComplex into a desired form.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文