Bug introduced in 8.0 or earlier and persisting through 11.3 or later
I am trying to control the style for edge labels in treeplot and have run into a problem.
Consider these two graphs:
edges1 = {{1 -> 2,"Test"}, 2 -> 3}
edges2 = {{1 -> 2,"Test"}, 2 -> 3, 1 -> 4}
If I plot the first then the labeled edge displays correctly:
TreePlot[edges1, BaseStyle-> 20]
But if I plot the second it slants the text:
TreePlot[edges2, BaseStyle-> 20]
Anyone have any insight how to stop the second behavior?
Edit
Here is a more complicated example showing how it slants the text in both directions and in different amounts (Note that in actuality my edges have different labels)
edges = {{1 -> 2, "Test"}, {1 -> 3, "Test"}, {2 -> 14,
"Test"}, {3 -> 4, "Test"}, {4 -> 99, "Test"}, {3 -> 6,
"Test"}, {6 -> 7, "Test"}, {6 -> 8, "Test"}, {7 -> 9,
"Test"}, {8 -> 10, "Test"}, {8 -> 11, "Test"}, {10 -> 12,
"Test"}, {11 -> 13, "Test"}};
edges[[All, 2]] = Map[Panel@Style[#, 12] &, edges[[All, 2]]];
TreePlot[edges, Top, 1, AspectRatio -> 1/3]
**Edit 2 ** Combining M.R.'s solution and LayerSizeFunction I can somewhat still control the aspect ratio, but Mr. Wizard's solution is much better
M.R. + LayerSizeFunction:
DeleteCases[TreePlot[edges, Top, 1, LayerSizeFunction -> (1/4 # &)], AspectRatio -> _]
Mr. Wizard:
edges3 = {{1 -> 2, "Test"}, {1 -> 3, "Test"}, {2 -> 14,
"Test"}, {3 -> 4, "Test"}, {4 -> 99, "Test"}, {3 -> 6,
"Test"}, {6 -> 7, "Test"}, {6 -> 8, "Test"}, {7 -> 9,
"Test"}, {8 -> 10, "Test"}, {8 -> 11, "Test"}, {10 -> 12,
"Test"}, {11 -> 13, "Test"}};
TreePlot[edges3, Top, 1, AspectRatio -> 1/3, EdgeRenderingFunction -> ({Line[#1],
If[#3 === None, {}, Text[Panel@Style[#3, 16], Mean@#1]]} &)]
Answer
The labels are implemented in terms of Arrowheads
and Inset
in a rather strange way. One fix is to render the labels manually with a custom EdgeRenderingFunction
:
TreePlot[edges2, BaseStyle -> 20,
EdgeRenderingFunction ->
({Line[#1], If[#3 === None, {}, Text[Panel@#3, Mean@#1]]} &)
]
Regarding the default rendering, an arrowhead normally points in the direction of the arrow and therefore the labels, implemented as Arrowheads, would also point in the direction of the line. The fifth argument of Inset
is used to compensate for this but the implementation is flawed. You can see the default alignment with:
TreePlot[edges2, BaseStyle -> 20] /.
Inset[a_, b_, c_, d_, DIR_, opts__] :> Inset[a, b, c, d, opts]
Solution
We can correct the fifth argument from None
to {None, None}
like this:
edges = {{1 -> 2, "Test"}, {1 -> 3, "Test"}, {2 -> 14,
"Test"}, {3 -> 4, "Test"}, {4 -> 99, "Test"}, {3 -> 6,
"Test"}, {6 -> 7, "Test"}, {6 -> 8, "Test"}, {7 -> 9,
"Test"}, {8 -> 10, "Test"}, {8 -> 11, "Test"}, {10 -> 12,
"Test"}, {11 -> 13, "Test"}};
edges[[All, 2]] = Map[Panel[Style[#, 12], FrameMargins -> 2] &, edges[[All, 2]]];
TreePlot[edges, Top, 1, AspectRatio -> 1/3] /.
Inset[a__, None, opts___] :> Inset[a, {None, None}, opts]
Comments
Post a Comment