Here is an example:
edge1 = Property[1 -> 2, EdgeStyle -> Red];
edge2 = Property[1 -> 2, EdgeStyle -> Blue];
Graph[{edge1, edge2}]
This does not work the way I want it. How can I make it so that I get two edges, one blue and one red?
Mathematica Stack Exchange is a question and answer site for users of Wolfram Mathematica. It only takes a minute to sign up.
Sign up to join this communityHere is an example:
edge1 = Property[1 -> 2, EdgeStyle -> Red];
edge2 = Property[1 -> 2, EdgeStyle -> Blue];
Graph[{edge1, edge2}]
This does not work the way I want it. How can I make it so that I get two edges, one blue and one red?
Another trick you can do:
Graph[Join[Table[1 -> 2, {10}], Table[2 -> 3, {5}],
Table[3 -> 1, {5}]],
EdgeShapeFunction -> {1 \[DirectedEdge]
2 -> (a = 0; {a++; ColorData[35, "ColorList"][[a]],
Arrow[#]} &),
2 \[DirectedEdge]
3 -> (b = 0; {b++; ColorData[55, "ColorList"][[b]],
Arrow[#]} &),
3 \[DirectedEdge] 1 -> (c = 0; {c++; ColorData[5, "ColorList"][[c]],
Arrow[#]} &)}]
VertexInDegree[g]
yields $\{5, 10, 5\}$. +1.
$\endgroup$
Aug 20, 2015 at 21:23
The trick is to render both a directed and an undirected edge with the same arrow EdgeShapeFunction
. Alas, the full graph representation will retain the different classes of edge, so functions such as FindKClan
, VertexOutDegree
, VertexInDegree
, and others that distinguish between different classes of edge will give incorrect answers.
Graph[{1, 2},
{Property[1 \[DirectedEdge] 2, EdgeStyle -> Red],
Property[1 <-> 2, EdgeStyle -> Blue]},
EdgeShapeFunction -> (Arrow[#] &)]
Because there are only two classes of edge (directed and undirected), following this approach also implies that one can have at most two edges between a given pair of vertexes.
You can kludge together a graph representation that appears as if three (or more) edges join two vertexes by forcing different vertexes to lie in the same position, through VertexCoordinates
:
Graph[{1, 2, 3}, {Property[1 \[DirectedEdge] 2, EdgeStyle -> Red],
Property[1 <-> 2, EdgeStyle -> Blue],
Property[1 <-> 3, EdgeStyle -> Green]},
EdgeShapeFunction -> (Arrow[#] &),
VertexCoordinates -> {{0, 0}, {1, 0}, {1, 0}}]
(Arrow[#]&)
works, I think that more properly you would want (Arrow[#1]&)
for your EdgeShapeFunction
, to reming the reader that a custom edge function is passed a sequence of two arguments: 1) a list of points describing the edge; 2) the edge denomination itself. Arrow
needs only the first one. I think this is also the reason why simply using Arrow
doesn't work: the edge definition would be interpreted as an arrow setback amount, which is expected to be a number.
$\endgroup$
EdgeShapeFunction
of the form ef[#, ___]
and called it within Graph
, as the two-argument approach would seem to require. I found indeed that both (Arrow[#]&)
and (Arrow[#1]&)
worked, but don't know why the former does.
$\endgroup$
Aug 19, 2015 at 22:24
(Arrow[#]&)
works because #
always represents only the first argument provided to the function, i.e. it is automatically equivalent to #1
, so that call discards the second argument passed to Arrow
by EdgeShapeFunction
. In other words, (Arrow[#]&)
is equivalent to Arrow[#1]&
; both are different from (Arrow)
alone, which would behave as (Arrow[__]&)
, i.e. SlotSequence[]
. That's why I suggested using #1
rather than #
: although they are perfectly equivalent, the latter makes the intended behavior more explicit.
$\endgroup$
Graph[{1, 2}, {Property[1 \[DirectedEdge] 2, EdgeStyle -> Red], Property[1 <-> 2, EdgeStyle -> Blue]}]
$\endgroup$