6

I use the forest package to create a diagram similar to the one below. Is there any chance to reduce the distance between B5 and B6? I would prefer, if B6 and its subtree could be moved up. I have played around with the options l, s, l sep, s sep and fit without success so far. Actually I thought the default value fit=tight should do the job, but it does not...

enter image description here

Source for example diagram:

\documentclass{standalone} \usepackage{forest} \begin{document} \begin{forest} for tree={fit=tight} [A, grow'=east [B1, [B2, [B3, [B4, [B5, [B6, grow'=east, [C, grow'=east, [D1, for tree={grow=north}, [D2, [D3 ]]] [E1, for tree={grow=south}, [E2 ]]]]]]]]]] \end{forest} \end{document} 

Source for full diagram:

\documentclass{standalone} \usepackage{forest} % Document \begin{document} \begin{forest} for tree={anchor=center} [FB, grow'=east [BJ$_X$ [BJ$_Y$ [BJ$_Z$ [BJ$_X$ [BJ$_Y$ [BJ$_Z$, grow'=east [F, grow'=east [LLJ$_X$, for tree={grow=north} [LLJ$_Z$ [F, grow=east [FT, for tree={grow=south}, [WMJ$_{ABD}$, [WM$_{ABD}$]]] [ABD, for tree={grow=north} [ULJ$_X$ [ULJ$_Y$ [ULJ$_Z$ [F, grow=east [FT, for tree={grow=south}, [WMJ$_{THO}$, [WM$_{THO}$]]] [THO, for tree={grow=north} [F, grow'=east [F, grow'=east [LNJ$_X$, [LNJ$_Y$, [LNJ$_Z$, [HEA, for tree={grow=north}, [EP]]]]] [SJ$_{L,X}$, for tree={grow=south}, [SJ$_{L,Y}$, [SJ$_{L,Z}$, [UPA$_L$, [EJ$_{L,Z}$, [LOA$_L$, [EP]]]]]]] ] [SJ$_{R,X}$, for tree={grow=south}, [SJ$_{R,Y}$, [SJ$_{R,Z}$, [UPA$_R$, [EJ$_{R,Z}$, [LOA$_R$, [EP]]]]]]] ]]]]]]]]]] [PEL, for tree={grow=south} [F, grow=south [HJ$_{L,X}$, [HJ$_{L,Y}$, [HJ$_{L,Z}$, [THI$_L$, [KJ$_{L,Z}$, [SHA$_L$, [AJ$_{L,X}$, [AJ$_{L,X}$, [AJ$_{L,X}$, [F, grow'=east, [COPJ$_{L,X}$, for tree={grow=north}, [COPJ$_{L,Y}$, [COPJ$_{L,Z}$, [COP$_L$]]]], [FOO$_L$, [EP]]]]]]]]]]]] [HJ$_{R,X}$, [HJ$_{R,Y}$, [HJ$_{R,Z}$,, [THI$_R$, [KJ$_{R,Z}$, [SHA$_R$, [AJ$_{R,X}$, [AJ$_{R,X}$, [AJ$_{R,X}$, [F, grow'=east, [COPJ$_{R,X}$, for tree={grow=north}, [COPJ$_{R,Y}$, [COPJ$_{R,Z}$, [COP$_R$]]]], [FOO$_R$, [EP]]]]]]]]]]]] ]]]]]]]]]] \end{forest} \end{document} 
6
  • 1
    Does for tree={fit=tight,l sep=-30mm} help? Commented Apr 22, 2017 at 13:48
  • Using l sep=-30mm, will reduce the longest line between B5 and B6, but it won't reduce the other lines any further ... at least not in my tests. Commented Apr 22, 2017 at 13:58
  • Thank you for your quick responses. l sep=-30mm works fine for the given example. Unfortunately not for my actual diagram (I added the source to the question). So probably I have to play around with l sep for each node? Commented Apr 22, 2017 at 14:15
  • You can increase it to l sep=-200mm... Maybe it creates other line problems. But do you really need such big diagram? I Commented Apr 22, 2017 at 14:32
  • Well, I was able to tune the distances by setting l sep+=5mm for the F nodes and l sep=-300mm for the others. Thank you again! If you put your comment in an answer, I am happy to accept it :) Commented Apr 22, 2017 at 14:48

2 Answers 2

6

To be honest, I'm not sure this is much of an improvement. However, it is a lot clearer what is going on and the code is considerably less cluttered. It is also slightly more compact (both width and height/depth are smaller than in the OP's solution). Whether any of this is of any importance is, of course, another matter.

\documentclass[border=10pt]{standalone} \usepackage{forest} \usetikzlibrary{matrix} \tikzset{ fixedBase/.style={draw, circle, fill=black, text=white}, prismaticJoint/.style={draw}, revoluteJoint/.style={draw, rounded corners=2mm}, rigidLink/.style={draw, color=blue, fill=blue, text=white}, fixedTranslation/.style={draw, fill=gray}, fixedRotation/.style={draw, fill=gray, rounded corners=2mm}, springDamperElement/.style={draw, circle, color=blue, fill=blue, text=white}, fork/.style={draw, circle, color=red, fill=red, text=white}, endpoint/.style={draw, fill=black, text=white}, } \newsavebox\treelegend \setbox0=\hbox{% solution from Steven B. Segletes: https://tex.stackexchange.com/a/366710/ \begin{tikzpicture} \matrix [matrix of nodes, column 2/.style={text height=3.5mm, text depth=3.5mm, text width=40mm}] {% |[fixedBase]| F8 & Fixed base \\ |[prismaticJoint]| PJ & Prismatic joint \\ |[revoluteJoint]| RJ & Revolute joint \\ |[rigidLink]| RL & Rigid link \\ |[fixedTranslation]| FT & Fixed translation \\ |[springDamperElement]| SD & Spring-damper element \\ |[fork]| F & Fork \\ |[endpoint]| EP & Endpoint \\ }; \end{tikzpicture}% } \savebox\treelegend{\copy0} \begin{document} \begin{forest} fork/.style={ /tikz/fork, before computing xy={for children={l'+=8mm}}, }, for tree={ anchor=center }, before computing xy={ for tree={l'=9mm}, } [FB, fixedBase, grow'=east, anchor=east [BJ$_X$, prismaticJoint, for tree={grow=north} [BJ$_Y$, prismaticJoint [BJ$_Z$, prismaticJoint [BJ$_X$, revoluteJoint [BJ$_Y$, revoluteJoint [BJ$_Z$, revoluteJoint, grow'=east [F, fork, grow'=east, before computing xy={for children={l'+=5mm}} [LLJ$_X$, revoluteJoint, for tree={grow=north} [LLJ$_Z$, revoluteJoint [F, fork, grow=east [FT, fixedTranslation, for tree={grow=south} [WMJ$_{ABD}$, prismaticJoint [SD, springDamperElement, before computing xy={l'=0pt, s'=15mm}] [EP, endpoint, before computing xy={l=10mm, s'=0pt}] ] ] [ABD, rigidLink, for tree={grow=north} [ULJ$_X$, revoluteJoint [ULJ$_Y$, revoluteJoint [ULJ$_Z$, revoluteJoint [F, fork, grow=east [FT, fixedTranslation, for tree={grow=south} [WMJ$_{THO}$, prismaticJoint [SD, springDamperElement, before computing xy={l'=0pt, s'=15mm}] [EP, endpoint, before computing xy={l=10mm, s'=0pt}] ] ] [THO, rigidLink, for tree={grow=north} [F, fork, grow'=east, before computing xy={for children={l'+=10mm}} [F, fork, grow'=east [LNJ$_X$, revoluteJoint [LNJ$_Y$, revoluteJoint [LNJ$_Z$, revoluteJoint [HEA, rigidLink, for tree={grow=north} [EP, endpoint] ] ] ] ] [SJ$_{L,X}$, revoluteJoint, for tree={grow=south} [SJ$_{L,Y}$, revoluteJoint [SJ$_{L,Z}$, revoluteJoint [UPA$_L$, rigidLink [EJ$_{L,Z}$, revoluteJoint [LOA$_L$, rigidLink [EP, endpoint] ] ] ] ] ] ] ] [SJ$_{R,X}$, revoluteJoint, for tree={grow=south} [SJ$_{R,Y}$, revoluteJoint [SJ$_{R,Z}$, revoluteJoint [UPA$_R$, rigidLink [EJ$_{R,Z}$, revoluteJoint [LOA$_R$, rigidLink [EP, endpoint] ] ] ] ] ] ] ]]]]]]]]] ] [PEL, rigidLink, for tree={grow=south} [F, fork, grow=south, before packing={s sep'+=5mm}, before computing xy={for children={l'-=5mm}} [HJ$_{L,X}$, revoluteJoint [HJ$_{L,Y}$, revoluteJoint [HJ$_{L,Z}$, revoluteJoint [THI$_L$, rigidLink [KJ$_{L,Z}$, revoluteJoint [SHA$_L$, rigidLink [AJ$_{L,X}$, revoluteJoint [AJ$_{L,Y}$, revoluteJoint [AJ$_{L,Z}$, revoluteJoint [F, fork, grow'=east [COPJ$_{L,X}$, prismaticJoint, for tree={grow=north} [COPJ$_{L,Y}$, prismaticJoint [COPJ$_{L,Z}$, prismaticJoint [EP, endpoint] ] ] ] [FOO$_L$, rigidLink [EP, endpoint] ] ] ] ] ] ] ] ] ] ] ] [HJ$_{R,X}$, revoluteJoint [HJ$_{R,Y}$, revoluteJoint [HJ$_{R,Z}$, revoluteJoint [THI$_R$, rigidLink [KJ$_{R,Z}$, revoluteJoint [SHA$_R$, rigidLink [AJ$_{R,X}$, revoluteJoint [AJ$_{R,Y}$, revoluteJoint [AJ$_{R,Z}$, revoluteJoint [F, fork, grow'=east [COPJ$_{R,X}$, prismaticJoint, for tree={grow=north} [COPJ$_{R,Y}$, prismaticJoint [COPJ$_{R,Z}$, prismaticJoint [EP, endpoint] ] ] ] [FOO$_R$, rigidLink [EP, endpoint] ] ] ] ] ] ] ] ] ] ] ] ] ]]]]]]]] ] \node [anchor=north west] at (current bounding box.north west) {\usebox{\treelegend}}; \end{forest} \end{document} 

which-way tree

1
  • @JotWe I've also left a message in the Forest chat room as I'm not clear whether it is expected that this much manual intervention is needed i.e. that Forest gets confused very quickly. But I think Forest's author is not around just at the moment. Commented Apr 26, 2017 at 19:48
3

Ok, thank you Bobyandbob and Tina for providing the initial hint. The option l sep was the key. Here is the code and diagram I finally came up with. I had to use some before computing xy, but I like the result.

enter image description here

\documentclass{standalone} \usepackage{forest} \begin{document} \forestset{ fixedBase/.style={draw, circle, fill=black, text=white}, prismaticJoint/.style={draw}, revoluteJoint/.style={draw, rounded corners=2mm}, rigidLink/.style={draw, color=blue, fill=blue, text=white}, fixedTranslation/.style={draw, fill=gray}, fixedRotation/.style={draw, fill=gray, rounded corners=2mm}, springDamperElement/.style={draw, circle, color=blue, fill=blue, text=white}, fork/.style={draw, circle, color=red, fill=red, text=white}, endpoint/.style={draw, fill=black, text=white}, } \begin{forest} for tree={anchor=center} [FB, fixedBase, l sep=-300mm, grow'=east, [FB, fixedBase, edge'={}, grow'=east, before computing xy={l=5mm, s=160mm}, [Fixed base, edge'={}, anchor=west, before computing xy={l=5mm, s=0}]], [PJ, prismaticJoint, edge'={}, grow'=east, before computing xy={l=5mm, s=150mm}, [Prismatic joint, edge'={}, anchor=west, before computing xy={l=5mm, s=0}]], [RJ, revoluteJoint, edge'={}, grow'=east, before computing xy={l=5mm, s=140mm}, [Revolute joint, edge'={}, anchor=west, before computing xy={l=5mm, s=0}]], [RL, rigidLink, edge'={}, grow'=east, before computing xy={l=5mm, s=130mm}, [Rigid link, edge'={}, anchor=west, before computing xy={l=5mm, s=0}]], [FT, fixedTranslation, edge'={}, grow'=east, before computing xy={l=5mm, s=120mm}, [Fixed translation, edge'={}, anchor=west, before computing xy={l=5mm, s=0}]], [SD, springDamperElement, edge'={}, grow'=east, before computing xy={l=5mm, s=110mm}, [Spring-damper element, edge'={}, anchor=west, before computing xy={l=5mm, s=0}]], [F, fork, edge'={}, grow'=east, before computing xy={l=5mm, s=100mm}, [Fork, edge'={}, anchor=west, before computing xy={l=5mm, s=0}]], [EP, endpoint, edge'={}, grow'=east, before computing xy={l=5mm, s=90mm}, [Endpoint, edge'={}, anchor=west, before computing xy={l=5mm, s=0}]], [BJ$_X$, prismaticJoint, l sep=-300mm, for tree={grow=north}, before computing xy={l=12mm, s=0}, [BJ$_Y$, prismaticJoint, l sep=-300mm, [BJ$_Z$, prismaticJoint, l sep=-300mm, [BJ$_X$, revoluteJoint, l sep=-300mm, [BJ$_Y$, revoluteJoint, l sep=-300mm, [BJ$_Z$, revoluteJoint, l sep=-300mm, grow'=east, [F, fork, grow'=east, [LLJ$_X$, revoluteJoint, l sep=-300mm, for tree={grow=north}, [LLJ$_Z$, revoluteJoint, l sep=-300mm, [F, fork, grow=east, [FT, fixedTranslation, for tree={grow=south}, [WMJ$_{ABD}$, prismaticJoint, [SD, springDamperElement, before computing xy={l=0, s=15mm}], [EP, endpoint, before computing xy={l=10mm, s=0}]]], [ABD, rigidLink, l sep=-300mm, for tree={grow=north}, [ULJ$_X$, revoluteJoint, l sep=-300mm, [ULJ$_Y$, revoluteJoint, l sep=-300mm, [ULJ$_Z$, revoluteJoint, l sep=-300mm, [F, fork, grow=east, [FT, fixedTranslation, for tree={grow=south}, [WMJ$_{THO}$, prismaticJoint, [SD, springDamperElement, before computing xy={l=0, s=15mm}], [EP, endpoint, before computing xy={l=10mm, s=0}]]], [THO, rigidLink, l sep=-300mm, for tree={grow=north}, [F, fork, l sep+=15mm, grow'=east, [F, fork, l sep+=5mm, grow'=east, [LNJ$_X$, revoluteJoint, [LNJ$_Y$, revoluteJoint, [LNJ$_Z$, revoluteJoint, [HEA, rigidLink, for tree={grow=north}, [EP, endpoint]]]]], [SJ$_{L,X}$, revoluteJoint, for tree={grow=south}, [SJ$_{L,Y}$, revoluteJoint, [SJ$_{L,Z}$, revoluteJoint, [UPA$_L$, rigidLink, [EJ$_{L,Z}$, revoluteJoint, [LOA$_L$, rigidLink, [EP, endpoint]]]]]]], ], [SJ$_{R,X}$, revoluteJoint, for tree={grow=south}, [SJ$_{R,Y}$, revoluteJoint, [SJ$_{R,Z}$, revoluteJoint, [UPA$_R$, rigidLink, [EJ$_{R,Z}$, revoluteJoint, [LOA$_R$, rigidLink, [EP, endpoint]]]]]]], ]]]]]]]]]], [PEL, rigidLink, for tree={grow=south}, [F, fork, grow=south, [HJ$_{L,X}$, revoluteJoint, l sep=-300mm, [HJ$_{L,Y}$, revoluteJoint, l sep=-300mm, [HJ$_{L,Z}$, revoluteJoint, l sep=-300mm, [THI$_L$, rigidLink, l sep=-300mm, [KJ$_{L,Z}$, revoluteJoint, l sep=-300mm, [SHA$_L$, rigidLink, l sep=-300mm, [AJ$_{L,X}$, revoluteJoint, l sep=-300mm, [AJ$_{L,Y}$, revoluteJoint, l sep=-300mm, [AJ$_{L,Z}$, revoluteJoint, l sep=-300mm, [F, fork, grow'=east, [COPJ$_{L,X}$, prismaticJoint, for tree={grow=north}, [COPJ$_{L,Y}$, prismaticJoint, [COPJ$_{L,Z}$, prismaticJoint, [EP, endpoint]]]], [FOO$_L$, rigidLink, [EP, endpoint]]]]]]]]]]]], [HJ$_{R,X}$, revoluteJoint, l sep=-300mm, [HJ$_{R,Y}$, revoluteJoint, l sep=-300mm, [HJ$_{R,Z}$, revoluteJoint, l sep=-300mm, [THI$_R$, rigidLink, l sep=-300mm, [KJ$_{R,Z}$, revoluteJoint, l sep=-300mm, [SHA$_R$, rigidLink, l sep=-300mm, [AJ$_{R,X}$, revoluteJoint, l sep=-300mm, [AJ$_{R,Y}$, revoluteJoint, l sep=-300mm, [AJ$_{R,Z}$, revoluteJoint, l sep=-300mm, [F, fork, grow'=east, [COPJ$_{R,X}$, prismaticJoint, for tree={grow=north}, [COPJ$_{R,Y}$, prismaticJoint, [COPJ$_{R,Z}$, prismaticJoint, [EP, endpoint]]]], [FOO$_R$, rigidLink, [EP, endpoint]]]]]]]]]]]], ]]]]]]]]]] \end{forest} \end{document} 
9
  • I think you could prune this quite a bit. l sep=-300mm doesn't make much sense. I would rename fork, if I were you, to avoid confusion with forked edge. I mean, technically, fork is fine. But I would find it potentially confusing. Commented Apr 22, 2017 at 19:10
  • Thanks for the comment. I agree with you that it might be confusing, but these are predefined terms from a modeling library I used. Commented Apr 23, 2017 at 9:26
  • I was more concerned about l sep=-300mm. Since l sep is the minimum separation permitted between levels, what would this mean? That the next level always precede its parent by at least 0.3m? Commented Apr 23, 2017 at 22:05
  • 1
    Yes, the approach is quite 'hacky' and probably just tricks the placing algorithm. Do you think there is a better solution? Commented Apr 24, 2017 at 7:55
  • 1
    When I implemented the graph, it was very convenient to use the syntax of the forest package in order to get the general form. In a second step I started to care about the look and placed some of the nodes manually to make it more compact. The legend is definitely a pretty dirty hack, but because I use it as a standalone figure, compilation time is not that important. Commented Apr 25, 2017 at 19:15

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.