1

I have to draw a lot of graphs with a lot of edges. Some of the nodes are connected via edges in one direction, some in both. Edges that come from specific nodes are painted red, while the edges going into these nodes are painted black. Now I have two thinks I'd like to change to make the graphs more easy to understand:

  • If two nodes are connected in both ways change the two arrows <-- and --> into one <--> (the differences are small but they bug me).
  • If two nodes are connected in both ways, and one is one with the outgoing nodes in red automaticaly draw two arrows, either slightly bend or shifted, one in black one in red.

Its important, that this is done automaticaly, so that the results look always the same, independent from the slope of the connection. Here is my current code with the result:

\documentclass[preview]{standalone}

\usepackage{tikz}
\usepackage{pgfplots}
\usetikzlibrary {positioning}
\usetikzlibrary{arrows,automata,shapes}
\usetikzlibrary{trees,fit,decorations.pathreplacing}
\usetikzlibrary{calc}
\usetikzlibrary{graphs}
\tikzset{near start abs/.style={xshift=1cm}}

\begin{document}
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}

Graph type one:
    \begin{figure}[H]
    \centering
        \begin{tikzpicture}[->,>=stealth',shorten >=1pt,auto,node distance=3cm,semithick]
        \tikzstyle{every state}=[scale =1,fill=blue,draw=none,text=white]

        \def \n {12}
        \def \radius {4cm}
        \def \labelrad {4.7cm}
        \def \margin {8} % margin in angles, depends on the radius

        \foreach \s in {0,...,11}
        {
            \node[draw, state] (\s) at ({-360/\n * (\s +4.5)}:\radius) {$\s$};
            %           \draw[->, >=latex] ({360/\n * (\s - 1)+\margin}:\radius) 
            %           arc ({360/\n * (\s - 1)+\margin}:{360/\n * (\s)-\margin}:\radius);
        }
        \node[fit=(0)(1)(2)(3)](input){};
        \node[fit=(4)(5)](output){};
        \node[fit=(6)(7)(8)(9)](intern){};
        \node[fit=(10)(11)](inhib){};

        % edges
        \path
        (0) edge (9)
        edge (11)
        (1) edge (8)
        edge (9)
        edge (10)
        edge (11)
        (2) edge (6)
        edge (7)
        edge (8)
        edge (9)
        (3) edge (9)
        edge (11)
        (4) edge (7)
        edge (9)
        edge (11)
        (5) edge (6)
        edge (9)
        edge (10)
        (6) edge (4)
        edge (8)
        edge (9)
        edge (11)
        (7) edge (4)
        edge (5)
        edge [red,dashed,bend left =50] node {} (9)
        edge (11)
        (8) edge (4)
        edge (6)
        edge (11)
        (9) edge (4)
        edge (7)
        edge (10)
        (10) edge[red] (5)
        edge[red] (9)
        (11) edge[red] (4)
        edge[red] (5)
        edge[red] (6)
        ;


        % Input area
        \begin{pgfonlayer}{background}
        \filldraw [line width=4mm,join=round,black!10]
        (input.north west) rectangle (input.south east);
        \end{pgfonlayer}


        % Input area
        \begin{pgfonlayer}{background}
        \filldraw [line width=4mm,join=round,blue!10]
        (output.north west) rectangle (output.south east);
        \end{pgfonlayer}


        % Intern area
        \begin{pgfonlayer}{background}
        \filldraw [line width=4mm,join=round,green!10]
        (intern.north west |- intern.north) rectangle (intern.south east |- intern.south);
        \end{pgfonlayer}


        % Inhib area
        \begin{pgfonlayer}{background}
        \filldraw [line width=4mm,join=round,red!10]
        (inhib.north west |- inhib.north) rectangle (inhib.south east |- inhib.south);
        \end{pgfonlayer}


        % captions
        %       \node[below=0.3cm] at (input.south) {Input};
        %       \node[above=0.3cm] at(intern.north) {Intern};
        %       \node[below=0.3cm] at (inhib.south) {Inhibitorisch};

        % Labels
        \foreach \c [count=\x from 0] in {0,2,2,0,0,0,0,1,2,1,1,2} %{{a,f},{b,o},{c,o},{d,b},{e,a},{f,r}} 
        {
            \node (\x) at ({-360/\n * (\x +4.5)}:\labelrad) {\c};
        }
        \end{tikzpicture}
    \end{figure}




Graph type two:
    \begin{figure}[H]
    \centering
        \begin{tikzpicture}[->,>=stealth',shorten >=1pt,auto,node distance=2cm,semithick]
        \tikzstyle{every state}=[scale =1,fill=blue,draw=none,text=white]

        \node[state] (4)                    {4};
        \node[state] (7) [above right of=4] {7};
        \node[state] (9) [below right of=7] {9};
        \node[state] (10)[below left of=9]       {10};

        % edges
        \path
        (4) edge (7)
        edge (9)
        (7) edge (4)
        edge [red,dashed,bend left =50] node {} (9)
        (9) edge (4)
        edge (7)
        edge (10)
        (10) edge[red] (9)
        ;

        % Labels
        \node (l4) at ($(4)+(-.5,.7)$) {$(0,0\rightarrow2)$};
        \node (l7) at ($(7)+(-0,.7)$) {$(2,1\rightarrow2)$};
        \node (l9) at ($(9)+(.5,-.8)$) {$(4,1\rightarrow2)$};
        \node (l10) at ($(10)+(0,-.7)$) {$(2,1\rightarrow2)$};
        \node[red] (gew) at ($(7)!0.5!(9)+(1.3,.7)$) {$(0\rightarrow1)$};
        \end{tikzpicture}
    \end{figure}
\end{document} 

With the result:

enter image description here

EDIT: Just ignore the dashed edge from node 7 to node 9 that is a different thing.

  • You can't do this with this approach, I don't think. (I'm pretty sure.) The problem is that you aren't drawing them as graphs. You're just drawing a bunch of nodes and edges. So the relational properties you want to take as the basis for altering the output are simply not there. – cfr Jul 16 '16 at 21:37
  • I looked around, and did not find any package or method that was better made for this. Did i miss something? Can you point me to a better suited method for doing this kind of graphs? Maybe one that can do what I asked for in the original question? – audiophiel Jul 16 '16 at 22:00
  • I don't know the graph drawing facilities of TikZ well, but that is where I would be looking, provided LuaTeX is an option, of course. I don't know whether pstricks has anything like this, but the TikZ graphing stuff seems the best bet to me. – cfr Jul 16 '16 at 22:07
  • i tought i was using the tikz method for drawing graphs, am i not? – audiophiel Jul 16 '16 at 22:11
  • You're using TikZ to draw graphs, but you are not using the graph syntax or the automatic layout facilities. (The latter requires LuaTeX.) – cfr Jul 16 '16 at 22:13
2

This is not an answer. It is an illustration of TikZ's graphing syntax and of its support for graph-drawing algorithms.

The first 2 graphs just illustrate the syntax. The third uses the algorithmic graph layout facilities and, therefore, requires LuaTeX.

If the following line gives an error, comment it out. It is needed to fix a compatibility issue with standalone and current LuaTeX.

\RequirePackage{luatex85}
\documentclass[border=10pt,multi,tikz]{standalone}

Load some TikZ libraries. graphs supports the syntax. graphdrawing supports the algorithmic graph layouts provided for use with LuaTeX.

\usetikzlibrary{graphs,graphdrawing,arrows.meta}

The graphdrawing algorithms support includes a number of libraries for various out-of-the-box layout algorithms. Here's one of them.

\usegdlibrary{circular}
\begin{document}

This example doesn't use an algorithm but it does illustrate the syntax. It uses a circular placement strategy which lays out groups of 12 nodes in circular fashion.

\begin{tikzpicture}
  [

my node is a style which sets incoming edges black and outgoing edges red.

    my node/.style={<red, >black},
  ]

Here's the graph specification itself. We turn the nodes through an angle and increase the default radius a bit to lay things out a bit differently from the default.

  \graph [clockwise=12, radius=25mm, phase=-120, /tikz/>=Stealth, nodes={fill=blue, circle, node sep=12.5mm, minimum size=5mm, inner sep=1pt, text=white}]

Now for the nodes in the graph.

  {

Layout our 12 nodes.

    {\foreach \i in {0,...,11} \i,},

Specify the various connections between them.

    {1, 9} -> 10 [my node] -> 9,
    {0, 1, 3, 4, 5, 6, 7, 8} -> 11 [my node] -> {4, 5, 6},
    {0, 1, 2, 3, 4, 5, 6} -> 9 -> {4, 7},
    {1, 2, 6} -> 8 -> {4, 6},
    {2, 4} -> 7 -> 4,
    {2, 4, 5} -> 6 -> 4,
  };
\end{tikzpicture}

example 1

Here's a slightly different layout which explicitly uses circular placement.

\begin{tikzpicture}
  [
    my node/.style={<red, >black},
  ]
  \graph [circular placement, group polar shift=(-30:0), /tikz/>=Stealth, nodes={fill=blue, circle, minimum size=5mm, inner sep=1pt, text=white}]
  {
    a/ [fill=none] -!- \foreach \i in {0,...,11} { a -!- \i },
    {1, 9} -> 10 [my node] -> 9,
    {0, 1, 3, 4, 5, 6, 7, 8} -> 11 [my node] -> {4, 5, 6},
    {0, 1, 2, 3, 4, 5, 6} -> 9 -> {4, 7},
    {1, 2, 6} -> 8 -> {4, 6},
    {2, 4} -> 7 -> 4,
    {2, 4, 5} -> 6 -> 4,
  };
\end{tikzpicture}

example 2

The third example uses one of the algorithmic layouts we loaded with the circular library, called simple necklace layout.

\begin{tikzpicture}
  [
    my node/.style={<red, >black},
  ]

Note the use of node sep here to increase the spacing between nodes, as opposed to the more manual approach above. Setting radius, for example, obviously applies only to a circular layout. In contrast, node sep is neutral between layouts.

  \graph [simple necklace layout, grow'=60, /tikz/>=Stealth, nodes={fill=blue, circle, node sep=12.5mm, minimum size=5mm, inner sep=1pt, text=white}]
  {
    {\foreach \i in {0,...,11} \i,},
    {1, 9} -> 10 [my node] -> 9,
    {0, 1, 3, 4, 5, 6, 7, 8} -> 11 [my node] -> {4, 5, 6},
    {0, 1, 2, 3, 4, 5, 6} -> 9 -> {4, 7},
    {1, 2, 6} -> 8 -> {4, 6},
    {2, 4} -> 7 -> 4,
    {2, 4, 5} -> 6 -> 4,
  };
\end{tikzpicture}

example 3

\end{document}

It is possible to design your own algorithms to control the layout and appearance of the graph. Since this way of proceeding specifies the structural relationships between the nodes, this information is available when drawing the graph.

In the original code, nothing specifies these structural relationships, so there is no information which might be used to automate the graph's appearance in the way desired.

By using \graph, you can make the structural information available.

Whether it is worth pursuing this approach probably depends on the number and sophistication of the graphs you want to draw in this way.

Complete code:

\RequirePackage{luatex85}
\documentclass[border=10pt,multi,tikz]{standalone}
\usetikzlibrary{graphs,graphdrawing,arrows.meta}
\usegdlibrary{circular}
\begin{document}
\begin{tikzpicture}
  [
    my node/.style={<red, >black},
  ]
  \graph [clockwise=12, radius=25mm, phase=-120, /tikz/>=Stealth, nodes={fill=blue, circle, node sep=12.5mm, minimum size=5mm, inner sep=1pt, text=white}]
  {
    {\foreach \i in {0,...,11} \i,},
    {1, 9} -> 10 [my node] -> 9,
    {0, 1, 3, 4, 5, 6, 7, 8} -> 11 [my node] -> {4, 5, 6},
    {0, 1, 2, 3, 4, 5, 6} -> 9 -> {4, 7},
    {1, 2, 6} -> 8 -> {4, 6},
    {2, 4} -> 7 -> 4,
    {2, 4, 5} -> 6 -> 4,
  };
\end{tikzpicture}
\begin{tikzpicture}
  [
    my node/.style={<red, >black},
  ]
  \graph [circular placement, group polar shift=(-30:0), /tikz/>=Stealth, nodes={fill=blue, circle, minimum size=5mm, inner sep=1pt, text=white}]
  {
    a/ [fill=none] -!- \foreach \i in {0,...,11} { a -!- \i },
    {1, 9} -> 10 [my node] -> 9,
    {0, 1, 3, 4, 5, 6, 7, 8} -> 11 [my node] -> {4, 5, 6},
    {0, 1, 2, 3, 4, 5, 6} -> 9 -> {4, 7},
    {1, 2, 6} -> 8 -> {4, 6},
    {2, 4} -> 7 -> 4,
    {2, 4, 5} -> 6 -> 4,
  };
\end{tikzpicture}
\begin{tikzpicture}
  [
    my node/.style={<red, >black},
  ]
  \graph [simple necklace layout, grow'=60, /tikz/>=Stealth, nodes={fill=blue, circle, node sep=12.5mm, minimum size=5mm, inner sep=1pt, text=white}]
  {
%     0 -!- \foreach \i in {1,...,11} { 0 -!- \i },
    {\foreach \i in {0,...,11} \i,},
    {1, 9} -> 10 [my node] -> 9,
    {0, 1, 3, 4, 5, 6, 7, 8} -> 11 [my node] -> {4, 5, 6},
    {0, 1, 2, 3, 4, 5, 6} -> 9 -> {4, 7},
    {1, 2, 6} -> 8 -> {4, 6},
    {2, 4} -> 7 -> 4,
    {2, 4, 5} -> 6 -> 4,
  };
\end{tikzpicture}
\end{document}

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.