4

I am drawing a simple graph with tikz. This works OK but when I have two edges going in opposite directions between a pair of nodes I get one arrow with two heads (for example between nodes B and D below). How can I get two arrows? Here is a MWE:

\documentclass[]{article}
\usepackage{tikz}  
\usetikzlibrary{arrows.meta,positioning}
\usepackage{tkz-graph}
\usepackage{graphicx}  
\begin{document}  
\section{}
\begin{center}
    \begin{tikzpicture}[auto,node distance=2cm,thick,main node/.style={circle,fill=blue!20,draw,font=\sffamily\Large\bfseries}, scale=2]
    \node[main node, label=$0$] (A) at (0,5) {A};
    \node[main node, label=$\infty$] (B) at (2,6.5) {B};
    \node[main node, label=$\infty$] (E) at (4,5) {E};
    \node[main node, label=$\infty$] (C) at (1,3) {C};
    \node[main node, label=$\infty$] (D) at (3,3) {D};

    \path [->] (A) edge node {$-1$} (B);
    \path [->] (B) edge node {$2$} (E);
    \path [->] (A) edge node {$4$} (C);
    \path [->] (B) edge node {$3$} (C);
    \path [->] (B) edge node {$2$} (D);
    \path [->] (D) edge node {$1$} (B);
    \path [->] (D) edge node {$5$} (C);
    \path [->] (E) edge node {$-3$} (D);
    \end{tikzpicture}
\end{center}
\end{document}
6

Here is a proposal using the calc library to shift the paths by some amount away from the center. Of course, if you do that very often, you may write a macro for that. Or you just bend the paths, as illustrated in the arrows between the B and D nodes.

\documentclass[]{article}
\usepackage{tikz}  
\usetikzlibrary{arrows.meta,positioning,calc}
\usepackage{tkz-graph}
\usepackage{graphicx}  
\begin{document}  
\section{}
\begin{center}
    \begin{tikzpicture}[auto,node distance=2cm,thick,main node/.style={circle,fill=blue!20,draw,font=\sffamily\Large\bfseries}, scale=2]
    \node[main node, label=$0$] (A) at (0,5) {A};
    \node[main node, label=$\infty$] (B) at (2,6.5) {B};
    \node[main node, label=$\infty$] (E) at (4,5) {E};
    \node[main node, label=below:$\infty$] (C) at (1,3) {C};
    \node[main node, label=below:$\infty$] (D) at (3,3) {D};

    \path [->] (A) edge node {$-1$} (B);
    \path [->] (B) edge node {$2$} (E);
    \path [->] (A) edge node {$4$} (C);
    \path [->] (B) edge node {$3$} (C);
    \path [->] let \p1=($(D)-(B)$),\n1={atan2(\y1,\x1)},\n2={180+\n1} in
     ($ (B.\n1)!2pt!90:(D.\n2) $) edge node {$2$} ($ (D.\n2)!2pt!-90:(B.\n1) $);
    \path [->] let \p1=($(B)-(D)$),\n1={atan2(\y1,\x1)},\n2={180+\n1} in
     ($ (D.\n1)!2pt!90:(B.\n2) $) edge node {$-2$} ($ (B.\n2)!2pt!-90:(D.\n1) $);
    \path [->,bend left=10] (D) edge node {$5$} (C);
    \path [->,bend left=10] (C) edge node {$-5$} (D);
    \path [->] (E) edge node {$-3$} (D);
    \end{tikzpicture}
\end{center}
\end{document}

enter image description here

Off-topic but I just saw AndréC's answer and even though I generally agree with him, I'd not use a graph for that. A very simple loop is easier IMHO and shorter.

\documentclass[]{article}
\usepackage{tikz}  
\usetikzlibrary{calc}
\begin{document}  
\begin{center}
    \begin{tikzpicture}[auto,node distance=2cm,thick,main node/.style={circle,fill=blue!20,draw,font=\sffamily\Large\bfseries}, scale=2]
    \foreach \X/\Z [count=\Y,evaluate=\Y as \angle using {90-72+72*\Y}] in {B/\infty,A/0,C/\infty,D/\infty,E/\infty}
    {\node[main node,label={\angle:$\Z$}] (\X) at (\angle:2) {\X};}

    \path [->] (A) edge node {$-1$} (B);
    \path [->] (B) edge node {$2$} (E);
    \path [->] (A) edge node {$4$} (C);
    \path [->] (B) edge node {$3$} (C);
    \path [->] let \p1=($(D)-(B)$),\n1={atan2(\y1,\x1)},\n2={180+\n1} in
     ($ (B.\n1)!2pt!90:(D.\n2) $) edge node {$2$} ($ (D.\n2)!2pt!-90:(B.\n1) $);
    \path [->] let \p1=($(B)-(D)$),\n1={atan2(\y1,\x1)},\n2={180+\n1} in
     ($ (D.\n1)!2pt!90:(B.\n2) $) edge node {$-2$} ($ (B.\n2)!2pt!-90:(D.\n1) $);
    \path [->,bend left=10] (D) edge node {$5$} (C);
    \path [->,bend left=10] (C) edge node {$-5$} (D);
    \path [->] (E) edge node {$-3$} (D);
    \end{tikzpicture}
\end{center}
\end{document}
  • Thank you, this definitely works. I am surprised there isn't a "less clever" solution though somewhere within a tikz library. – Anush Oct 25 '18 at 15:56
  • @Anush An easier way is to just bend the paths. I could add an example if you wish. – marmot Oct 25 '18 at 15:58
  • That would be great if you don't mind. This was my first ever tikz diagram so I have much to learn. – Anush Oct 25 '18 at 15:59
  • @Anush Done, please have a look. – marmot Oct 25 '18 at 16:00
  • That is very nice! – Anush Oct 25 '18 at 16:15
4

To build graphs, there is the graphs library.

Here are two slightly different syntaxes that give the same result.

The circular placement option allows you to place the nodes on a circle. As there are 5, to draw a regular pentagon, it is enough that the angle is equal to 360/5=72°, its radius is given by radius=40mm.

The clockwise=5 option gives the same result in abbreviated form.

To place arrows, with the quotes library, simply place the text in quotation marks {B->["3"]C}.

\documentclass[tikz,border=5mm]{standalone}
\usetikzlibrary{arrows.meta}
\usetikzlibrary{graphs}
\usetikzlibrary{quotes}
\begin{document}  

   \tikz[>={Straight Barb[length=6pt,width=8pt]},thick] 
   \graph [circular placement, group polar shift=(-72:0), radius=40mm,nodes={draw,circle,font=\sffamily\Large\bfseries,fill=blue!20}]
   {B[label=$\infty$],E[label={[inner sep=0pt]60:$\infty$}],D[label=-90:$\infty$],C[label=-90:$\infty$],A[label={[inner sep=0pt]120:$0$}],
   {A->["-1"]B->["2"] E->["-3"] D->["5"] C},
   {B->["3"]C},
   {B->[bend left=10,"2"]D},
   {D->[bend left=10,"1"]B},
   {A->["4"]C}
   };


\tikz[>={Straight Barb[length=6pt,width=8pt]},thick] 
\graph [clockwise=5,radius=40mm,nodes={draw,circle,font=\sffamily\Large\bfseries,fill=blue!20}] 
   {B[label=$\infty$],E[label={[inner sep=0pt]60:$\infty$}],D[label=-90:$\infty$],C[label=-90:$\infty$],A[label={[inner sep=0pt]120:$0$}],
   {A->["-1"]B->["2"] E->["-3"] D->["5"] C},
   {B->["3"]C},
   {B->[bend left=10,"2"]D},
   {D->[bend left=10,"1"]B},
   {A->["4"]C}
   }; 

\end{document}

graphe

Translated with www.DeepL.com/Translator

  • This is great. It's definitely fussy but the labels of E and A seem a little far from the nodes. Can they easily be made closer? – Anush Oct 25 '18 at 18:32
  • 1
    @Anush You can add options to the labels in brackets A[label={{[inner sep=0pt]120:$0$}] Does that work for you? I updated the answer. – AndréC Oct 25 '18 at 19:22

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.