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:
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:
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
]
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"]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With