Skip to main content

Visualize networkx graphs interactively in a web browser.

Project description

Schnauzer - NetworkX Graph Visualization

Schnauzer is a Python library that visualizes NetworkX graphs in a web browser with an interactive interface.

Running the Server

From command line: Make sure that the currently active Python environment has the schnauzer package installed. Optionally set --port --backend-port .

pip install schnauzer
schnauzer-server 

Or from Python:

from schnauzer import Server
server = Server()
# server = Server(web_port=8080, backend_port=8086) # optional
server.start()

Modifying Node/Edge Data

To really make use of this visualisation tool you should add some information to your graph. On boring pdf-plots you might not be able to add all the information you want but with this interactive solution you definitely can. So take your graph and add some attributes.

import networkx as nx

# Create a graph or use an existing one
G = nx.Graph()

# Option 1: Add attributes on the fly when creating nodes and edges
G.add_node(1, name="Start Node", type="input", description="This is the start")
G.add_node(2, name="Process Node", type="process")
G.add_node(3, name="End Node", type="output")
G.add_edge(1, 2, name="Connection 1-2", weight=5)
G.add_edge(2, 3, name="Connection 2-3", weight=3)

# Option 2: Add or modify attributes of existing nodes and edges
G.nodes[1]['priority'] = 'high'
G.edges[2, 3]['weight'] = 10

# Option 3: Set multiple attributes at once
nx.set_node_attributes(G, {1: "critical", 2: "normal", 3: "low"}, "type")
nx.set_edge_attributes(G, {(1, 2): "data", (2, 3): "control"}, "type")

# Option 4: use an Iterator
for node, data in G.nodes(data=True): # need data=True to get the attributes as well!
    data['type'] = "critical"

for u, v, data in G.edges(data=True):
    data['type'] = "data"

Displaying the Graph

Now that you have your very cool graph we can display it. Make sure that the server is already running when you send your graph.

from schnauzer import VisualizationClient
import networkx as nx

G = nx.Graph()
client = VisualizationClient(host='localhost', port=8086)

# If not connected, connect and send the graph
client.send_graph(
    graph=G,
    title="Your super cool graph",
)

# We can use this function multiple times to update the graph in real time.
client.send_graph(G, title="Updated Network")

# Disconnect when done
client.disconnect()

Note that the connection is not closed until you close it manually.

Coloring, Types and Labels:

Colors and types:

To color nodes and edges you can assign your nodes and edges a type attribute.

import networkx as nx
G = nx.Graph()

nx.set_node_attributes(G, {1: "critical", 2: "normal", 3: "low"}, "type")
nx.set_edge_attributes(G, {(1, 2): "data", (2, 3): "control"}, "type")

Here we assigned the type critical, normal and low for some nodes and data and control for some edges. We can now assign colors to these types by creating a type_color_map dictionary.

type_color_map = {
    # Node type colors
    "critical": "#FF5733",    # Orange-red 
    "normal": "#33A8FF",  # Blue
    "low": "#33FF57",   # Green
    
    # Edge type colors
    "data": "#777777",     # Dark gray
    "control": "#AA33AA",  # Purple
}

The visualization server will color the nodes and edges according to their assigned type and the colors defined in the type_color_map.

Labels:

You add arbitrary attributes to nodes and edges of your Graph. All attributes are displayed by default. There are some special names though:

  • Add a name Attribute to assign your nodes and edges a name. You want name to be unique!

    • IMPORTANT: when putting a name attribute the node has from then on be referenced by that name. Working on this issue.
  • Add a type Attribute to assign your nodes and edges a type. This is used to color the nodes and edges.

  • Add a description Attribute to assign your nodes and edges a description that will be displayed on a little tooltip when you hover over nodes and edges. I'd recommend to keep this short though.

Filtering Labels:

If some other library creates the graph you want to visualize, you might have more attributes than you are interested in. Resulting in a bloated UI with too much information. Use the optional node_labels and edge_labels lists to filter for attributes that are displayed in the UI.

Examples:

Note: The examples assume the Visualization Server is already running in a separate Process. Find all examples also in examples/

import networkx as nx
from schnauzer import VisualizationClient

G = nx.DiGraph()

nodes = [ 'A', 'B', 'C', 'D', 'E']
edges = [ ('A', 'B'), ('A', 'C'), ('B', 'D'), ('C', 'D'), ('D', 'E') ]

G.add_nodes_from(nodes)
G.add_edges_from(edges)

viz_client = VisualizationClient()
viz_client.send_graph(G, 'Simple Graph')

simple

import networkx as nx
from schnauzer import VisualizationClient

G = nx.DiGraph()

nodes = [
    ('Entry', {'description': 'Here the program starts'}),
    ('Condition', {'description': 'Take red if you are brave'}),
    ('If Block', {'description': 'good choice'}),
    ('Red Pill', {'description': 'very nice'}),
    ('Else Block', {'description': 'bad choice'}),
    ('Blue Pill', {'description': 'not cool'}),
    ('Exit', {'description': 'Goodbye'})
]

edges = [
    ('Entry', 'Condition', {'description': 'Edges can also have attributes'}),
    ('Condition', 'If Block', {'description': 'Add any attribute you want'}),
    ('Condition', 'Else Block', {'description': 'Some attributes'}),
    ('If Block', 'Red Pill', {'description': 'They will all appear in the details panel'}),
    ('Else Block', 'Blue Pill', {'description': "like 'description', 'name' or 'type'"}),
    ('Red Pill', 'Exit', {'description': 'but are hidden in the graph for clarity'}),
    ('Blue Pill', 'Exit', {'description': 'have special rendering'}),
]

G.add_nodes_from(nodes)
G.add_edges_from(edges)

viz_client = VisualizationClient()
viz_client.send_graph(G, 'Graph with Custom Attributes')

simple

import networkx as nx
from schnauzer import VisualizationClient

G = nx.DiGraph()

type_color_map = {
    'standard': '#FFD700',
    'Blue Path': '#0000FF',
    'Red Path': '#FF0000',
}

nodes = [
    ('Entry', {
        'description': 'Here the program starts',
        'type': 'standard'
    }),
    ('Condition', {
        'description': 'Take red if you are brave',
        'type': 'standard'
    }),
    ('If Block', {
        'description': 'good choice',
        'type': 'Red Path'
    }),
    ('Red Pill', {
        'description': 'very nice',
        'type': 'Red Path'
    }),
    ('Else Block', {
        'description': 'bad choice',
        'type': 'Blue Path'
    }),
    ('Blue Pill', {
        'description': 'not cool',
        'type': 'Blue Path'
    }),
    ('Exit', {
        'description': 'Goodbye',
        'type': 'standard'
    })
]

edges = [
    ('Entry', 'Condition', {
        'description': 'Edges can also have attributes'
    }),
    ('Condition', 'If Block', {
        'description': 'Add any attribute you want',
        'type': 'Red Path'
    }),
    ('Condition', 'Else Block', {
        'description': 'Some attributes',
        'type': 'Blue Path'
    }),
    ('If Block', 'Red Pill', {
        'description': 'They will all appear in the details panel',
        'type': 'Red Path'
    }),
    ('Else Block', 'Blue Pill', {
        'description': "like 'description', 'name' or 'type'",
        'type': 'Blue Path'
    }),
    ('Red Pill', 'Exit', {
        'description': 'but are hidden in the graph for clarity',
        'type': 'Red Path'
    }),
    ('Blue Pill', 'Exit', {
        'description': 'have special rendering',
        'type': 'Blue Path'
    }),
]

G.add_nodes_from(nodes)
G.add_edges_from(edges)

viz_client = VisualizationClient()
viz_client.send_graph(G, 'Custom Coloring!', type_color_map=type_color_map)

simple

import networkx as nx
from schnauzer import VisualizationClient

G = nx.MultiDiGraph()

nodes = [ 'A', 'B', 'C', 'D', 'E']
edges = [ ('A', 'B', 0), ('A', 'B', 1), ('A', 'C', 0), ('B', 'D', 0), ('C', 'D', 0),('C', 'D', 1),('C', 'D', 2), ('D', 'E', 0),('D', 'E', 1),('D', 'E', 2),('D', 'E', 3),('A', 'D', 0),('E', 'C', 0)]

G.add_nodes_from(nodes)
G.add_edges_from(edges)

viz_client = VisualizationClient()
viz_client.send_graph(G, 'Multi Graph')

simple

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

schnauzer-0.2.2.tar.gz (479.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

schnauzer-0.2.2-py3-none-any.whl (478.5 kB view details)

Uploaded Python 3

File details

Details for the file schnauzer-0.2.2.tar.gz.

File metadata

  • Download URL: schnauzer-0.2.2.tar.gz
  • Upload date:
  • Size: 479.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for schnauzer-0.2.2.tar.gz
Algorithm Hash digest
SHA256 11d682ec28f6f9aa8492cee35cd74c16f5d86e356af808a37b51ceb6f25137a4
MD5 58de29fed42dc10c708e716e593011b0
BLAKE2b-256 3297be4b7d68200d577339253137477212cd8b48fe732758c025badb730c76b7

See more details on using hashes here.

Provenance

The following attestation bundles were made for schnauzer-0.2.2.tar.gz:

Publisher: publish.yml on Nifalu/schnauzer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file schnauzer-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: schnauzer-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 478.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for schnauzer-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 ac9717d2ede7a693f9655f54f041edc531d8e0d5a106aee6ec6bc57375000827
MD5 04206a1f5086e55f5fa77da6096f45a9
BLAKE2b-256 03c25740992fb29abd5c3bf688c836eb68efa22c13235090a72ac449d682b1ed

See more details on using hashes here.

Provenance

The following attestation bundles were made for schnauzer-0.2.2-py3-none-any.whl:

Publisher: publish.yml on Nifalu/schnauzer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page