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

  • 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 '17 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 '17 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. – timothymctim Feb 16 '17 at 19:38
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

  • 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 '17 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 '17 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 '17 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.

  • Yep, I agree. I'll think of implementing something as he suggested in my spare time (that is not that much). – jackb Feb 17 '17 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}

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.