#018 Diagram Sieci (Network Graph)

network graph / diagram sieci

Diagram sieci nazywany jest także mapą sieci (ang. Network Map) lub diagramem łączenia węzłów (ang. Node-Link Diagram). Diagram sieci jest wizualizacją, która pokazuje jak dane zbiory jednostek (np. osoby, przedmioty, transakcje, akcje itp.) są ze sobą połączone tworząc graficzny obraz sieci.

Elementy na wykresie sieci są wyświetlane jako węzły (ang. nodes), a relacje między nimi są reprezentowane jako linie zwane krawędziami (ang. edges). Węzły mogą mieć różne kolory i rozmiary. Zazwyczaj węzły są rysowane jako małe kropki lub kółka, ale można również używać ikon. Z kolei krawędzie mogą mieć różne kolory i grubości.

Diagram sieci można wykorzystać do interpretacji struktury sieci poprzez wyszukiwanie klastrów węzłów, gęstości połączeń węzłów lub sposobu rozmieszczenia układu diagramu. Mogą być również optymalne dla różnych przypadków użycia, takich jak wizualizacja relacji między ludźmi, firmami, miastami i tak dalej. Piszę w tym momencie o nich, bo sam je niedawno wykorzystałem to zaprezentowania, w jaki sposób klient porusza się po stronie internetowej. Dzięki diagramowi łatwo było zauważyć anomalie, czy zapętlenia (ciekawe info dla UXowców!).

Można wyszczególnić dwa rodzaje diagramu sieciowego: „nieskierowane” i „skierowane”. Nieskierowany diagram sieci wyświetla tylko połączenia między podmiotami, podczas gdy kierowany diagram sieci pokazuje, czy połączenia są jednokierunkowe, czy dwukierunkowe za pomocą małych strzałek.

Diagram sieci staje się trudny do odczytania, gdy jest zbyt wiele węzłów i połączeń i nie ma przy tym wyraźnego wzorca! Wówczas wizualizacja staje się bardzo nieczytelna. To zagrożenie określa się mianem „Hairball„.

Jak narysować diagram sieci w Python?

Na szczęście jest na ratunek przychodzi nam biblioteka networkx, która bardzo ułatwia rysowanie grafów w python. Wczytajmy najpierw potrzebne pakiety:

import pandas as pd

import matplotlib.pyplot as plt
import matplotlib

import networkx as nx

nx.__version__

Teraz zainicjujmy stworzenie naszego pierwszego grafu. Twórzmy najpierw 5 różnych wierzchołków. Następnie po prostu narysujmy je korzystając z funkcji nx.draw:

G = nx.Graph()

G.add_node(1)
G.add_node(2)
G.add_node(3)
G.add_node('A')
G.add_node('B')

print(G.nodes())

nx.draw(G)
diagram sieci przykład (networh graph example)

Możemy jeszcze podpisać wierzchołki, by było łatwiej nam zobaczyć, gdzie który jest:

nx.draw(G, with_labels=1)

Teraz możemy zdefiniować ręcznie kilka przykładowych krawędzi między wierzchołkami.

G.add_edge(1, 2)
G.add_edge(2, 3)
G.add_edge(3, 1)
G.add_edge(3, 'A')
G.add_edge('A', 'B')

print(G.edges())

nx.draw(G, with_labels=1)
diagram sieci przykład (networh graph example)

Jak możecie zauważyć ten przykład został dokładnie z wszystkimi zależnościami przeniesiony na wykres. Pobawmy się jeszcze kolorami, by dodać troszkę „polotu” do naszej wizualizacji.

# Specify colors
cmap = matplotlib.colors.ListedColormap(['pink','darkorange','lightgreen'])
node_colors = [1,1,2,3,3]
nx.draw(G, with_labels=1, 
        node_color=node_colors, cmap=cmap)
diagram sieci przykład (networh graph example)

Warto byście pamiętali, że również możecie dowolnie sterować wielkością węzłów czy grubościom krawędzi, by dodać dodatkowe informacje do wykresu.

f = plt.figure(figsize=(15,6))

node_sizes = [2000 if col in ['A','B'] else col*500 for col in list(G.nodes)]

nx.draw(G, with_labels=1, 
        node_color=node_colors, cmap=cmap,
        node_size=node_sizes)
diagram sieci przykład (networh graph example)

Pamiętajcie, że biblioteka networkX daje nam naprawdę dużą swobodę. Można dodać dodatkowo strzałki na wykresie, by wskazać kierunek połączenia. Można również dodać informację opisową dla krawędzi, czy je również pokolorować. W razie wątpliwości zachęcam do przeglądnięcia galerii w celu inspiracji!

f = plt.figure(figsize=(15,6))

G = nx.DiGraph()

G.add_edges_from([(1, 2),(3,'A')], weight=1)
G.add_edges_from([(2, 3),('A','B')], weight=2)
G.add_edges_from([(3, 1)], weight=3)

edge_labels=dict([((u,v,),d['weight'])
                 for u,v,d in G.edges(data=True)])

red_edges = [(3,'A')]
edge_colors = ['black' if not edge in red_edges 
                       else 'red' for edge in G.edges()]

pos=nx.spring_layout(G)
nx.draw_networkx_edge_labels(G,pos,edge_labels=edge_labels)
nx.draw(G, pos, with_labels=1,
        node_size=node_sizes, node_color=node_colors, cmap=cmap,
        edge_color=edge_colors,edge_cmap=plt.cm.Reds)

diagram sieci przykład (networh graph example)

Podczas ryzowania Waszych grafów popatrzcie proszę na różne sposoby wizualizacji i wybierzcie ten, który najwięcej mówi o Waszych danych!

f = plt.figure(figsize=(15,15))
f.tight_layout()

# Subplot 1
plt.subplot(2, 2, 1)
nx.draw(G, with_labels=1,
        node_size=node_sizes, node_color=node_colors, cmap=cmap,
        edge_color=edge_colors,edge_cmap=plt.cm.Reds)
plt.title('Spring Layout (Default)', fontsize=18)

# Subplot 2
plt.subplot(2, 2, 2)
nx.draw_random(G, with_labels=1,
        node_size=node_sizes, node_color=node_colors, cmap=cmap,
        edge_color=edge_colors,edge_cmap=plt.cm.Reds)
plt.title('Random Layout', fontsize=18)

# Subplot 3
plt.subplot(2, 2, 3)
nx.draw_shell(G, with_labels=1,
        node_size=node_sizes, node_color=node_colors, cmap=cmap,
        edge_color=edge_colors,edge_cmap=plt.cm.Reds)
plt.title('Shell Layout', fontsize=18)

# Subplot 4
plt.subplot(2, 2, 4)
nx.draw_spectral(G, with_labels=1,
        node_size=node_sizes, node_color=node_colors, cmap=cmap,
        edge_color=edge_colors,edge_cmap=plt.cm.Reds)
plt.title('Spectral Layout', fontsize=18)
diagram sieci przykład (networh graph example)

Zawsze możecie poinspirować się galerią z dokumentacji:

Udanego rysowania!

Pozdrawiam serdecznie z całego serducha,

podpis Mirek

.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *