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
ArrowBox
objects 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
? $\endgroup$g
, it is much simpler to useShow
to convert it to aGraphics
object. Then, the functionNormal
is documented to convert aGraphics
object with aGraphicsComplex
to one without anyGraphicsComplex
objects. The fact thatNormal
fails is a bug and has already been covered in questions (105184) and (104818). $\endgroup$