3

Sorry if this has been asked before, but I couldn't find something to address my particular issue. Everything I have seen (e.g. this) seems to assume particular pattern to the edges and nodes.

I have an arbitrary unweighted, undirected graph that I would like to draw. It can be specified entirely from its set of edges. I'm not especially fussed on the particular layout or look. I would prefer that the nodes are circles with the labels in the middle and that the graph grows out more horizontally than vertically to take better advantage of the page, but beyond that, I'm not really bothered and would prefer to leave as much as possible up to the layout engine.

The edges in question are [(1,2); (2,3); (3,4); (3,5); (3,6); (4, 7); (5, 9); (6,7); (6,10); (8,9); (9,10);]

I'm interested in TikZ solutions primarily, but if someone wants to suggest something else I'm listening.

I looked at the TikZ manual (both the big separate sections on graph drawing that I could find), as well as this blog post and other questions on this site, but nothing I have found seems to address the question for an arbitrary graph.

I have tried a couple of solutions already based on what I saw, but neither of them worked. Firstly, based on this question (I only included the first few edges while I experimented with this approach):

\documentclass{article}

\usepackage{tikz}
\usepackage{shellesc}

\usetikzlibrary{graphdrawing,graphs,external}
\tikzexternalize

    \begin{tikzpicture}[->,auto,main node/.style={circle,draw},node distance=3cm]
    \node[main node] (1) {1};
    \node[main node] (2) {2};
    \node[main node] (3) {3};
    \node[main node] (4) {4};
    \node[main node] (5) {5};
    \node[main node] (6) {6};
    \node[main node] (7) {7};
    \node[main node] (8) {8};
    \node[main node] (9) {9};
    \node[main node] (10) {10};

    \path[]
        (1) edge node (2)
        (2) edge node (3)
        (3) edge node (4);
    \end{tikzpicture}
\end{document}

but that seems to draw everything on top of each other. Secondly, and initially promisingly, based on something I saw somewhere (but forget where):

\documentclass{article}

\usepackage{tikz}
\usepackage{shellesc}

\usetikzlibrary{graphdrawing,graphs,external}
\tikzexternalize

    \begin{tikzpicture}[nodes={shape=circle,draw}]
    \graph {
    1 -- 2,
    2 -- 3,
    3 -- 4,
    3 -- 5,
    3 -- 6,
    4 -- 7,
    5 -- 9,
    6 -- 7,
    6 -- 10,
    8 -- 9,
    9 -- 10,
    };
    \end{tikzpicture}
\end{document}

but that seems to work well for the first two edges, then everything else just grows down the page with edges running right through all the other nodes.

Clearly, I am doing something badly wrong but I can't work out what. I would very much appreciate it if someone could please explain to me what I'm doing wrong and/or how I could actually achieve what I'm looking for (either by posting a sample or pointing me to the right place to look - nothing I have found gives a clear answer to this particular question). Thanks.

  • 2
    Welcome to TeX.SE! The first example you are quoting has seemingly innocent, but in fact important extras in it: the keys like below etc. If you omit them, of course everything will be drawn on top of each other since, if you do not specify coordinates, TikZ will take them to be (0,0). Could you perhaps explain or sketch a bit what you want to achieve? Also I am wondering how important externalize and shellesc are here. – user121799 Nov 7 '18 at 3:45
  • I'm just trying to produce an undirected graph to include in a paper as an example graph (for the 3-colouring problem). The precise layout of it is irrelevant to me, beyond that someone can clearly the how the nodes and edges fit together. Thus, I would prefer not to start telling the system precisely where everything should be laid out, if possible. I included the externalize part as part of the MWE (since that's how I'm doing it locally), but I could well believe that they're not relevant here - I'm not sure. – Jarak Nov 7 '18 at 3:57
2

My main problem is that I do not really know precisely what an undirected graph is. However, I have a few comments that my allow you to get what you want. First of all, if you want to make use of the graph drawing algorithms, you need to specify one. It turns out that these days you need a patch. Let me stress that this is highly unusual in LaTeX, but anyway with the patch this issue is solved. Now we need to agree on the algorithm. Here is an example:

\documentclass{article}
\usepackage{luacode}
\usepackage{tikz}

\usetikzlibrary{graphdrawing,graphs}
\begin{luacode*}
function pgf_lookup_and_require(name)
    local sep = package.config:sub(1,1)
    local function lookup(name)
        local sub = name:gsub('%.',sep)  
        if kpse.find_file(sub, 'lua') then
            require(name)
        elseif kpse.find_file(sub, 'clua') then
            collectgarbage('stop') 
            require(name)
            collectgarbage('restart')
        else
            return false
        end
        return true
    end
    return
        lookup('pgf.gd.' .. name .. '.library') or
        lookup('pgf.gd.' .. name) or
        lookup(name .. '.library') or
        lookup(name) 
end
\end{luacode*}
\usegdlibrary{force}
\begin{document}
\begin{tikzpicture}[nodes={shape=circle,draw}]
    \graph[spring layout] {
    1 -- 2,
    2 -- 3,
    3 -- 4,
    3 -- 5,
    3 -- 6,
    4 -- 7,
    5 -- 9,
    6 -- 7,
    6 -- 10,
    8 -- 9,
    9 -- 10,
    };
\end{tikzpicture}
\end{document}

enter image description here

To me it looks rather "undirected". However, if you give me more feedback I shall try to make it even more so.

If you want some randomness, you may want to do

\documentclass{article}
\usepackage{luacode}
\usepackage{tikz}

\usetikzlibrary{graphdrawing,graphs}
\begin{luacode*}
function pgf_lookup_and_require(name)
    local sep = package.config:sub(1,1)
    local function lookup(name)
        local sub = name:gsub('%.',sep)  
        if kpse.find_file(sub, 'lua') then
            require(name)
        elseif kpse.find_file(sub, 'clua') then
            collectgarbage('stop') 
            require(name)
            collectgarbage('restart')
        else
            return false
        end
        return true
    end
    return
        lookup('pgf.gd.' .. name .. '.library') or
        lookup('pgf.gd.' .. name) or
        lookup(name .. '.library') or
        lookup(name) 
end
\end{luacode*}
\usegdlibrary{force}
\begin{document}
\begin{tikzpicture}[nodes={shape=circle,draw}]
    \graph[spring layout,node distance=2cm] {
    1 -- 2[nudge up={(rand-0.5)*3mm},nudge right={(rand-0.5)*3mm}],
    2 -- 3[nudge up={(rand-0.5)*3mm},nudge right={(rand-0.5)*3mm}],
    3 -- 4[nudge up={(rand-0.5)*3mm},nudge right={(rand-0.5)*3mm}],
    3 -- 5[nudge up={(rand-0.5)*3mm},nudge right={(rand-0.5)*3mm}],
    3 -- 6[nudge up={(rand-0.5)*3mm},nudge right={(rand-0.5)*3mm}],
    4 -- 7[nudge up={(rand-0.5)*3mm},nudge right={(rand-0.5)*3mm}],
    5 -- 9[nudge up={(rand-0.5)*3mm},nudge right={(rand-0.5)*3mm}],
    6 -- 7,
    6 -- 10[nudge up={(rand-0.5)*3mm},nudge right={(rand-0.5)*3mm}],
    8 -- 9,
    9 -- 10,
    };
\end{tikzpicture}
\end{document}

enter image description here

  • 2
    An undirected graph is just a graph without arrows, just nodes and edges, precisely like what you provided. – YiFan Nov 7 '18 at 4:32
  • 1
    Yes, that's exactly what I was looking for! I was missing the force and spring layout parts - I had a vague idea of the spring layout, but not really how to use it. Thank you :) – Jarak Nov 8 '18 at 4:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.