Les Misrebles Network Analysis using NetworkX

More details at: http://networkx.readthedocs.io/en/networkx-1.10/index.html

Source: http://www-personal.umich.edu/~mejn/netdata/ and http://networkdata.ics.uci.edu/data/lesmis/ Code adopted from: https://github.com/networkx/notebooks

Citation: Les Miserables: coappearance network of characters in the novel Les Miserables. Please cite D. E. Knuth, The Stanford GraphBase: A Platform for Combinatorial Computing, Addison-Wesley, Reading, MA (1993).


In [1]:
%matplotlib inline

from operator import itemgetter
import networkx as nx

import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
import seaborn as sns

import os
from io import StringIO
import pydotplus
from IPython.display import SVG, display

In [2]:
sns.set_context("poster")
sns.set_style("ticks")

In [3]:
DATA_DIR="../data"
INPUT_NETWORK=os.path.join(DATA_DIR, "lesmis","lesmis.gml")
INPUT_NETWORK


Out[3]:
'../data/lesmis/lesmis.gml'

Reading the GML format

Please read the following about the GML format for storing networks http://networkx.readthedocs.io/en/networkx-1.10/reference/readwrite.gml.html#format


In [4]:
G = nx.read_gml(INPUT_NETWORK)
#nx.write_gml(G, "../data/lesmis/lesmis.paj.gml")

In [5]:
df_node_degree = pd.DataFrame(list(dict(G.degree()).items()), columns=["node_name", "degree"])

In [6]:
df_node_degree.sort_values("degree", ascending=False).head(10)


Out[6]:
node_name degree
10 Valjean 36
33 Gavroche 22
36 Marius 19
20 Javert 17
18 Thenardier 16
16 Fantine 15
37 Enjolras 15
38 Bossuet 13
62 Courfeyrac 13
69 Joly 12

In [7]:
print("radius: {:d}\n".format(nx.radius(G)))
print("diameter: {:d}\n".format(nx.diameter(G)))
print("eccentricity: {}\n".format(nx.eccentricity(G)))
print("center: {}\n".format(nx.center(G)))
print("periphery: {}\n".format(nx.periphery(G)))
print("density: {:f}".format(nx.density(G)))


radius: 3

diameter: 5

eccentricity: {'Myriel': 4, 'Napoleon': 5, 'MlleBaptistine': 4, 'MmeMagloire': 4, 'CountessDeLo': 5, 'Geborand': 5, 'Champtercier': 5, 'Cravatte': 5, 'Count': 5, 'OldMan': 5, 'Valjean': 3, 'Labarre': 4, 'Marguerite': 4, 'MmeDeR': 4, 'Isabeau': 4, 'Gervais': 4, 'Fantine': 4, 'MmeThenardier': 4, 'Thenardier': 3, 'Cosette': 4, 'Javert': 3, 'Fauchelevent': 4, 'Bamatabois': 4, 'Simplice': 4, 'Scaufflaire': 4, 'Woman1': 4, 'Judge': 4, 'Champmathieu': 4, 'Brevet': 4, 'Chenildieu': 4, 'Cochepaille': 4, 'Woman2': 4, 'MotherInnocent': 4, 'Gavroche': 3, 'Gillenormand': 4, 'MlleGillenormand': 4, 'Marius': 3, 'Enjolras': 3, 'Bossuet': 3, 'Gueulemer': 3, 'Babet': 3, 'Claquesous': 4, 'Montparnasse': 3, 'Toussaint': 4, 'Tholomyes': 4, 'Listolier': 5, 'Fameuil': 5, 'Blacheville': 5, 'Favourite': 5, 'Dahlia': 5, 'Zephine': 5, 'Perpetue': 5, 'Eponine': 4, 'Anzelma': 4, 'Magnon': 5, 'Pontmercy': 4, 'Boulatruelle': 4, 'Brujon': 4, 'LtGillenormand': 4, 'Gribier': 5, 'MmePontmercy': 5, 'Mabeuf': 4, 'Courfeyrac': 4, 'Jondrette': 5, 'MmeBurgon': 4, 'Combeferre': 4, 'Prouvaire': 4, 'Feuilly': 4, 'Bahorel': 4, 'Joly': 4, 'Grantaire': 4, 'Child1': 4, 'Child2': 4, 'MmeHucheloup': 4, 'BaronessT': 4, 'MlleVaubois': 5, 'MotherPlutarch': 5}

center: ['Valjean', 'Thenardier', 'Javert', 'Gavroche', 'Marius', 'Enjolras', 'Bossuet', 'Gueulemer', 'Babet', 'Montparnasse']

periphery: ['Napoleon', 'CountessDeLo', 'Geborand', 'Champtercier', 'Cravatte', 'Count', 'OldMan', 'Listolier', 'Fameuil', 'Blacheville', 'Favourite', 'Dahlia', 'Zephine', 'Perpetue', 'Magnon', 'Gribier', 'MmePontmercy', 'Jondrette', 'MlleVaubois', 'MotherPlutarch']

density: 0.086808

Connected components


In [8]:
connected_components = sorted(nx.connected_component_subgraphs(G), key = len, reverse=True)
print("{} connected components found.".format(len(connected_components)))


1 connected components found.

Drawing the graph


In [9]:
nx.draw(G)


/home/napsternxg/anaconda3/envs/get17_sna/lib/python3.6/site-packages/networkx/drawing/nx_pylab.py:126: MatplotlibDeprecationWarning: pyplot.hold is deprecated.
    Future behavior will be consistent with the long-time default:
    plot commands add elements without first clearing the
    Axes and/or Figure.
  b = plt.ishold()
/home/napsternxg/anaconda3/envs/get17_sna/lib/python3.6/site-packages/networkx/drawing/nx_pylab.py:138: MatplotlibDeprecationWarning: pyplot.hold is deprecated.
    Future behavior will be consistent with the long-time default:
    plot commands add elements without first clearing the
    Axes and/or Figure.
  plt.hold(b)
/home/napsternxg/anaconda3/envs/get17_sna/lib/python3.6/site-packages/matplotlib/__init__.py:917: UserWarning: axes.hold is deprecated. Please remove it from your matplotlibrc and/or style files.
  warnings.warn(self.msg_depr_set % key)
/home/napsternxg/anaconda3/envs/get17_sna/lib/python3.6/site-packages/matplotlib/rcsetup.py:152: UserWarning: axes.hold is deprecated, will be removed in 3.0
  warnings.warn("axes.hold is deprecated, will be removed in 3.0")
/home/napsternxg/anaconda3/envs/get17_sna/lib/python3.6/site-packages/matplotlib/font_manager.py:1297: UserWarning: findfont: Font family ['sans-serif'] not found. Falling back to DejaVu Sans
  (prop.get_family(), self.defaultFamily[fontext]))

In [10]:
fig, ax = plt.subplots(1,1, figsize=(16,16))
nx.draw_networkx(
    G, with_labels=True,
    node_size=[x[1]*10 for x in G.degree_iter()],
    pos=nx.spring_layout(G),
    node_color="g",
    font_size=8,
    ax=ax)
ax.axis("off")


Out[10]:
(-0.10500000000000001, 1.105, -0.10493563726530096, 1.1043226588395958)
/home/napsternxg/anaconda3/envs/get17_sna/lib/python3.6/site-packages/matplotlib/font_manager.py:1297: UserWarning: findfont: Font family ['sans-serif'] not found. Falling back to DejaVu Sans
  (prop.get_family(), self.defaultFamily[fontext]))

In [11]:
def show_graph(G, file_path):
    dotfile = StringIO()
    nx.drawing.nx_pydot.write_dot(G, dotfile)
    pydotplus.graph_from_dot_data(dotfile.getvalue()).write_svg(file_path)
    display(SVG(file_path))

In [12]:
show_graph(G, "../output/lesmis.svg")


Myriel Myriel Napoleon Napoleon Myriel--Napoleon MlleBaptistine MlleBaptistine Myriel--MlleBaptistine MmeMagloire MmeMagloire Myriel--MmeMagloire CountessDeLo CountessDeLo Myriel--CountessDeLo Geborand Geborand Myriel--Geborand Champtercier Champtercier Myriel--Champtercier Cravatte Cravatte Myriel--Cravatte Count Count Myriel--Count OldMan OldMan Myriel--OldMan Valjean Valjean Myriel--Valjean MlleBaptistine--MmeMagloire MlleBaptistine--Valjean MmeMagloire--Valjean Labarre Labarre Valjean--Labarre Marguerite Marguerite Valjean--Marguerite MmeDeR MmeDeR Valjean--MmeDeR Isabeau Isabeau Valjean--Isabeau Gervais Gervais Valjean--Gervais Fantine Fantine Valjean--Fantine MmeThenardier MmeThenardier Valjean--MmeThenardier Thenardier Thenardier Valjean--Thenardier Cosette Cosette Valjean--Cosette Javert Javert Valjean--Javert Fauchelevent Fauchelevent Valjean--Fauchelevent Bamatabois Bamatabois Valjean--Bamatabois Simplice Simplice Valjean--Simplice Scaufflaire Scaufflaire Valjean--Scaufflaire Woman1 Woman1 Valjean--Woman1 Judge Judge Valjean--Judge Champmathieu Champmathieu Valjean--Champmathieu Brevet Brevet Valjean--Brevet Chenildieu Chenildieu Valjean--Chenildieu Cochepaille Cochepaille Valjean--Cochepaille Woman2 Woman2 Valjean--Woman2 MotherInnocent MotherInnocent Valjean--MotherInnocent Gavroche Gavroche Valjean--Gavroche Gillenormand Gillenormand Valjean--Gillenormand MlleGillenormand MlleGillenormand Valjean--MlleGillenormand Marius Marius Valjean--Marius Enjolras Enjolras Valjean--Enjolras Bossuet Bossuet Valjean--Bossuet Gueulemer Gueulemer Valjean--Gueulemer Babet Babet Valjean--Babet Claquesous Claquesous Valjean--Claquesous Montparnasse Montparnasse Valjean--Montparnasse Toussaint Toussaint Valjean--Toussaint Marguerite--Fantine Fantine--MmeThenardier Fantine--Thenardier Fantine--Javert Fantine--Bamatabois Fantine--Simplice Tholomyes Tholomyes Fantine--Tholomyes Listolier Listolier Fantine--Listolier Fameuil Fameuil Fantine--Fameuil Blacheville Blacheville Fantine--Blacheville Favourite Favourite Fantine--Favourite Dahlia Dahlia Fantine--Dahlia Zephine Zephine Fantine--Zephine Perpetue Perpetue Fantine--Perpetue MmeThenardier--Thenardier MmeThenardier--Cosette MmeThenardier--Javert MmeThenardier--Gueulemer MmeThenardier--Babet MmeThenardier--Claquesous Eponine Eponine MmeThenardier--Eponine Anzelma Anzelma MmeThenardier--Anzelma Magnon Magnon MmeThenardier--Magnon Thenardier--Cosette Thenardier--Javert Thenardier--Gavroche Thenardier--Marius Thenardier--Gueulemer Thenardier--Babet Thenardier--Claquesous Thenardier--Montparnasse Thenardier--Eponine Thenardier--Anzelma Pontmercy Pontmercy Thenardier--Pontmercy Boulatruelle Boulatruelle Thenardier--Boulatruelle Brujon Brujon Thenardier--Brujon Cosette--Javert Cosette--Woman2 Cosette--Gillenormand Cosette--MlleGillenormand Cosette--Marius Cosette--Toussaint Cosette--Tholomyes LtGillenormand LtGillenormand Cosette--LtGillenormand Javert--Fauchelevent Javert--Bamatabois Javert--Simplice Javert--Woman1 Javert--Woman2 Javert--Gavroche Javert--Enjolras Javert--Gueulemer Javert--Babet Javert--Claquesous Javert--Montparnasse Javert--Toussaint Fauchelevent--MotherInnocent Gribier Gribier Fauchelevent--Gribier Bamatabois--Judge Bamatabois--Champmathieu Bamatabois--Brevet Bamatabois--Chenildieu Bamatabois--Cochepaille Simplice--Perpetue Judge--Champmathieu Judge--Brevet Judge--Chenildieu Judge--Cochepaille Champmathieu--Brevet Champmathieu--Chenildieu Champmathieu--Cochepaille Brevet--Chenildieu Brevet--Cochepaille Chenildieu--Cochepaille Gavroche--Marius Gavroche--Enjolras Gavroche--Bossuet Gavroche--Gueulemer Gavroche--Babet Gavroche--Montparnasse Gavroche--Brujon Mabeuf Mabeuf Gavroche--Mabeuf Courfeyrac Courfeyrac Gavroche--Courfeyrac MmeBurgon MmeBurgon Gavroche--MmeBurgon Combeferre Combeferre Gavroche--Combeferre Prouvaire Prouvaire Gavroche--Prouvaire Feuilly Feuilly Gavroche--Feuilly Bahorel Bahorel Gavroche--Bahorel Joly Joly Gavroche--Joly Grantaire Grantaire Gavroche--Grantaire Child1 Child1 Gavroche--Child1 Child2 Child2 Gavroche--Child2 MmeHucheloup MmeHucheloup Gavroche--MmeHucheloup Gillenormand--MlleGillenormand Gillenormand--Marius Gillenormand--Magnon Gillenormand--LtGillenormand BaronessT BaronessT Gillenormand--BaronessT MlleGillenormand--Marius MlleGillenormand--LtGillenormand MmePontmercy MmePontmercy MlleGillenormand--MmePontmercy MlleVaubois MlleVaubois MlleGillenormand--MlleVaubois Marius--Enjolras Marius--Bossuet Marius--Tholomyes Marius--Eponine Marius--Pontmercy Marius--LtGillenormand Marius--Mabeuf Marius--Courfeyrac Marius--Combeferre Marius--Feuilly Marius--Bahorel Marius--Joly Marius--BaronessT Enjolras--Bossuet Enjolras--Claquesous Enjolras--Mabeuf Enjolras--Courfeyrac Enjolras--Combeferre Enjolras--Prouvaire Enjolras--Feuilly Enjolras--Bahorel Enjolras--Joly Enjolras--Grantaire Enjolras--MmeHucheloup Bossuet--Mabeuf Bossuet--Courfeyrac Bossuet--Combeferre Bossuet--Prouvaire Bossuet--Feuilly Bossuet--Bahorel Bossuet--Joly Bossuet--Grantaire Bossuet--MmeHucheloup Gueulemer--Babet Gueulemer--Claquesous Gueulemer--Montparnasse Gueulemer--Eponine Gueulemer--Brujon Babet--Claquesous Babet--Montparnasse Babet--Eponine Babet--Brujon Claquesous--Montparnasse Claquesous--Eponine Claquesous--Brujon Montparnasse--Eponine Montparnasse--Brujon Tholomyes--Listolier Tholomyes--Fameuil Tholomyes--Blacheville Tholomyes--Favourite Tholomyes--Dahlia Tholomyes--Zephine Listolier--Fameuil Listolier--Blacheville Listolier--Favourite Listolier--Dahlia Listolier--Zephine Fameuil--Blacheville Fameuil--Favourite Fameuil--Dahlia Fameuil--Zephine Blacheville--Favourite Blacheville--Dahlia Blacheville--Zephine Favourite--Dahlia Favourite--Zephine Dahlia--Zephine Eponine--Anzelma Eponine--Brujon Eponine--Mabeuf Eponine--Courfeyrac Pontmercy--MmePontmercy Mabeuf--Courfeyrac Mabeuf--Combeferre Mabeuf--Feuilly Mabeuf--Bahorel Mabeuf--Joly MotherPlutarch MotherPlutarch Mabeuf--MotherPlutarch Courfeyrac--Combeferre Courfeyrac--Prouvaire Courfeyrac--Feuilly Courfeyrac--Bahorel Courfeyrac--Joly Courfeyrac--Grantaire Courfeyrac--MmeHucheloup Jondrette Jondrette Jondrette--MmeBurgon Combeferre--Prouvaire Combeferre--Feuilly Combeferre--Bahorel Combeferre--Joly Combeferre--Grantaire Prouvaire--Feuilly Prouvaire--Bahorel Prouvaire--Joly Prouvaire--Grantaire Feuilly--Bahorel Feuilly--Joly Feuilly--Grantaire Bahorel--Joly Bahorel--Grantaire Bahorel--MmeHucheloup Joly--Grantaire Joly--MmeHucheloup Grantaire--MmeHucheloup Child1--Child2