10

I have to plot some property graph data in LaTeX. When I try to do this task in LaTeX with TiKz, it usually takes me a lot of time, because I always have to decide which is the best position of the nodes, and I have no pre-built graph layout to use. Secondly, I would like that such graph layout would adapt to the informations that are contained in each node so that two nodes do not overlap due to the huge information content. Last but not least, I would like to automatically assign to each node and edge a specific color in order to distinguish them by label value. Is there a way to automate such process? When I have to provide a lot of examples, the process of both defining the vertices and alignign them takes me too much time. Thanks in advance.

A final desired representation: enter image description here

3
  • I suspect laying things out will be quite difficult. But partly it will depend on the maximum number of nodes, and the maximum number of connections between them. If you cap things at 5 nodes and 8 connections, it's not too bad. If you want to go arbitrarily big, things will get bad quickly.
    – Teepeemm
    Feb 16, 2017 at 15:18
  • Indeed. Since I have to mainly plot examples for research papers, I don't think I will ever have more than a dozen of vertices and arcs whatsoever. It's not a data visualization problem, but only a way to automate part of the TikZ writing process.
    – jackb
    Feb 16, 2017 at 18:48
  • 2
    Using graphdrawing and \usegdlibrary together with LuaTeX, you can try to chose an automated graph layout. See Part IV on Graph Drawing in the PGF manual. Feb 16, 2017 at 19:38

3 Answers 3

2
+25

It's not exactly a template, but I think this could help you.

To position the nodes automatically without overlapping, you may use a matrix.

Some pics with some args may speed your work.

Here an example:

\documentclass[11pt,openright]{book}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{graphicx}
\usepackage[british]{babel}
\usepackage{tikz}

\tikzset{%
    pics/myrec/.style n args={7}{code={%  
        \node (#1) at (0,0) [draw,#2,text=black,font=\tiny, align=center,thick,minimum width=2cm,minimum height=1cm, rounded corners,label={\tiny\{#3,#4\}}]{\textsc{Title=}\textit{#5}\\  \textsc{1Author=}\textit{#6}\\ \textsc{Name=}\textit{#7}};
    }},
    pics/myfc/.style n args={5}{code={% 
    \draw[->, red, dotted] (#1) to[bend left=#3] node[midway,font=\tiny,rotate=#4,#5] {\{Follows,Cites\}} (#2);  
    }},
   pics/myf/.style n args={5}{code={% 
    \draw[->, orange] (#1) to[bend right=#3] node[midway,font=\tiny, rotate=#4,#5] {\{Follows\}} (#2);
     }},
   pics/myc/.style n args={5}{code={% 
  \draw[->, red] (#1) to[bend left=#3] node[midway,font=\tiny, rotate=#4,#5] {\{Cites\}} (#2);
      }},
 }

\begin{document}
\begin{figure}[htbp]
\centering
\begin{tikzpicture}
  \matrix[row sep=1cm,column sep=1.5cm] {
       \pic {myrec={nodea}{blue}{User}{Paper}{Graph}{Alice}{Alice}}; & 
       \pic {myrec={nodeb}{green}{User}{Paper}{Join}{Alice}{Alice}}; & 
       \pic {myrec={nodec}{green}{User}{Paper}{OWL}{Bob}{Bob}}; \\
        & 
        & 
       \\
       \pic {myrec={noded}{red}{User}{Paper}{Projection}{Carl}{Carl}}; &
       & 
       \pic {myrec={nodee}{red}{User}{Paper}{$\mu$-calc}{Dan}{Dan}}; \\
    };    
    \pic {myfc={nodea.north east}{nodec.north west}{40}{0}{above}};
    \pic {myfc={nodeb.south}{noded.north east}{0}{45}{below}};
    \pic {myf={nodea.west}{noded.west}{40}{90}{above}};
    \pic {myf={nodeb.east}{nodec.west}{0}{0}{above}};
    \pic {myf={nodec.east}{nodee.east}{-40}{90}{below}};
    \pic {myf={nodee.south west}{noded.south east}{0}{0}{below}};
    \pic {myc={nodec.south west}{noded.east}{0}{30}{below}}; 
    \pic {myc={noded.south east}{nodee.south west}{-40}{0}{below}}; 
    \end{tikzpicture}
\caption{Example}
\end{figure}
\end{document}

enter image description here

3
  • Actually, I was thinking more of a Lua-based approach. Part of the solution is to use the matrix layout to avoid vertex collisions, but it does not help when automating the writing of some parts and, besides the matrix layout, it actually looks like the code I used to generate my picture.
    – jackb
    Feb 17, 2017 at 16:15
  • 1
    @jackb Sorry, I'm a beginner, I don't know how to create a Lua-based approach, but the pics can be re-utilized in all the pictures of the document.
    – CarLaTeX
    Feb 17, 2017 at 16:18
  • Yep, in my case I just used node styles, then macros for automating the data input, but my solution is very similar to yours (that's because I'm a beginner, too). Do not worry, and thanks for your suggestion anyway :)
    – jackb
    Feb 17, 2017 at 16:25
1

If you want to be fast you can also use:

However if you really want to "automate the process", Timothy provided you with a great solution in the comments.

1
  • Yep, I agree. I'll think of implementing something as he suggested in my spare time (that is not that much).
    – jackb
    Feb 17, 2017 at 8:59
0

enter image description here

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}
\begin{document}
\begin{tikzpicture}[align=center,rounded corners]
    \node (nw) [text width=3cm] at (-5,3) [rectangle,draw] {\textsc{Title} $=$ \textit{Graphs} \textsc{1Author} $=$ \textit{Alice} \textsc{Name} $=$ \textit{Alice}};
    \node (n)  [text width=3cm] at ( 0,3) [rectangle,draw] {\textsc{Title} $=$ \textit{Join} \textsc{1Author} $=$ \textit{Alice} \textsc{Name} $=$ \textit{Alice}};
    \node (ne) [text width=3cm] at (+5,3) [rectangle,draw] {\textsc{Title} $=$ \textit{Graphs} \textsc{1Author} $=$ \textit{Alice} \textsc{Name} $=$ \textit{Alice}};
    \node (sw) [text width=3cm] at (-5,0) [rectangle,draw] {\textsc{Title} $=$ \textit{Graphs} \textsc{1Author} $=$ \textit{Alice} \textsc{Name} $=$ \textit{Alice}};
    \node (se) [text width=3cm] at (+5,0) [rectangle,draw] {\textsc{Title} $=$ \textit{Graphs} \textsc{1Author} $=$ \textit{Alice} \textsc{Name} $=$ \textit{Alice}};
    \node[anchor=south] at (nw.north) {\{User, Paper\}};
    \node[anchor=south] at (n.north)  {\{User, Paper\}};
    \node[anchor=south] at (ne.north) {\{User, Paper\}};
    \node[anchor=south] at (sw.north) {\{User, Paper\}};
    \node[anchor=south] at (se.north) {\{User, Paper\}};
    \draw[red,-{Latex},dotted,very thick] (n) -- node[below,sloped] {\{Follows, Cities\}} (sw.north east);
    \draw[red,-{Latex},dotted,very thick] (nw.north east) to[bend left] node[above,sloped] {\{Follows, Cities\}} (ne.north west);
    \draw[orange,-{Latex},thick] (nw.south west) to node[below,sloped] {\{Follows\}} (sw.north west);
    \draw[orange,-{Latex},thick] (ne.south east) to node[above,sloped] {\{Follows\}} (se.north east);
    \draw[magenta,-{Latex}] (sw.south east) to[bend right] node[below,sloped] {\{Cities\}} (se.south west);
    \draw[orange,-{Latex}] (se.south west) to node[above,sloped] {\{Follows\}} (sw.south east);
    \draw[orange,-{Latex}] (n.east) to node[above,sloped] {\{Follows\}} (ne.west);
    \draw[magenta,-{Latex}] (ne.south west) to node[below,sloped] {\{Cities\}} (sw.east);
\end{tikzpicture}
\end{document}

You must log in to answer this question.

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