import warnings
from pprint import pprint
import matplotlib.pyplot as plt
import networkx as nx
import seaborn as sns
from graphrole import RecursiveFeatureExtractor, RoleExtractor
# load the well known karate_club_graph from Networkx
G = nx.karate_club_graph()
# extract features
feature_extractor = RecursiveFeatureExtractor(G)
features = feature_extractor.extract_features()
print(f'\nFeatures extracted from {feature_extractor.generation_count} recursive generations:')
print(features)
Features extracted from 3 recursive generations: external_edges(mean)(mean) degree(mean) degree(sum) \ 0 19.637500 4.312500 69.0 1 22.422685 5.777778 52.0 2 25.537083 6.600000 66.0 3 23.717361 7.666667 46.0 4 17.979167 7.666667 23.0 5 17.234375 6.250000 25.0 6 17.234375 6.250000 25.0 7 26.342708 10.250000 41.0 8 27.214363 11.800000 59.0 9 28.108824 13.500000 27.0 10 17.979167 7.666667 23.0 11 24.937500 16.000000 16.0 12 25.302083 11.000000 22.0 13 26.897696 11.600000 58.0 14 29.017157 14.500000 29.0 15 29.017157 14.500000 29.0 16 13.000000 4.000000 8.0 17 26.302083 12.500000 25.0 18 29.017157 14.500000 29.0 19 27.240605 14.000000 42.0 20 29.017157 14.500000 29.0 21 26.302083 12.500000 25.0 22 29.017157 14.500000 29.0 23 25.340196 8.000000 40.0 24 21.527778 4.333333 13.0 25 21.477778 4.666667 14.0 26 25.183824 10.500000 21.0 27 25.871078 8.750000 35.0 28 24.461438 11.000000 33.0 29 24.908578 9.000000 36.0 30 27.675245 10.750000 43.0 31 27.773080 9.000000 54.0 32 22.394526 5.083333 61.0 33 22.418627 3.823529 65.0 external_edges(mean) degree external_edges internal_edges 0 24.937500 16 17 34 1 27.666667 9 19 21 2 27.100000 10 34 21 3 25.666667 6 20 16 4 16.000000 3 16 5 5 13.000000 4 15 7 6 13.000000 4 15 7 7 22.500000 4 25 10 8 25.000000 5 44 10 9 26.000000 2 25 2 10 16.000000 3 16 5 11 17.000000 1 15 1 12 18.500000 2 18 3 13 21.600000 5 41 11 14 20.500000 2 25 3 15 20.500000 2 25 3 16 15.000000 2 4 3 17 18.000000 2 21 3 18 20.500000 2 25 3 19 18.000000 3 37 4 20 20.500000 2 25 3 21 18.000000 2 21 3 22 20.500000 2 25 3 23 20.600000 5 27 9 24 26.666667 3 8 4 25 25.666667 3 9 4 26 21.000000 2 17 3 27 21.750000 4 29 5 28 31.333333 3 28 4 29 21.250000 4 24 8 30 26.000000 4 33 7 31 17.166667 6 42 9 32 28.916667 12 23 25 33 29.117647 17 18 32
# assign node roles
role_extractor = RoleExtractor(n_roles=None)
role_extractor.extract_role_factors(features)
node_roles = role_extractor.roles
print('\nNode role assignments:')
pprint(node_roles)
print('\nNode role membership by percentage:')
print(role_extractor.role_percentage.round(2))
Node role assignments: {0: 'role_3', 1: 'role_6', 2: 'role_6', 3: 'role_6', 4: 'role_1', 5: 'role_0', 6: 'role_0', 7: 'role_1', 8: 'role_2', 9: 'role_1', 10: 'role_1', 11: 'role_1', 12: 'role_1', 13: 'role_2', 14: 'role_1', 15: 'role_1', 16: 'role_4', 17: 'role_1', 18: 'role_1', 19: 'role_1', 20: 'role_1', 21: 'role_1', 22: 'role_1', 23: 'role_2', 24: 'role_4', 25: 'role_4', 26: 'role_1', 27: 'role_2', 28: 'role_1', 29: 'role_1', 30: 'role_1', 31: 'role_2', 32: 'role_6', 33: 'role_3'} Node role membership by percentage: role_0 role_1 role_2 role_3 role_4 role_5 role_6 0 0.10 0.02 0.02 0.42 0.02 0.02 0.42 1 0.12 0.02 0.02 0.02 0.02 0.28 0.52 2 0.09 0.02 0.22 0.02 0.02 0.22 0.41 3 0.12 0.02 0.02 0.02 0.02 0.28 0.52 4 0.17 0.40 0.03 0.17 0.03 0.03 0.17 5 0.27 0.27 0.05 0.27 0.05 0.05 0.05 6 0.27 0.27 0.05 0.27 0.05 0.05 0.05 7 0.12 0.29 0.02 0.12 0.02 0.29 0.12 8 0.02 0.02 0.47 0.02 0.11 0.11 0.25 9 0.17 0.40 0.03 0.03 0.03 0.17 0.17 10 0.17 0.40 0.03 0.17 0.03 0.03 0.17 11 0.04 0.55 0.04 0.04 0.04 0.24 0.04 12 0.03 0.42 0.03 0.03 0.03 0.42 0.03 13 0.02 0.02 0.45 0.02 0.02 0.24 0.24 14 0.03 0.42 0.03 0.03 0.03 0.42 0.03 15 0.03 0.42 0.03 0.03 0.03 0.42 0.03 16 0.06 0.06 0.06 0.06 0.34 0.06 0.34 17 0.03 0.42 0.03 0.03 0.03 0.42 0.03 18 0.03 0.42 0.03 0.03 0.03 0.42 0.03 19 0.03 0.32 0.32 0.14 0.03 0.14 0.03 20 0.03 0.42 0.03 0.03 0.03 0.42 0.03 21 0.03 0.42 0.03 0.03 0.03 0.42 0.03 22 0.03 0.42 0.03 0.03 0.03 0.42 0.03 23 0.02 0.11 0.25 0.02 0.11 0.25 0.25 24 0.04 0.20 0.04 0.04 0.46 0.04 0.20 25 0.04 0.20 0.04 0.04 0.46 0.04 0.20 26 0.03 0.40 0.03 0.03 0.17 0.17 0.17 27 0.15 0.15 0.35 0.03 0.15 0.03 0.15 28 0.14 0.32 0.14 0.03 0.03 0.03 0.32 29 0.14 0.32 0.03 0.03 0.03 0.32 0.14 30 0.02 0.27 0.27 0.02 0.02 0.12 0.27 31 0.11 0.02 0.47 0.02 0.25 0.02 0.11 32 0.28 0.02 0.02 0.12 0.02 0.02 0.52 33 0.10 0.02 0.02 0.42 0.02 0.02 0.42
# build color palette for plotting
unique_roles = sorted(set(node_roles.values()))
color_map = sns.color_palette('Paired', n_colors=len(unique_roles))
# map roles to colors
role_colors = {role: color_map[i] for i, role in enumerate(unique_roles)}
# build list of colors for all nodes in G
node_colors = [role_colors[node_roles[node]] for node in G.nodes]
# plot graph
plt.figure()
with warnings.catch_warnings():
# catch matplotlib deprecation warning
warnings.simplefilter('ignore')
nx.draw(
G,
pos=nx.spring_layout(G, seed=42),
with_labels=True,
node_color=node_colors,
)
plt.show()