I am struggling to write the correct pattern to match all ArrowBox objects with the relevant graphic directives in following snippet
{
Arrowheads[Medium], Directive[Opacity[0.7], Hue[0.6, 0.7, 0.5]],
{
Arrowheads[0.],
ArrowBox[BezierCurveBox[{1, {0.606341, 0.514848}, 2}], 0.0127299]
},
ArrowBox[BezierCurveBox[{1, {0.10576, 0.352183}, 3}], 0.0127299],
ArrowBox[BezierCurveBox[{2, {0.499413, 0.70158}, 3}], 0.0127299],
{
Arrowheads[0.],
ArrowBox[BezierCurveBox[{2, {0.500581, 1.03046}, 3}], 0.0127299]
},
ArrowBox[BezierCurveBox[{2, {0.890575, 0.349397}, 1}], 0.0127299],
ArrowBox[BezierCurveBox[{3, {0.391162, 0.515612}, 1}], 0.0127299]
}
To generate the same code, use this snippet which extracts it from a GraphicsComplexBox:
g = Block[{Identity},
Graph[{1 <-> 2, 2 <-> 3, 1 -> 3, 2 -> 1, 2 -> 3, 3 -> 1},
EdgeWeight -> Identity /@ {{0, 0}, {0, 0}, {1, 0}, {0, 1}, {1, 0}, {0, 1}}]];
Cases[ToBoxes[g], _GraphicsComplexBox, Infinity][[1, 2, 1]]
I try to improve the answer https://mathematica.stackexchange.com/a/169265/13042 so it works with other graphs as well. The following part of the solution in the referenced answer does not work as intended for the above given graph:
Cases[ToBoxes[g], {dir___, ar : Longest[__ArrowBox], ___} :>
(## & @@ Thread[{dir, {ar}}]), Infinity]
It returns
{
{
Arrowheads[0.],
ArrowBox[BezierCurveBox[{1, {0.606341, 0.514848}, 2}], 0.0127299]
},
{
Arrowheads[0.],
ArrowBox[BezierCurveBox[{2, {0.500581, 1.03046}, 3}], 0.0127299]
},
{
Arrowheads[Medium], Directive[Opacity[0.7], Hue[0.6, 0.7, 0.5]], Arrowheads[0.],
ArrowBox[BezierCurveBox[{1, {0.10576, 0.352183}, 3}], 0.0127299]
},
{
Arrowheads[Medium], Directive[Opacity[0.7], Hue[0.6, 0.7, 0.5]],
ArrowBox[BezierCurveBox[{1, {0.606341, 0.514848}, 2}], 0.0127299],
ArrowBox[BezierCurveBox[{2, {0.499413, 0.70158}, 3}], 0.0127299]
}
}
There are several issues
- the last two
ArrowBoxobjects are missing - contains a duplicate
ArrowBox, and - graphic directives are not properly handled.
The output should look like
{
{
Directive[Opacity[0.7], Hue[0.6, 0.7, 0.5]], Arrowheads[0.],
ArrowBox[BezierCurveBox[{1, {0.606341, 0.514848}, 2}], 0.0127299]
},
{
Arrowheads[Medium], Directive[Opacity[0.7], Hue[0.6, 0.7, 0.5]],
ArrowBox[BezierCurveBox[{1, {0.10576, 0.352183}, 3}], 0.0127299]},
{
Arrowheads[Medium], Directive[Opacity[0.7], Hue[0.6, 0.7, 0.5]],
ArrowBox[BezierCurveBox[{2, {0.499413, 0.70158}, 3}], 0.0127299]
},
{
Directive[Opacity[0.7], Hue[0.6, 0.7, 0.5]], Arrowheads[0.],
ArrowBox[BezierCurveBox[{2, {0.500581, 1.03046}, 3}], 0.0127299]
},
{
Arrowheads[Medium], Directive[Opacity[0.7], Hue[0.6, 0.7, 0.5]],
ArrowBox[BezierCurveBox[{2, {0.890575, 0.349397}, 1}], 0.0127299]
},
{
Arrowheads[Medium], Directive[Opacity[0.7], Hue[0.6, 0.7, 0.5]],
ArrowBox[BezierCurveBox[{3, {0.391162, 0.515612}, 1}], 0.0127299]
}
}
General scheme is
{
directivesLevel1,
RepeatedPattern[ primitive | {directivesLevel2, primitive}]
}
which should return with the replacement rule
{
{directivesLevel1, primitive} OR
{directiveslevel1, directivesLevel2, primitive},
...
}
Other graphs for more extensive testing
g2 = Block[{Identity},
Graph[{1 <-> 2, 1 <-> 3, 2 <-> 3, 2 <-> 4, 2 <-> 5, 4 <-> 5, 5 <-> 6, 3 <-> 6, 3 <-> 7,
6 <-> 7, 4 -> 3, 4 -> 1, 7 -> 2, 6 -> 4, 5 -> 1, 6 -> 1, 7 -> 1, 5 -> 7},
EdgeWeight -> Identity /@ Join[Table[{0, 0}, 10], {{1, 0}, {1, 0}, {0, 1}, {0, 1},
{1, 1}, {1, 1}, {0, 1}, {1, 0}}]]]
g3 = Block[{Identity},
Graph[{1 <-> 2, 1 <-> 3, 1 <-> 4, 1 <-> 6, 2 <-> 3, 3 <-> 4, 4 <-> 5, 4 <-> 6, 5 <-> 6,
1 -> 5, 2 -> 5, 2 -> 4, 5 -> 3, 6 -> 3, 6 -> 2},
EdgeWeight -> Identity /@ Join[Table[{0, 0}, 9], Table[{0, 1}, 3], Table[{1, 0}, 3]]]]
To see all errors, run
ClearAll[displayWeightedMultiGraph]
displayWeightedMultiGraph = Module[{i = 1, j, g = #, bcurves,
labels = PropertyValue[#, EdgeWeight],
gccoords = Cases[ToBoxes[#], GraphicsComplexBox[x_, y_, z___] :> x, Infinity][[1]]},
bcurves = Cases[ToBoxes[g], {dir___, ar : Longest[__ArrowBox], ___} :>
(## & @@ Thread[{dir, {ar}}]), Infinity] /.
{ArrowBox[BezierCurveBox[x_, y___], z___] :>
Arrow[BezierCurve[x /. k_Integer :> gccoords[[k]], y], z],
ArrowBox[x : {__}, y_] :> Arrow[gccoords[[x]], y]};
SetProperty[g, EdgeShapeFunction -> ({j = i++; Text[labels[[j]],
BezierFunction[#, SplineDegree -> 7][0.5]], bcurves[[j]]} &)]] &;
displayWeightedMultiGraph/@{g, g2, g3}
ArrowBox? – MarcoB Apr 16 '18 at 21:09g, it is much simpler to useShowto convert it to aGraphicsobject. Then, the functionNormalis documented to convert aGraphicsobject with aGraphicsComplexto one without anyGraphicsComplexobjects. The fact thatNormalfails is a bug and has already been covered in questions (105184) and (104818). – Carl Woll Apr 17 '18 at 15:18