The Witch’s Brew: Python fangs

BigVisualData
4 min readJan 3, 2023

--

Best read listening to Rhapsody & Christopher Lee “The Magic of the Wizard’s Dream”

So far, we have gone through the inspiration and preparation for creating a two-mode network with the ingredients and potions of Harry Potter books, films and videogames, and followed the steps necessary to create and visualiza the network in Gephi. Let us now turn to Python.

Another option to work with networks is to use programming languages like Python or R. This allows for nice and interactive visualizations, along with computing relevant statistic metrics like the ones used in Gephi. Networkx is the library of choice, and I found a lot of useful code snippets in Melanie Walsh’s Introduction to Cultural Analytics & Python.

To make long issues short, I took the gexf file and imported it to python. Of course, it didn’t work.

import networkx as nx
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
G = nx.read_gexf('Syntages-networkx.gexf')
“No <graph> element in GEXF file” error

A quick search gave the solution: open the gexf file in Notepad for Windows or Textedit in Mac and change the header from

<gexf xmlns="http://www.gexf.net/1.3" version="1.3" xmlns:viz="http://www.gexf.net/1.3/viz" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.gexf.net/1.3 http://www.gexf.net/1.3/gexf.xsd">

to

<gexf version="1.2" xmlns="http://www.gexf.net/1.2draft" xmlns:viz="http://www.gexf.net/1.2/viz" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.gexf.net/1.2draft http://www.gexf.net/1.2draft/gexf.xsd">

A new error came up, necessitating a discussion about edges.

“Directed edge found in undirected graph” error

Uh, Edges got mixed up

Edges come in two fashions: directed and undirected.

Directed edges are one-way: They designate a From-To direction. As in a relationship when A is in love with B, but B does not respond. As in Twitter when A is following B, but B is not following back. As in Cookbooks when ingredients are part of a recipe!

Undirected edges are two-way: They are mutual. As in a travel you go from place A to place B, and then you come back from B to A. As in a friendship in real life or in Facebook: A and B are friends, hence each one of them is friend to the other. As in Cookbooks all the ingredients must go together well to prepare a dish [or a potion]!

While Gephi can use networks with both directed and undirected edges (mixed), networkx cannot. Therefore, I had to change directed to undirected. Then everything worked smoothly.

A first glimpse to the network

I computed Degree centrality, Weighted Degree, Betweenness, the Communities (based on Modularity classes), and created a pandas dataframe to keep all metrics in a table (some day I will compare those metrics with the ones produced by Gephi to discuss compatibility issues).

# Compute degree
nx.degree(G)
degrees = dict(nx.degree(G))
nx.set_node_attributes(G, name='degree', values=degrees)
degree_df = pd.DataFrame(G.nodes(data='degree'), columns=['node', 'degree'])
degree_df = degree_df.sort_values(by='degree', ascending=False)
More metrics in one dataframe

The images of the network produced were not really enlightening. Nodes were huge and overlapping without edges to indicate connections. Everything was drawn in the same boring blue, too bright (value=98%), unsaturated (saturation=4), dull. Boring.

The original visualization in Networkx: Boring!

This is where Bokeh enters the scene to make things interesting again. And interactive.

A little code brewing…

from bokeh.io import output_notebook, show, save
output_notebook()
from bokeh.models import Range1d, Circle, ColumnDataSource, MultiLine
from bokeh.plotting import figure
from bokeh.plotting import from_networkx

# Basic Network
#Choose a title!
title = "The Witch's Brew"

#Establish which categories will appear when hovering over each node
HOVER_TOOLTIPS = [("Ingredient or Potion", "@label")]

#Create a plot — set dimensions, toolbar, and title
plot = figure(tooltips = HOVER_TOOLTIPS,
tools="pan,wheel_zoom,save,reset", active_scroll='wheel_zoom',
x_range=Range1d(-10.1, 10.1), y_range=Range1d(-10.1, 10.1), title=title)

#Create a network graph object with spring layout
# https://networkx.github.io/documentation/networkx-1.9/reference/generated/networkx.drawing.layout.spring_layout.html
network_graph = from_networkx(G, nx.spring_layout, scale=10, center=(0, 0))

#Set node size and color
network_graph.node_renderer.glyph = Circle(size=5, fill_color='skyblue')

#Set edge opacity and width
network_graph.edge_renderer.glyph = MultiLine(line_alpha=0.5, line_width=1)

#Add network graph to the plot
plot.renderers.append(network_graph)

show(plot)

…and there it comes.

The Witch’s Brew network in Python, with Networkx and Bokeh

With a little more brewing it became interactive as well. Just click here to open the interactive webpage.

Next comes the network in two more softwares.

--

--

BigVisualData

Analyzing Visual Corpora with computational methods. It’ll provide pieces on methodology, sociological & semiotics viewpoints. Yannis Skarpelos