8

Are there any possible shorter codes of drawing this diagram, maybe using graphs but it is not a regular polygon, or shortening the repetitive \draw in my code:

%% filename henry3.pgf
\begin{tikzpicture}
%%styles and libraries
\usetikzlibrary{decorations.markings, arrows}
\tikzstyle{mdar}=[decoration={markings, mark=at position 0.45 with {\arrow{stealth}}}, postaction={decorate}]
\tikzstyle{mdad}=[decoration={markings, mark=at position 0.3 with {\arrow{stealth}}}, postaction={decorate}]
\tikzstyle{point}=[node distance=2cm, inner sep=0pt, fill=black, circle]
%nodes
\node[point] (p1) {.} ;
\node[point, below of = p1] (p2) {.}; 
\node[point, below of = p2, yshift=0.7cm](p3){.};
\node[point, below of = p3, yshift=0.4cm](p4){.};
\node[point, below of = p4, yshift=0.7cm](p5){.}; 
%%
\node[point, right of=p1, yshift=-1.4cm](p10){.};
\node[point, left of=p1, yshift=-1.4cm](p11){.};
\node[point, right of=p4,  xshift=-0.3cm] (p40) {.};
\node[point,left of=p4, xshift=0.3cm] (p41) {.};
%% there is a way of importing tikz's graph library and making things
%%easier and compressed but importing this does not work on my
 %%computer
%joining nodes
\draw[mdar](p1) -- (p11) ;\draw[mdar](p1) -- (p10);\draw[mdar] (p1) -- (p41);\draw[mdar] (p1) -- (p40);\draw[mdar](p1) -- (p2);
\draw[mdar](p2) -- (p11); \draw[mdar](p2) -- (p3);\draw[mdar](p2) -- (p10); \draw[mdar](p2) -- (p40); \draw[mdar](p2) -- (p41);
\draw[mdad](p11) -- (p3); \draw[mdad](p11) -- (p4); \draw[mdad](p11) -- (p5); \draw[mdar](p11) -- (p41);
\draw[mdar] (p10) -- (p3); \draw[mdad] (p10) -- (p4); \draw[mdad] (p10) -- (p5); \draw[mdar] (p10) -- (p40);
\draw[mdar](p3) -- (p4); \draw[mdar](p3) -- (p41); \draw[mdar](p3) -- (p40);
\draw[mdar](p4) -- (p41); \draw[mdar](p4) -- (p40); \draw[mdar](p4) -- (p5);
\draw[mdar](p40) -- (p5); \draw[mdar](p41) -- (p5);
\end{tikzpicture}

Output: enter image description here

Xrobot
  • 153

3 Answers3

10

I don't know much about graphs so I won't attempt to use the graph libraries but you can renumber your nodes bit more meaningfully and then do a typical adjacency matrix approach.

\documentclass[tikz]{standalone}
\usetikzlibrary{decorations.markings, arrows}
\begin{document}    
\begin{tikzpicture}[mdar/.style={
    decoration={markings, mark=at position 0.45 with {\arrow{stealth}}},
    postaction={decorate}
    },
mdad/.style={decoration={markings, mark=at position 0.3 with {\arrow{stealth}}}, 
             postaction={decorate}},
point/.style={node distance=2cm, inner sep=0pt, fill=black, circle}]

\node[point] (p1) {.} ;
\node[point, left of=p1, yshift=-1.4cm](p2){.};
\node[point, below of = p1] (p3) {.}; 
\node[point, right of=p1, yshift=-1.4cm](p4){.};
\node[point, below of = p3, yshift=0.7cm](p5){.};
\node[point, below of = p5, yshift=0.4cm](p7){.};
\node[point,left of=p7, xshift=0.3cm] (p6) {.};
\node[point, right of=p7,  xshift=-0.3cm] (p8) {.};
\node[point, below of = p7, yshift=0.7cm](p9){.}; 
\def\myadjmat{%
{0,1,1,1,0,1,0,1,0},
{0,0,0,0,1,1,1,0,1},
{0,1,0,1,1,1,0,1,1},
{0,0,0,0,1,0,1,1,1},
{0,0,0,0,0,1,0,1,0},
}

\foreach \x[count=\xi] in \myadjmat{
  \foreach \y[count=\yi] in \x{
    \ifnum1=\y\relax\draw[mdar] (p\xi) -- (p\yi);\fi
  }
}

\end{tikzpicture}
\end{document}

enter image description here

I got bored after the fifth but you get the idea. Also don't leave the \usetikzlibrary{...} commands in the picture. Instead carry them to your preamble. Finally you might consider skipping the \tikzstyle command as it is deprecated as per Should \tikzset or \tikzstyle be used to define TikZ styles?

percusse
  • 157,807
  • Nice solution (+1), but I cant see where you use mdad style. And by the way, all nodes have the same style ... so it can be defined as every node/.style = {...} and later at nodes dropped the style name :-) – Zarko Feb 11 '16 at 13:48
  • @Zarko Frankly, I didn't bother – percusse Feb 11 '16 at 14:02
  • Is there some reason why else part of the ifnum was used? – AJN Feb 11 '16 at 14:36
  • 1
    @AJN it doesn't have any else part. \relax is to signal TeX to stop looking for numbers further – percusse Feb 11 '16 at 14:43
  • Thanks. I had wrongly assumed that the first command after the number was the if part and the second command was the else part. – AJN Feb 11 '16 at 16:32
  • Wow, need to go back and learn to draw using matrix approach cos we're definitely going to draw more stuff like this. Thanks too for the PoA :-) – Xrobot Feb 11 '16 at 21:16
6

Here's an example with the graph drawing stuff. The node positioning is not amazing, but can be changed fairly easily. It can be complied "as usual" with pdflatex (or xelatex, or latex -> dvipdfm, etc).

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{graphs,decorations.markings}
\tikzgraphsset{on edge arrow/.style={/tikz/every edge/.append style={
  -, draw, postaction={
  decoration={markings, mark=at position \arrowpos with {\arrow{stealth}}},
  decorate}}}, > pos/.store in=\arrowpos, > pos=0.5}
\begin{document}
\begin{tikzpicture}[x=0.75cm,y=0.75cm]
\foreach \p [count=\i] in {(0,0),(-2,-1),(0,-1.75),(2,-1),(0,-3),
    (-1.5,-4.5),(0,-4.5),(1.5,-4.5),(0,-6.25)}
  \node [shape=circle, inner sep=0, minimum size=2,fill] (\i) at \p {};
\graph [use existing nodes, on edge arrow]{
    1 -> {2, 3, 4};
    2 -> {5 -> {6, 7, 8}, 6, 7 -> 9};
    3 -> {2, 4 -> {5, 7, 8}, 5};
    1 ->[> pos=.45] {6, 8};
    3 ->[> pos=.45] {6, 8};
    {2, 4} ->[> pos=0.66] 9;
};
\end{tikzpicture}
\end{document}

enter image description here

Mark Wibrow
  • 70,437
5

Since your arrows have no regular pattern, it's hard to make a really concise code because there is not an actual rule that governs where the arrows should go to, and so on. So This is a slightly longer code than I wanted to write, but it's still pretty short.

Output

enter image description here

Code

\documentclass[margin=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.markings, arrows}

\tikzset{
    %mdar/.style={very thin,decoration={markings, mark=at position 0.45 with {\arrow{stealth reversed}}}, postaction={decorate}},
    mdad/.style={very thin,decoration={markings, mark=at position 0.45 with {\arrow[scale=.8]{stealth}}}, postaction={decorate}},
    point/.style={inner sep=.5pt, fill=black, circle}
}

\begin{document}
\begin{tikzpicture}

% Nodes
\foreach \points [count=\xi] in {
        (0,0),
        (-1,1),(0,1),(1,1),
        (0,2),
        (-1.2,3.3),(0,3),(1.2,3.3),
        (0,4)}{
    \node[point] (p\xi) at \points {};
}

% Arrows
\foreach \name/\dest in {%  
    2/{1},
    3/{1,2,4},
    4/{1},
    5/{2,3,4},
    6/{1,2,3,5},
    7/{2,4,5,6,8},
    8/{1,3,4,5},
    9/{2,4,6,7,8},
    }{%
    \foreach \ppp in \dest{
        \draw[very thin, mdad] (p\name) -- (p\ppp);
    }
}
\end{tikzpicture}
\end{document}
Alenanno
  • 37,338