Easiest way to create simple connected graphs?
Here is an easy solution with pstricks
:
\documentclass[border=3pt, x11names]{standalone}%
\usepackage{pst-node}
\usepackage{auto-pst-pdf}
\begin{document}
\sffamily
\psset{algebraic, yunit = -1, arrows=->, arrowinset=0.12, linecolor=SteelBlue3, fillcolor=SlateGray3!60, nodesepB=1pt}
\begin{pspicture*}
\foreach \X[count=\I] in {A, B, C, D, E} {\Cnodeput[linecolor=SteelBlue4, fillstyle=solid]{0}(\I, \I){\X}{\X}}
\foreach \X/\Y in{A/B, B/C, C/D, D/E}{\ncline{\X}{\Y}}
\ncarc[arcangle=-25]{A}{D}
\ncarc[arcangle=25]{A}{C}
\psset{border=1pt}
\ncarc[arcangle=-45]{A}{B}
\ncarc[arcangle=45]{B}{C}
\ncarc[arcangle=45]{C}{D}
\ncarc[arcangle=-35]{B}{D}
\ncarc[arcangle=-45]{D}{E}
\end{pspicture*}
\end{document}
TikZ
provides at least two general approaches for drawing graphs. In the first approach, the user defines the placement of coordinates manually in relation to the origin. The second approach is to use a TikZ
graph drawing algorithm, in which case, the algorithm determines the node placement. Several algorithms are provided, which can be classified into two broading groups: those that produce graphs of a defined shape (e.g. circular
, tree
, layered
) versus those whose shape is not predefined (e.g. spring
). TikZ
provides a range of macros for modifying node placement of graphs drawing with a graph drawing algorithm.
The example posted is suitable for using a layered layout
. This answer steps through the steps required for creating the graphs. This is illustrated with 5 examples.
Example 1 just grows the graph horizontally. No graph drawing algorithm is used and grow=315
is not respected here. If we want the graph to grow south-east, we have to do something else.
Example 2 uses node anchors to specifically place nodes at known locations on the canvas. Manual intervention is required to achieve the direction of growth by specifically nominating the node placement.
Example 3 introduces the use of the layered layout algorithm. It's fine for the "backbone", but if we try to add other graph elements, the algorithm will move the nodes to accommodate the new information. That's not what we want.
Example 4 uses subgraph nodes to place each of the graph relationships in relation to others. A red edge is added to illustrate how individual edges can be customized.
Example 5 illustrates how to use two different edge styles and customization of the edge bend.
The nodes are labelled to make it easier to follow the code. To turn off the labels, just add empty nodes
to the graph options.
This is the MWE. Thanks to Michael and his answer for the node and edge formatting.
% !TeX TS-program = lualatex
\RequirePackage{luatex85}
\documentclass[a3paper]{article}
\usepackage{tikz}
\usepackage[margin=0.75cm]{geometry}
\pagestyle{empty}
\usetikzlibrary{
graphs,
graphdrawing
}
\usegdlibrary{
layered, % requied for layered layout
trees
}
% define styles for arrows and text nodes from https://tex.stackexchange.com/a/394946
\tikzset{
majoredges/.style={
draw=eedge,
line width=1pt,
->, % alwways draw arrow tip
>=stealth, % style of arrow tip
shorten >=2pt, % shorten a bit, so that it doesn't quite
shorten <=2pt, % touch the nodes
preaction={ % provide a wider white background for
draw=white, % each arrow for the intersection effect
line width=3pt,
-, % no arrow tip for background
}
},
minoredges/.style={
draw=medge,
line width=0.25pt,
->, % alwways draw arrow tip
>=stealth, % style of arrow tip
shorten >=2pt, % shorten a bit, so that it doesn't quite
shorten <=2pt, % touch the nodes
preaction={ % provide a wider white background for
draw=white, % each arrow for the intersection effect
line width=3pt,
-, % no arrow tip for background
}
},
every node/.style={
anchor=center,
text=black,
inner sep=2pt,
shape=circle,
draw=bbord, % border
fill=ffill, % background
font=\footnotesize,
minimum height=15pt % assign minimum height to make nodes equally
% large, regardless of letter size
}
}
\definecolor{bbord}{RGB}{70,78,82} % node border
\definecolor{ffill}{RGB}{171,213,238} % node fill
\definecolor{eedge}{RGB}{27,128,196} % major edge
\definecolor{medge}{RGB}{96,15,36} % minor edge
\begin{document}
\textbf{Example 1}\par
Grow horizontally
\begin{tikzpicture}
\graph [
% % no graph drawing algorithm
%empty nodes, % show node labels
grow=315, % Not respected here
edges=majoredges % use edge style defined with tikzset
]
{
a -> b -> c -!- d -> e -!- f -> g -> h -!- i;
a ->[bend right] d;
b ->[bend left] g;
d ->[bend left] f;
d ->[bend right] i;
e ->[bend right] h;
e ->[bend left] i;
}
;
\end{tikzpicture}
\textbf{Example 2:}\par
Anchor the nodes on the canvas (TikZ manual §27.4)
\begin{tikzpicture}[x=0.75cm,y=1.5cm]
\graph [
% % no graph drawing algorithm
%empty nodes, % show node labels
grow=315, % Not respected here
edges=majoredges % use edge style defined with tikzset
]
{
a -> b[x=0.5,y=-0.5] -> c[x=1,y=-1] -!- d[x=1.5,y=-1.5] -> e[x=2,y=-2] -!- f[x=2.5,y=-2.5] -> g[x=3,y=-3] -> h[x=3.5,y=-3.5] -!- i[x=4,y=-4];
a ->[bend right] d;
b ->[bend left] g;
d ->[bend left] f;
d ->[bend right] i;
e ->[bend right] h;
e ->[bend left] i;
}
;
\end{tikzpicture}
\bigskip
\textbf{Example 3:}\par
While we can get the nodes, positioned as required using layered layout + \par grow=315 (left),
as soon as we add an extra edge a -> d,\par the structure is altered (right).
\begin{tikzpicture}
\graph [
layered layout, % no graph drawing algorithm
%empty nodes, % show node labels
grow=315, % Not respected here
edges=majoredges % use edge style defined with tikzset
]
{
{a -> b -> c --[draw=none] d -> e --[draw=none] f -> g -> h --[draw=none] i};
}
;
\end{tikzpicture}%
\begin{tikzpicture}
\graph [
layered layout, % no graph drawing algorithm
%empty nodes, % show node labels
grow=315, % Not respected here
edges=majoredges % use edge style defined with tikzset
]
{
{a -> b -> c --[draw=none] d -> e --[draw=none] f -> g -> h --[draw=none] i};
{a ->[bend right] d};
}
;
\end{tikzpicture}
\textbf{Example 4:}\par
Grow south east and add subgraph nodes (TikZ manual §27.10.2)
\begin{tikzpicture}
\graph [
layered layout, % graph drawing algorithm
%empty nodes,
grow=315, % direction of growth of the graph
edges=majoredges
]
{
% cannot use -!- syntax here to hide the edge. compilation is in endless loop.
// [layered layout] {a -> b -> c --[draw=none] d -> e
--[draw=none] f -> g -> h --[draw=none] i};
// [layered layout] {a ->[bend left,red] d};
// [layered layout] {b ->[bend left] g};
// [layered layout] {d ->[bend left] f};
// [layered layout] {d ->[bend right] i};
// [layered layout] {e ->[bend right] h};
// [layered layout] {e ->[bend left] i};
};
\end{tikzpicture}
\bigskip
\textbf{Example 5:}\par
Wikipedia example: two edge types and modified edge bends
\begin{tikzpicture}
\graph [
layered layout, % graph drawing algorithm
sibling distance=1.5cm,
layer distance=1.5cm,
%empty nodes,
grow=315, % direction of growth of the graph
edges=majoredges
]
{
% cannot use -!- syntax here to hide the edge. compilation is in endless loop.
// [layered layout] {a -> b -> c --[draw=none] d -> e
--[draw=none] f -> g -> h --[draw=none] i};
// [layered layout] {a ->[bend right=50,red] d};
// [layered layout] {b ->[bend left=50] g};
// [layered layout] {d ->[bend left=30] f};
// [layered layout] {d ->[bend right=40] g};
// [layered layout] {d ->[bend right=50] i};
// [layered layout] {e ->[bend left=40] h};
// [layered layout] {e ->[bend left=40] i};
// [layered layout] {a ->[bend left=50,minoredges] c};
// [layered layout] {a ->[bend right=60,minoredges] e};
// [layered layout] {a ->[bend left=50,minoredges] f};
// [layered layout] {a ->[bend left=70,minoredges] g};
// [layered layout] {a ->[bend left=80,minoredges] h};
// [layered layout] {a ->[bend right=70,minoredges] i};
// [layered layout] {b ->[bend left=70,minoredges] h};
// [layered layout] {d ->[bend left=50,minoredges] h};
// [layered layout] {f ->[bend right,minoredges] h};
};
\end{tikzpicture}
\end{document}
Here is a start:
\documentclass[crop,border=1pt]{standalone}
\usepackage{tikz,xcolor}
% define styles for arrows and text nodes
\tikzset{
myarrow/.style={
draw=blue,
line width=1pt,
->, % alwways draw arrow tip
>=stealth, % style of arrow tip
shorten >=2pt, % shorten a bit, so that it doesn't quite
shorten <=2pt, % touch the nodes
preaction={ % provide a wider white background for
draw=white, % each arrow for the intersection effect
line width=3pt,
-, % no arrow tip for background
}
}
}
\tikzstyle{every node}=[
anchor=center,
text=black,
fill=white,
inner sep=2pt,
shape=circle,
draw=blue, % border
fill=blue!20, % background - blue!20 is 20% blue, 80% white
font=\footnotesize,
minimum height=15pt % assign minimum height to make nodes equally
% large, regardless of letter size
]
\begin{document}
\begin{tikzpicture}[x=1cm,y=1cm] % scale coordinate system
\path % define points.
(0,10) node (a) {a} % (a) is a label that we refer to when
(2,8) node (b) {b} % adding the arrows, {a} is the text content
(4,6) node (c) {c}
(6,4) node (d) {d}
(8,2) node (e) {e}
;
\draw[myarrow] (a) -- (b); % draw a straight arrow
\draw[myarrow] (b) to [out=0,in=90] (d); % draw a bezier-shaped arrow, specifying
% angles of departure and arrival
\draw[myarrow] (c) to [out=0,in=90,looseness=1.25] (e); % looseness tweaks the bezier shape
\end{tikzpicture}
\end{document}
You can easily declare additional styles, say, myredarrow
by just changing draw=blue
to draw=red
. If you have multiple style declarations in the same \tikzset
clause, they must be separated by commas.
You can also have finer control of your bezier curves by declaring explicit control points, like so:
\draw[myarrow] (a) .. controls (c1) and (c2) .. (b);
This assumes that you have declared c1
and c2
as coordinates, like so:
\path
(3,5) coordinate (c1)
(6,8) coordinate (c2)
;