1

I want to visualize a social network with nodes and edges, with colors of nodes representing values of attributes. It will be nice if I can do it with tools in python (like networkx), but I am also open to other tools (like Gephi , graph-tools) . The nodes and edges that I have in my social network are in the form of numpy arrays. I want nodes of this visualization to be colored according to values of attributes.

Each row in the nodes array points to an user. Each column in the nodes array points to an attribute. The values in each column of the nodes array point to attribute values. Here is an example of a nodes array with 10 users and 3 attributes (with names [Att1, Att2, Att3].

Nodes = np.array([[1,2,4],[1,3,1],[2,2,1],[1,1,2],
              [1,2,2],[2,1,4],[1,2,1],[2,0,1],
              [2,2,4],[1,0,4]])

Similarly, the edges array (adjacency matrix) is a square array of size number of nodes * number of nodes. A value of 1 in the adjacency matrix points to a presence of an edge between two nodes, and a value of 0 points to absence of an edge. Here is an example of an edges array.

Edges = np.random.randint(2, size=(10,10))

Let's say I want the nodes to be colored according to attribute values given in the middle column of Nodes (i.e. Attribute_Value = Nodes[:,1] = [2, 3, 2, 1, 2, 1, 2, 0, 2, 0]) There are four unique attribute values [0,1,2,3] so, I will like to have four different colors for the nodes. In my actual graph, I have many more unique values for attributes. Also, I have tens of thousands of nodes, so I will like to be able to adjust the sizes (radii) of nodes in my plot.

Following a previous post of mine, I have tried this:

import networkx as nx
G = nx.from_numpy_array(Edges)
nx.draw(G, with_labels=True)

But, results from the above code snippet do not let me choose colors as per attribute values. Also, I will need to adjust sizes of nodes. How can I visualize social graphs in the described way?

Siddharth Satpathy
  • 2,737
  • 4
  • 29
  • 52

2 Answers2

2

Networkx allows visualizing graphs and specifying nodes' sizes and colors. For example:

import networkx as nx
import matplotlib.pyplot as plt

G = nx.barabasi_albert_graph(20, 2)
node_colors = [x for x in range(20)]
node_sizes = [50 * x for x in range(20)]
cmap = plt.cm.jet
nx.draw_networkx(G,
                 with_labels=True,
                 labels={node : 'some text {}'.format(node) for node in G.nodes()},
                 node_color=node_colors,
                 node_size=node_sizes,
                 cmap=cmap)
plt.show()
  • labels - is an array of labels (according to the order of G.nodes())
  • node_sizes - is an array of integers specifying the size of each node
  • node_colors - is an array of numbers specifying the color of each node
  • cmap - is mapping each number to a specific color

This results with: enter image description here

To fully understand how Networkx drawing works I suggest reading the documentation.

Personally, for exploring and visualizing a specific graph instance I prefer to save the networkx graph to a file, and load it with gephi. If you want an automated process for many instances of graphs networkxs would probably be better.

In case you choose gephi, just load a graph and play with the GUI, it's pretty self explanatory.

zohar.kom
  • 1,765
  • 3
  • 12
  • 28
1

networkx.draw accepts lists for node_color and node_size that need to be as long as the number of nodes. So you simply need to map your unique attributes to some colors, and create those lists. If you have many different attributes, you will want to do that mapping automatically. Below, I outline 2 options, one using the matplotlib color cycle, and another simply assigning random colors to unique attributes.

import numpy as np
import matplotlib.pyplot as plt
import networkx as nx

Nodes = np.array([[1,2,4],
                  [1,3,1],
                  [2,2,1],
                  [1,1,2],
                  [1,2,2],
                  [2,1,4],
                  [1,2,1],
                  [2,0,1],
                  [2,2,4],
                  [1,0,4]])
Edges = np.random.randint(2, size=(10,10))
attribute_values = Nodes[:,1]

# make a color mapping from node attribute to color

# option 1: using the matplotlib color cycle;
# however, you may run out of colors if there are many different unique attributes
color_cycle = plt.rcParams['axes.prop_cycle'].by_key()['color']
attribute_to_color = dict()
for ii, attribute in enumerate(np.unique(attribute_values)):
    attribute_to_color[attribute] = color_cycle[ii]

# option 2: assign random colors
attribute_to_color = dict()
for ii, attribute in enumerate(np.unique(attribute_values)):
    attribute_to_color[attribute] = np.random.rand(3)

node_color = [attribute_to_color[attribute] for attribute in attribute_values]

# adjust node sizes according to some other attribute
node_size = Nodes[:, 2] * 100

G = nx.from_numpy_matrix(Edges)
nx.draw(G, node_color=node_color, node_size=node_size, with_labels=True)
plt.show()
Paul Brodersen
  • 11,221
  • 21
  • 38