1

Consider following graph created with the GUI tool LaTeXDraw:

enter image description here

I want to create a similar graph with tikz. This is how far I got:

%! TEX program = lualatex
\documentclass{article}
\usepackage{tikz}
\usepackage[graphics, active, tightpage]{preview}
\PreviewEnvironment{tikzpicture}
\usetikzlibrary{graphs,graphdrawing}
\usegdlibrary{layered}

\begin{document}
\begin{tikzpicture}
  \graph [layered layout] {
  { [edge={draw=none}] 12 -> 6 -> 4 -> 3 -> 2};
  { [same layer] 12, a/17 },
  { [same layer] 6, b/16,c/14,d/15 },
  { [same layer] 4, e/9 },
  { [same layer] 3, f/13 },
  { [same layer] 2, g/2, h/5 },
  a -- { b -- {f,g}, c -- {f,h}, d -- {f,h}, e -- {g,h}};
};
\end{tikzpicture}
\end{document}

enter image description here

The most important and for my case semantic difference is that I have not yet added the multi-edge between 9 and 5 and that the edges do not start and end at common points. However, I need additionally the possibility to specify for a few edges (here one) different start and end points (minimal offset) at the vertices. In my case this has meaning. You can see this in the first LaTeXDraw picture at vertex 9 and 5 and in the second LaTeXDraw picture for the edges 52-13, 17-3, 34-7, 30-7, 33-7.

The graphs are not too complex (as given) which means I do not mind to place manually nodes and edges.

In other graph drawing tools/formats this is typically called ports (graphviz, graphml, yfiles/yed).

Second Update

(first update moved into my own answer)

A more complicated case would look like:

enter image description here

Related Questions:

2 Answers 2

2

Here is a solution using tikz-cd. The arrow option dash uses no arrowhead; the option equals gives you the double line.

enter image description here

\documentclass{article}

\usepackage{tikz-cd}

\begin{document}
\begin{tikzcd}[column sep=1cm,row sep=1cm,start anchor=south,end anchor=north]
    12 & & & 17\arrow[dash,dll]\arrow[dash,dl]\arrow[dash,d]\arrow[dash,ddrr] \\
    6 & 16\arrow[dash,ddr]\arrow[dash,dddrrr] & 14\arrow[dash,dd]\arrow[dash,dddrrr] & 15\arrow[dash,ddl]\arrow[dash,dddrr] \\
    4 & & & & & 9\arrow[dash,ddl]\arrow[equals,dd] \\
    3 & & 13 \\
    2 & & & & 2 & 5
\end{tikzcd}
\end{document}

If you want to shift the double line to the right so that the lines from 14 and 15 meet the left line, the xshift option can be used: \arrow[xshift=.3mm,equals,dd]

For a more complicated example, the double lines can be implemented manually by placing two lines parallel (using xshift). This takes some playing around to get things how you like.

enter image description here

Here is the code:

\documentclass{article}

\usepackage{tikz-cd}

\begin{document}

\begin{tikzcd}[column sep=1cm,row sep=2cm,start anchor=south,end anchor=north]
    &&&&&52\arrow[dash,dlllll]
            \arrow[dash,dlll]
            \arrow[dash,dl]
            \arrow[dash,dr]
            \arrow[dash,drrr,end anchor={[xshift=-1.6mm]north}]
            \arrow[dash,drrr,start anchor={[xshift=1.6mm]south}]
            \arrow[dash,drrrrr,start anchor={[xshift=1.6mm]south}]\\
    17\arrow[dash,drr,end anchor={[xshift=-1.2mm]north}]
            \arrow[dash,drr,start anchor={[xshift=1.2mm]south}]&&
        34\arrow[dash,d]
            \arrow[dash,drrrr,end anchor={[xshift=-3.4mm]north}]
            \arrow[dash,drrrr,start anchor={[xshift=2.2mm]south},end anchor={[xshift=-1.2mm]north}]&&
        30\arrow[dash,dll,start anchor={[xshift=.3mm]south}]
            \arrow[dash,drr,start anchor={[xshift=.3mm]south},end anchor={[xshift=-1.1mm]north}]
            \arrow[dash,drr,start anchor={[xshift=1.7mm]south},end anchor={[xshift=.3mm]north}]&&
        33\arrow[dash,dll,start anchor={[xshift=.3mm]south}]
            \arrow[dash,d,xshift=.3mm]
            \arrow[dash,d,xshift=1mm]&&
        13\arrow[dash,dllllll]
            \arrow[dash,dll,end anchor={[xshift=1mm]north}]&&
        14\arrow[dash,dllllll]
            \arrow[dash,dllll,end anchor={[xshift=1mm]north}]
            \arrow[dash,dll]\\
    &&3&&4&&7&&2
\end{tikzcd}

\end{document}
4
  • Thanks for your answer. But I am afraid that your solution also only works very well for my first simple example. Please see the second update of my question showing a more complicated graph. This one should illustrate more clearly what kind of graph drawing problem I am asking about. See in particular vertex 7.
    – Hotschke
    May 17, 2018 at 8:48
  • I updated my answer with the more complicated graph.
    – Sandy G
    May 17, 2018 at 15:54
  • I should really consider using tikz-cd for such kind of graphs. My previous comment was totally ignorant. Sorry. Thanks for your effort to actually create the more complicated graph. I would have hoped that something similar as end anchor={[xshift=1mm]north} would be possible in the tikzlibrary graphs/graphdrawing. One short question: Could the shared option dash moved to the options given to the environment tikzcd?
    – Hotschke
    May 18, 2018 at 6:51
  • The option dash can be moved to tikzcd environment as arrows={dash}.
    – Hotschke
    May 20, 2018 at 12:41
1

Workaround

One possible workaround is to use one shared anchor point with the setting head anchor=north, tail anchor=south and add shifted parallel edges manually. The vertex labels are available as coordinates which makes it convenient to refer to them.

However, this does not easily extend to more complicated graphs. But right now for the five graphs I have in mind this works.

The following solution also solves the problem of non-straight edges with \graph[edges={bend left=0}] and adjusts node positioning with nudge left/right=....

%! TEX program = lualatex
\RequirePackage{luatex85}
\documentclass[tikz]{standalone}
\usetikzlibrary{graphs,graphdrawing}
\usegdlibrary{layered}

\begin{document}
\begin{tikzpicture}
  \graph[
      layered layout,
      head anchor=north,
      tail anchor=south,
      edges={bend left=0},
  ]{
    { [edge={draw=none}] 12 -> 6 -> 4 -> 3 -> 2}; 
    { [same layer] 12, a/17 },
    { [same layer] 6, b/16,c/14,d/15 },
    { [same layer] 4, e/9 },
    { [same layer] 3, f/13 },
    { [same layer] 2, g/2, h/5 },
    a -- {
      b -- {f[nudge right=10mm], g[nudge left=25mm]},
      c -- {f, h[nudge left=20mm]},
      d -- {f, h},
      e -- {g, h}
    };
  };
  % Add manually parallel edge:
  \draw ([xshift=2pt]e.south) -- ([xshift=2pt]h.north);
\end{tikzpicture}
\end{document}

enter image description here

Note

Local adjustments for head anchor and tail anchor as given in https://tex.stackexchange.com/a/287300/8917 do not work for me:

\graph [tree layout, grow'=right, 
        fresh nodes, level distance=0.5in,
        sibling distance=0.1in]
    {
        4 -> {
          3 -> { 1 -> { 5, " " }, 2,2 },
          3 -> { 1, 2, 2 },
          3 -> [head anchor=west]{ 1, 2, 2222}
        }
    };

Update: Workaround applied to more complicated example

%! TEX program = lualatex
\documentclass{article}
\usepackage{tikz}
\usepackage[graphics, active, tightpage]{preview}
\PreviewEnvironment{tikzpicture}

\usetikzlibrary{graphs,graphdrawing}
\usegdlibrary{layered}
\usegdlibrary{more-crossing-algorithms}
% needs files 'more-crossing-algorithms.lua' and 'noCrossing.lua'
% from https://tex.stackexchange.com/a/180045/8917

\begin{document}
\begin{tikzpicture}
  \graph[
    layered layout,
    no crossing minimization,
    head anchor=north,
    tail anchor=south,
    level distance=1.5cm,
    edges={bend left=0},
  ]{
    % Determine layer and order manually
    { [same layer] 52 },
    { [same layer] 17, 34, 30, 33, 13, 14 },
    { [same layer] 3, 4, 7, 2 },
    % Draw graph with edges disabled
    { [edge={draw=none}] 
    52 -- { 
      17 -- {3[nudge left=1.25cm], 4[nudge left=1.25cm]},
      34 -- {3, 7[nudge left=0.25cm]},
      30 -- {3, 7},
      33 -- {4, 7},
      13 -- {3, 7},
      14 -- {4, 7, 2[nudge right=0.05cm]}
    }};
  };
  % Add the 24 edges manually:
  % Starting from 52
  \draw ([xshift=-1pt]52.south) -- (17.north);
  \draw ([xshift=-1pt]52.south) -- (34.north);
  \draw ([xshift=-1pt]52.south) -- (30.north);
  \draw ([xshift=-1pt]52.south) -- (33.north);
  \draw ([xshift=-1pt]52.south) -- ([xshift=-1pt]13.north);
  \draw ([xshift=+1pt]52.south) -- ([xshift=+1pt]13.north);
  \draw ([xshift=+1pt]52.south) -- (14.north);
  % Starting from 17
  \draw ([xshift=-1pt]17.south) -- ([xshift=-1pt]3.north);
  \draw ([xshift=+1pt]17.south) -- ([xshift=+1pt]3.north);
  \draw ([xshift=+1pt]17.south) -- (4.north);
  % Starting from 34
  \draw ([xshift=-1pt]34.south) -- ([xshift=+1pt]3.north);
  \draw ([xshift=-1pt]34.south) -- ([xshift=-3pt]7.north);
  \draw ([xshift=+1pt]34.south) -- ([xshift=-1pt]7.north);
  % Starting from 30
  \draw ([xshift=-1pt]30.south) -- ([xshift=+1pt]3.north);
  \draw ([xshift=-1pt]30.south) -- ([xshift=-1pt]7.north);
  \draw ([xshift=+1pt]30.south) -- ([xshift=+1pt]7.north);
  % Starting from 33
  \draw ([xshift=-1pt]33.south) -- (4.north);
  \draw ([xshift=-1pt]33.south) -- ([xshift=+1pt]7.north);
  \draw ([xshift=+1pt]33.south) -- ([xshift=+3pt]7.north);
  % Starting from 13
  \draw (13.south) -- ([xshift=+1pt]3.north);
  \draw (13.south) -- ([xshift=+3pt]7.north);
  % Starting from 14
  \draw (14.south) -- (4.north);
  \draw (14.south) -- ([xshift=+3pt]7.north);
  \draw (14.south) -- (2.north);
\end{tikzpicture}       
\end{document}

enter image description here

This uses the answer from https://tex.stackexchange.com/a/180045/8917 to manually set the order of nodes in a layer. A possible improvement would be to write a node placement algorithm which simply distributes the nodes evenly in a layer.

1
  • Overwrite the edge by \draw[double] (e) -- (h) is probably simple and it works even if (e) is not straight above (h).
    – Kpym
    May 17, 2018 at 6:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .