[Tex/LaTex] Labeling Edges in a Weighted Digraph

labelstkz-graph

I would like to have the labels of the edges of a weighted digraph positioned "beside" (north, south, east, west, etc.) the arrows. I have already created the digraph with:

\documentclass{article}
\usepackage{tkz-graph}
\usetikzlibrary{calc}
\usetikzlibrary{decorations.markings}
\begin{document}
\begin{tikzpicture}[x=2.0cm,y=0.8cm]
\GraphInit[vstyle=Classic]
\begin{scope}[VertexStyle/.append style = {minimum size = 6pt, inner sep = 0pt}]
\Vertex[Lpos=180,L=$e$]{e}
\Vertex[x=2,y=3,Lpos=90,L=$a$]{a}
\Vertex[x=4,y=2.5,Lpos=45,L=$b$]{b}
\Vertex[x=5,y=-1,Lpos=-90,L=$c$]{c}
\Vertex[x=2,y=-2,Lpos=-90,L=$d$]{d}
\tikzset{EdgeStyle/.style={postaction=decorate,decoration={markings,mark=at position 0.5 with {\arrow{triangle 60}}}}}
\Edge[style={bend right = 45}](a)(e)
\Edge[style={bend left}](a)(b)
\Edge(a)(c)
\Edge(b)(c)
\Edge[style={bend right}](b)(d)
\Edge(c)(e)
\Edge[style={bend right =60}](c)(b)
\end{scope}
\end{tikzpicture}
\end{document}

You may use any set of weights for the edges.

Best Answer

You can add labels to \Edges by adding e.g. label={Stuff} in the \Edge options. By default the label is placed on top of the arrow, you can shift it by changing the style of the label with e.g. labelstyle={above left}, which moves the label up and to the left.

To get a more automatic label placement you can use the auto key, mentioned by Qrrbrbirlbel in a comment. This is a TikZ key, described in section 16.8 Placing Nodes on a Line or Curve Explicitly of the manual. The swap key, allowing you to switch from auto=left to auto=right (or vice versa) for a single label is also described here.

You can apply that to all labels by changing the LabelStyle style, which is the default style used by on labels tkz-graph as far as I understand. However, when I tried this, I wasn't able to use swap. (I may have done something wrong, not sure.) Therefore I've defined a new style, MyLabel, and applied that to all the labels with labelstyle={MyLabel}. By adding swap after MyLabel, the label will be placed on the other side of the arrow.

In MyLabel I also defined fill=none and outer sep=0.2ex. The labels are TikZ nodes that by default have a white background. If they are placed on top of the lines this is a good thing, as the line will seem to have a gap around the label. When the labels are placed next to the lines, it is better to not have any fill, as that could partially cover lines or arrow heads. The outer sep key is a (not ideal) way of changing the distance from the line to the label (it is described in section 16.2.2 Common Options: Separations, Margins, Padding and Border Rotation of the TikZ manual).

Other options you can use to customize the label placement include the following (add them to the labelstyle):

  • sloped: rotates the label text so that its baseline is roughly parallel to the edge (described in the same section of the manual as auto and swap).
  • pos=<fraction>: <fraction> is a number between 0 and 1, that defines where along the line the node should be placed. This allows you to fine tune the position of individual labels. The default is pos=0.5, i.e. halfway along the line (described in the same section of the manual as auto and swap).
  • xshift/yshift=<length>: If you are really picky about where the labels and up, you can move them around with these keys.

As the labels are just TikZ nodes, you can also customize their looks (colors, borders etc.), should that be of interest.

\documentclass{standalone}
\usepackage{tkz-graph}
\usetikzlibrary{calc}
\usetikzlibrary{decorations.markings}
\begin{document}
\begin{tikzpicture}[x=2.0cm,y=0.8cm]
\GraphInit[vstyle=Classic]
\begin{scope}[VertexStyle/.append style = {minimum size = 6pt, inner sep = 0pt}]
\Vertex[Lpos=180,L=$e$]{e}
\Vertex[x=2,y=3,Lpos=90,L=$a$]{a}
\Vertex[x=4,y=2.5,Lpos=45,L=$b$]{b}
\Vertex[x=5,y=-1,Lpos=-90,L=$c$]{c}
\Vertex[x=2,y=-2,Lpos=-90,L=$d$]{d}
\tikzset{EdgeStyle/.style={postaction=decorate,decoration={markings,mark=at position 0.5 with {\arrow{triangle 60}}}},
MyLabel/.style={
   auto=right,
   fill=none,
   outer sep=0.2ex}}

\Edge[style={bend right = 45},label={$1$},labelstyle={MyLabel}](a)(e)
% swap the two following labels to the left side
\Edge[style={bend left},label={$2$},labelstyle={MyLabel,swap}](a)(b)
\Edge[label={$3$},labelstyle={MyLabel,swap}](a)(c)

\Edge[label={$4$},labelstyle={MyLabel}](b)(c)
% move the next label a little further along the line with pos
\Edge[style={bend right},label={$5$},labelstyle={MyLabel,pos=0.6}](b)(d)
% increase the distance from the line a little with outer sep
\Edge[label={$6$},labelstyle={MyLabel,outer sep=.5ex}](c)(e)

\Edge[style={bend right=60},label={$7$},labelstyle={MyLabel}](c)(b)
\end{scope}
\end{tikzpicture}
\end{document}

enter image description here