3

I am using the TikZ+LuaTeX graph drawing library and enjoying it. I am trying to match a style where vertex labels are drawn outside the vertices. Here is an example:

graph drawing

(From Mathematics, a Discrete Introduction, by Edward R. Scheinerman. (C) 2012 Cengage Learning)

I thought I would be clever to make the node labels as graph nodes in disguise, with invisible edges to their corresponding nodes. But of course they are laid out as far away from their nodes as the rest of the nodes. I couldn't find a way to make specific edges naturally shorter while using the force graph drawing library.

So I decided to make the nodes for vertex labels also invisible, and manually place the node labels along the line segment between each actual node and its invisible label node. That has worked OK.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{graphs,graphdrawing}
\usegdlibrary{force}

\begin{document}


\begin{tikzpicture}
\begin{scope}[
    spring layout,
    node distance=2cm,
    vertex/.style={
        draw,circle,minimum size=1ex, inner sep=0pt
    }
] 
   \foreach \i in {1,...,6} {
% The actual nodes
       \draw node[vertex] (\i) {}
% vertex label directions as nodes
             node (\i-labeldir) {} 
             (\i) edge[draw=none] (\i-labeldir);
   }
% the actual edges
   \draw (1) edge (2) edge (3) edge (5) edge (6)
         (2) edge (3) edge (4)
         (3) edge (6);
\end{scope}
% the actual labels (can't be put in for loop?)
    \draw ($(1)!2ex!(1-labeldir)$) node {$1$}
      ($(2)!2ex!(2-labeldir)$) node {$2$}
      ($(3)!2ex!(3-labeldir)$) node {$3$}
      ($(4)!2ex!(4-labeldir)$) node {$4$}
      ($(5)!2ex!(5-labeldir)$) node {$5$}
      ($(6)!2ex!(6-labeldir)$) node {$6$}
      ;
% also: bounding box is too big
\end{tikzpicture}
\end{document}

sample code output

This is satisfying, but I'd prefer something a little cleaner. For instance,

  • the invisible nodes make the bounding box too big. I think I can take care of that with the fit library.

  • I couldn't get the node labels placed in a \foreach loop. This wasn't parsing:

      \foreach \i in {1,...,6} { \draw ($(\i)!2ex!(\i-labeldir)$) node {$\i$}; }
    
  • But mainly: is there really no way to set a specific edge's natural length to be different from the others in the spring layouts? I tried tweaking the spring constant, but that only seemed to have a global effect. I also tried the spring electrical layout, and tweaked the electrical charge of the label nodes, but that affects placement of other nodes too.

2
  • 1
    You could make the invisible nodes coordinates at least and/or add overlay to their option. Adding overlay to the edges doesn't seem to do anything, though. Commented Jun 10, 2023 at 11:28
  • 1
    By the way, with your code, the loop to place the $\i$ nodes does work but it needs to be after the scope. Commented Jun 13, 2023 at 21:56

2 Answers 2

3
+50

I don't like it either …

The overlay option seems to be ignored when the graphdrawing is placing nodes and edges.

Replacing the --[draw=none] edge by -!- screws up the whole diagram.

This works by overlaying the whole graph but saving all the nodes in a macro and fitting a not overlayed node around it, basically manually evaluating the bounding box. (This ignored all edges but unless they're only between “real” nodes, it should work …)

Code

% !TeX TS-program = lualatex
\documentclass[tikz]{standalone}
\usetikzlibrary{fit, graphs, graphdrawing, quotes}
\usegdlibrary{force}
\makeatletter
\tikzset{
  every picture/.append code={\let\tikz@graphs@bbnodes\pgfutil@empty},
  every picture/.append style={
    execute at end picture={\node[rectangle,path only,inner sep=+0pt,fit/.expanded=\tikz@graphs@bbnodes]{};}},
  save this node/.style={append after command=\pgfextra{\xdef\tikz@graphs@bbnodes{\tikz@graphs@bbnodes(\tikzlastnode)}}}}
\makeatother
\begin{document}
\tikz[vertex/.style={draw, circle, minimum size=1ex, inner sep=0pt, save this node}]
\graph[
  /tikz/overlay,
  spring layout,
  node distance=2cm,
  typeset =,
  edge quotes= {save this node}
]{
   \foreach \i in {1,...,6}{[parse/.expanded={% \i in quotes expansion issue
      \i[vertex] --[draw=none, "$\i$" near start] \i'[coordinate]}]},
   1 -- {2, 3, 5, 6},
   2 -- {3, 4},
   3 -- 6
};
\end{document}

Output

enter image description here

2
  • 1
    I haven't found an interface where overlay might be working (i.e. at the stage where the edge actually gets constructed and not just saved away until Lua has done its thing). Commented Jun 13, 2023 at 21:54
  • Thank you for this answer! I apologize for neglecting to manually award the bounty. Commented Jun 19, 2023 at 15:10
2

enter image description here

I defined a command \selabels that takes one argument (the number of vertices) and writes the labels you wish. It uses \tikzmath and a loop, of course. Otherwise, your initial code is not modified.

Remark. I don't know how to modify the length of the unseen edges.

The code

\documentclass[margin=10pt]{standalone} % {article} % 
\usepackage{tikz}
\usetikzlibrary{calc, math, fit}
\usetikzlibrary{graphs, graphdrawing}
\usegdlibrary{force}

\begin{document}

\newcommand{\setlabels}[1]{%
  \tikzmath{
    integer \i;
    coordinate \v;
    for \i in {1, ..., #1}{%
      \v = (\i-labeldir.center) -(\i.center);
      \t{\i} = {atan2(\vy, \vx)};
      {
        \path (\i.center) ++(\t{\i}:1.5ex) node {\i};
      };
    };
  }
}
\begin{tikzpicture}[every node/.style={scale=.7}]
  \begin{scope}[spring layout, node distance=2cm,
    vertex/.style={
      draw, circle, minimum size=1ex, inner sep=0pt
    }] 
    \foreach \i in {1,...,7} {
      \draw[] node[vertex] (\i) {} % actual nodes
      node (\i-labeldir) {} % vertex label directions as nodes
      (\i) edge[draw=none] (\i-labeldir);
    }
    % actual edges
    \draw
    (1) edge (2) edge (3) edge (5)
    (2) edge (3) edge (4)
    (3) edge (6) edge (7)
    (5) edge (7);
  \end{scope}
  % actual labels
  \setlabels{7}
\end{tikzpicture}
\end{document}

You must log in to answer this question.

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