Using NetworkX, how is it possible to plot a directed, unweighted graph, given set of edges with a legend?

928 Views Asked by At

I am currently working on a project where I have to deal with Bayesian Networks and given the graphical nature of these probabilistic models, it is very essential to visualize them as a graph. I am using pgmpy for my project.

The model I am dealing with has a large number of variables, often having long names as data identifiers. I therefore was contemplating on illustrating the graph with a legend and each node having a 'code' or a 'number', mapping to a data identifier (perhaps a dict could be used).

The edges I have are in the following format:

[('A','B'), ('B', 'C'), ('C','A')]

In other words, an array of 2-tuples of strings.

It would be great if someone could help me in solving this particular issue.

1

There are 1 best solutions below

0
On

pgmpy models (at least BayesianNetworks) inherit from nx.Digraphs and can be visualized using nx.draw, which takes a Matplotlib Axes object as optional parameter. Therefore, one can create an axes object, manually add a legend, hide the handles, relabel the nodes and draw the model.

Here is an example using a dict (as suggested) for identifier mapping:

import networkx as nx
from pgmpy.models import BayesianNetwork
import matplotlib.pyplot as plt
from matplotlib import patches

identifier_mapping = {'long_identifier_for_A': 'A',
                      'long_identifier_for_B': 'B',
                      'long_identifier_for_C': 'C'}
model = BayesianNetwork([('long_identifier_for_A', 'long_identifier_for_B'),
                           ('long_identifier_for_C', 'long_identifier_for_B')])

# add identifier mappings to legend
ax = plt.subplot()
handles = [patches.Patch(label=f'{identifier_mapping[node]}: {node}') for node in model.nodes()]
ax.legend(handles=handles, handlelength=0, handletextpad=0, fancybox=True)

# draw model
nx_graph = nx.relabel_nodes(model, identifier_mapping)
nx.draw(nx_graph, ax=ax, with_labels=True, pos=nx.random_layout(nx_graph))
plt.show()

bayesian network


PS:

  • To avoid the relabeling step one can directly create the model with short identifiers and store a mapping to the long ones.
  • The edges from the question ([('A','B'), ('B', 'C'), ('C','A')]) form a cycle (Bayesian Networks are asyclic).
  • In case nx.draw raises a StopIteration exception checkout this question.