Skip to main content
Logo image

Section 3.9 Networks

PreFigure enables authors to create diagrams of networks, such as that shown in Figure 3.9.1. Mathematicians sometimes refer to these as graphs, but we will use the term network to distinguish them from graphs of functions. There is quite a bit of flexibility as will be explained in the remainder of this section.
Figure 3.9.1. A simple network.

Subsection 3.9.1 Getting started

Let’s begin by discussing Figure 3.9.1. Notice that it is a directed network and that there are multiple edges between two of the vertices. The PreFigure source is in Listing 3.9.2.
<diagram dimensions="(300,300)" margins="5">
  <definition>graph={1:[3,4,5,5],2:[4,5],3:[4,5],6:[2,4]}</definition>
  <coordinates bbox="(-1,-1,1,1)">
    <network directed="yes" graph="graph" scale="0.8"
	     node-fill="#fcf" node-stroke="black"
	     seed="1" labels="yes"
	     tactile-node-size="40">
    </network>
  </coordinates>
</diagram>
Listing 3.9.2. The PreFigure source for Figure 3.9.1.
The network is defined by the dictionary in line 2 where each key in the dictionary defines a node in the network and the corresponding value lists the nodes connected by edges. Notice that node 1 is connected to node 5 by two edges, as seen in the diagram.
The <network> element then constructs the graphical representation of the network. There are quite a few attributes for that element so let’s take a moment to consider them.
graph
The @graph attribute tells PreFigure about the dictionary that defines the structure of the network.
directed
The attribute @directed="yes" declares this to be a directed network, which means that the edges have a direction indicated by arrows. If this attribute is set to "no", which is the default, then no arrows are placed on the edges.
labels
Use @labels="yes" to include labels inside the nodes.
scale
The nodes will fit just inside the bounding box defined by the current coordinate system so the value of @scale can be used to pull the nodes in toward the center. The default is @scale="0.8".
node-fill
The @node-fill attribute defines the color to use when filling the nodes. This is part of a collection of attributes that control the visual appearance of the network. Each <node> will generate a <point> so other attributes include @node-stroke, @node-thickness, @node-size, @node-style.
Similarly, an edge will generate a <path> so some path attributes can be applied, such as @edge-stroke, @edge-thickness, and @edge-dash.
seed
The algorithm that determines the positions of the nodes uses a random seed. To ensure consistent behavior while you are developing a diagram, set the value of the @seed attribute so that the nodes will stay in the same position from one compilation to the next. If you are not satisfied with the appearance of the network, you could try using a different seed.

Subsection 3.9.2 A more verbose network

A second way of defining the same network is shown in Listing 3.9.3. In this case, we do not define the structure of the network using a dictionary. Instead, we include <node> elements as children of <network>. The @edges attribute for each node defines the edges connecting that node to others.
As we will see shortly, we can mix these two approaches to defining the network for more flexibility.
<diagram dimensions="(300,300)" margins="5">
  <coordinates bbox="(-1,-1,1,1)">
    <network directed="yes" scale="0.8"
	     node-fill="#fcf" node-stroke="black"
	     seed="1" labels="yes"
	     tactile-node-size="40">
      <node at="1" edges="[3,4,5,5]"/>
      <node at="2" edges="[4,5]"/>
      <node at="3" edges="[4,5]"/>
      <node at="4"/>
      <node at="5"/>
      <node at="6" edges="[2,4]"/>
    </network>
  </coordinates>
</diagram>
Listing 3.9.3. Another PreFigure source for Figure 3.9.1.

Subsection 3.9.3 Positioning the nodes

PreFigure relies on the Python package networkx to determine the positions of the nodes, a process referred to as layout. This subsection shows some examples that demonstrate the possibilities.
First, we may explicitly declare where we would like the nodes to be by including a @p attribute for each node.
Figure 3.9.4. The complete graph on 5 vertices.
<diagram dimensions="(300,300)" margins="5">
  <coordinates bbox="(-1,-1,1,1)">
    <definition>N=5</definition>
    <definition>f(t)=(cos(2*pi*t/N), sin(2*pi*t/N))</definition>
    <network scale="0.8" labels="yes"
	     node-fill="#ccf" node-stroke="black"
	     tactile-node-size="40">
      <node at="0" p="f(0)" edges="[1,2,3,4]"/>
      <node at="1" p="f(1)" edges="[2,3,4]"/>
      <node at="2" p="f(2)" edges="[3,4]"/>
      <node at="3" p="f(3)" edges="[4]"/>
      <node at="4" p="f(4)"/>
    </network>
  </coordinates>
</diagram>
Listing 3.9.5. The PreFigure source for Figure 3.9.4.
Alternatively, we can define the structure of the graph by including a @graph attribute inside the <network> element and then using <node> elements to set the positions. This is seen in Listing 3.9.6.
<diagram dimensions="(300,300)" margins="5">
  <coordinates bbox="(-1,-1,1,1)">
    <definition>graph={0:[1,2,3,4], 1:[2,3,4], 2:[3,4], 3:[4]}</definition>
    <definition>N=5</definition>
    <definition>f(t)=(cos(2*pi*t/N), sin(2*pi*t/N))</definition>
    <network scale="0.8" labels="yes" graph="graph"
	     node-fill="#ccf" node-stroke="black"
	     tactile-node-size="40">
      <node at="0" p="f(0)"/>
      <node at="1" p="f(1)"/>
      <node at="2" p="f(2)"/>
      <node at="3" p="f(3)"/>
      <node at="4" p="f(4)"/>
    </network>
  </coordinates>
</diagram>
Listing 3.9.6. A second source for Figure 3.9.4.
Nodes are created when they are referenced in the dictionary defined by the @graph attribute. When a <node> element is encountered inside the <network> element, PreFigure checks to see if the node has already been defined. If not, it will add it to the graph using the @edges attribute to append more structure to the network. While this is allowed, it is not necessary and could be confusing to author and maintain a network defined like this.
In these last two examples, we have specified the position of the nodes as an attribute inside the <node> element. If we would like networkx to position the nodes, we have some more options.
By default, PreFigure will use the spring layout defined by networkx. Two other options are bfs, a shorthand for breadth-first, and spectral. Interested authors are encouraged to consult the networkx documentation for more information.
We can prescribe a different layout method using the @layout of the <network> element. The diagram in Figure 3.9.7 illustrates how the @layout="bfs" can be used to illustrate a binary tree.
Figure 3.9.7. A binary tree.
<diagram dimensions="(300,300)" margins="5">
  <definition>
    graph={0:[1,2],1:[3,4],2:[5,6],3:[7,8],4:[9,10],5:[11,12],6:[13,14]}
  </definition>
  <coordinates bbox="(-1,-1,1,1)">
    <rectangle center="(0,0)" dimensions="(2,2)" stroke="black"/>
    <network layout="bfs" start="0" graph="graph" node-fill="orange"
	     rotate="-90" scale="0.8">
      <node at="0" fill="red"/>
      <edge vertices="[0,1]" stroke="blue" thickness="4"/>
    </network>
  </coordinates>
</diagram>
Listing 3.9.8. The PreFigure source for Figure 3.9.7.
There are a couple of features to notice here. If we use the bfs algorithm for the layout, we need to specify a node at which to @start. This is an attribute of the <network> element.
The bfs algorithm produces a tree that moves from left to right. To depict the tree with the root at the top, we use @rotate="-90" to rotate the graph.
Since we would like the root to be colored differently, we use a <node> element to specify the color of that node.
In the same way, we use an <edge> element to modify the appearance of a particular edge that has already been added to the graph structure. If the edge has not been added previously, then it will be added to the structure of the graph.

Subsection 3.9.4 Putting everything together

Networks have a lot of features so it may be worthwhile to show an example that illustrates how these features can be used in mathematical exposition. Suppose that we would like to explain the idea of a spanning tree as a subgraph of a graph \(G\text{.}\) On the left of Figure 3.9.9 is the graph \(G\) with a collection of dashed edges. If we remove those edges, we obtain a spanning tree as shown on the right. To make the point clear, we would like the nodes to be in the same positions in both diagrams.
Figure 3.9.9. A graph \(G\) with some edges indicated on the left. When those edges are removed, we have a spanning tree as seen on the right.
<diagram dimensions="(250,250)" margins="5">
  <definition>graph={1:[3,4,5],2:[4,5],3:[4,5],6:[2,4]}</definition>
  <coordinates bbox="(-1,-1,1,1)">
    <network graph="graph" scale="0.8"
	     node-fill="#fcf" node-stroke="black"
	     seed="1" labels="yes" node-style="box"
	     tactile-node-size="40">
      <edge vertices="[3,5]" dash="9 9"/>
      <edge vertices="[1,4]" dash="9 9"/>
      <edge vertices="[4,6]" dash="9 9"/>
      <edge vertices="[2,4]" dash="9 9"/>
    </network>
  </coordinates>
</diagram>
Listing 3.9.10. The PreFigure source for the left of Figure 3.9.9.
The PreFigure source for Figure 3.9.9 is shown in Listing 3.9.10. Notice how the structure of the graph is defined using a dictionary with instructions given to draw some edges as dashed lines.
The PreFigure source to create the diagram on the right is quite similar except that we replace @dash="9 9" in the <edge> elements with @stroke="none".
<diagram dimensions="(250,250)" margins="5">
  <definition>graph={1:[3,4,5],2:[4,5],3:[4,5],6:[2,4]}</definition>
  <coordinates bbox="(-1,-1,1,1)">
    <network graph="graph" scale="0.8"
	     node-fill="#fcf" node-stroke="black"
	     seed="1" labels="yes" node-style="box"
	     tactile-node-size="40">
      <edge vertices="[3,5]" stroke="none"/>
      <edge vertices="[1,4]" stroke="none"/>
      <edge vertices="[4,6]" stroke="none"/>
      <edge vertices="[2,4]" stroke="none"/>
    </network>
  </coordinates>
</diagram>
Listing 3.9.11. The PreFigure source for the right of Figure 3.9.9.