Creating Graphs and Graph Types #
If you followed the installation process (see Installing NetworkX, you should now have NetworkX and Pandas successfully installed on the system. It’s now time to create some graphs, but first a little theory.
Theory #
Networks usually share two key features: they have nodes and edges. Sure, there are different types of networks out there, but they all boil down to having nodes (you might also hear them called vertices or points) and edges. Think of nodes as the things you’re connecting (people, computers, entities, etc.), while edges are the connections or links between them.
Just so we’re on the same page, the terms “networks” and “graphs” basically mean the same thing, so I might use them interchangeably. Don’t worry—they’re just two ways to talk about the same concept.
Python Code #
Creating a New Graph #
Now it’s time to get things going! Let’s begin by importing NetworkX into the script.
>>> import networkx as nx
To initialise an empty graph with no nodes or edges, we use the built-in Graph
object to get things going. This can be achieved as follows…
>>> G = nx.Graph()
Adding nodes #
As an example, let’s create a simple graph where we want to add three people known as Alice, Ben and Charlie. This is as simple as…
>>> G.add_node("Alice")
>>> G.add_node("Ben")
>>> G.add_node("Charlie")
Rather than adding them one by one, we can use a shortcut and do it all in one go with the following line…
>>> G.add_nodes_from(["Alice", "Ben", "Charlie"])
To keep track of how many nodes we have in our network, we can use the following line to see what we’ve got
>>> G.nodes()
NodeView(('Alice', 'Ben', 'Charlie'))
G.nodes()
maintains a list of all the nerds that are featured in the graph. This is useful to know as we can use this function to keep track of what is already included.
Adding Edges #
Now that we’ve got a graph that contains nodes, we can now start to link them together. In our case, an edge represents a friendship. If Alice and Ben are to be friends then we do the following…
>>> G.add_edge("Alice", "Ben")
Much like before, there are one of two ways to add edges to the network. The first option involves creating a single edge (as shown above) or we can create multiple edges in one go using…
>>> G.add_edges_from([("Alice", "Ben"), ("Ben", "Charlie")])
In this example, we use the Python tuple data structure to form a list of edges. To see the newly created edges, we use the G.edges()
function.
>>> G.edges()
EdgeView([('Alice', 'Ben'), ('Ben', 'Charlie')])
Attributes #
So far, the graphs we’ve created are pretty simple and don’t have much detail. Let’s say we want to add more information about specific nodes or edges in the graph. For instance, in our example, we might want to add attributes to nodes to show a person’s age or include edge attributes to represent how long a friendship has lasted.
There are tons of ways you can use attributes, but the main idea is that they help to highlight certain parts of the network. With NetworkX, it’s super easy to attach attributes to edges and nodes, which makes everything much clearer.
Setting and reading attributes is really straightforward since they use key-value pair mapping. You set attributes while creating an edge. For example, if I wanted to show how long a friendship has been going on, I’d set an attribute like this:
>>> G.add_edge('Alice', 'Charlie', years_friends=9)
It’s essentially a variable. Reading values again is very straightforward…
>>> print(G['Alice']['Charlie']['years_friends'])
9
Weights #
In social networks, it’s common to include a wait to document how many times an edge has been used between a pair of users. It’s essentially the sum of all interactions. This again is treated as an attribute using the ‘weight’ key.
Graph generators #
There are loads of ways to generate networks with NetworkX. In this post, we kept it simple by manually adding nodes and edges. But NetworkX has a bunch of built-in algorithms for creating different types of graphs, which can come in handy if you want to simulate some real-world data without actually going out and collecting it.
We won’t dive too deep, but here are a few useful generators that NetworkX provides. You can check out the full list here.
- Complete graph: This one creates a graph where every node is connected to every other node—fully connected.
- Random: There are a few variations of this, but basically, nodes and edges are added randomly based on a chosen distribution.
- Paths: Generates a linear structure, where nodes and edges are arranged in a straight line, like a chain.
- Cycle: Similar to a path, but the last node loops back to the first one, forming a cycle.
- Tree: Think of this like a hierarchy—nodes and edges are arranged to show levels of dependency or inheritance.
- Lattice: Nodes and edges are laid out in a grid-like structure, almost like a mesh.
Graph types #
One of the coolest things about NetworkX is that you can create different types of networks. In the example from this guide, we worked with a basic undirected graph using the nx.Graph
type. But there are a few other graph types that are popular in network analysis.
- DiGraph: This is just like a regular graph, except the edges have a direction, pointing from one node to another—kind of like a one-way street that shows a relationship or interaction that isn’t always mutual.
- MultiGraph: Sometimes graphs get complicated, and edges can represent different things. A MultiGraph lets you have multiple edges between the same pair of nodes, useful when tracking interactions that happen more than once.
- MultiDiGraph: Same idea as a MultiGraph, but with directed edges. You can have multiple directed edges between nodes, in different directions.
Conclusions #
In this guide, we went through the basic steps of creating and filling up a graph. The method we used is super simple, but for more complex graphs, you might want to explore other formats. We’ll cover those in another guide.
Prev: Simple Metrics Next: Node Profiling