Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python, networkx, pyvis: How do you change the node label font size

I have been struggling with a simple question. How to change the label size for a certain type of node? My nodes are switches and their ports. I wish to have nodes that are switches to have their labels in a larger size font than the port nodes. I am using networkx and pyvis to plot my data.

I essentially want when I add nodes (lsysname, rsysname, lswname) to have a larger font size e.g. 25. I want when I add ports as nodes for the font size to be the default 12. Is this at all possible? If yes how would I alter my code below?

Here is my code:

#!/usr/bin/env python3
import pandas as pd
from pyvis.network import Network
import networkx as nx
import re

nt = nx.Graph()
nt = Network(height='750px', bgcolor='#222222')

# set the physics layout of the network
nt.barnes_hut(gravity=-80000, central_gravity=0.3, spring_length=10, spring_strength=0.002, damping=0.09, overlap=0)

got_dataLLDP = pd.read_csv('switchLLDPgraph.csv', sep='|')
got_dataPortDescr = pd.read_csv('switchPortDescr.csv', sep='|')

#lsystemname and rsystemname are SWITCHES
#lportnode and rportnode are PORTS
lsystemname = got_dataLLDP['Local SystemName']
lsystemdescr = got_dataLLDP['Local SystemDescr']
lportnode = got_dataLLDP['Local PortNode']
lportlabel = got_dataLLDP['Local PortLabel']

rsystemname = got_dataLLDP['Remote SystemName']
rsystemdescr = got_dataLLDP['Remote SystemDescr']
rportnode = got_dataLLDP['Remote PortNode']
rportlabel = got_dataLLDP['Remote PortLabel']

#lswitchname are SWITCHES
#lswitchport are PORTS
lswitchname = got_dataPortDescr['SW Name']
lswitchport = got_dataPortDescr['Local PortNode']
lswitchportstate = got_dataPortDescr['PORT STATE']

edge_dataLLDP = zip(lsystemname, lsystemdescr, lportnode, lportlabel, rsystemname, rsystemdescr, rportnode, rportlabel)
edge_dataPortDescr = zip(lswitchname, lswitchport, lswitchportstate)

for e in edge_dataLLDP:
    lsysname = e[0]
    lpnode = e[2]
    lplabel = e[3]
    rsysname = e[4]
    rpnode = e[6]
    rplabel = e[7]

    nt.add_node(lsysname, lsysname, size=100, shape='triangle', color='#1abc9c')
    nt.add_node(lpnode, lplabel, size=25, color='#DFFF00')
    nt.add_node(rsysname, rsysname, size=100, shape='triangle', color='#1abc9c')
    nt.add_node(rpnode, rplabel, size=25, color='#DFFF00')
    nt.add_edge(lsysname, lpnode, value=0.05, color='#DFFF00')
    nt.add_edge(lpnode, rpnode, value=0.03, color='#FFFFCC')
    nt.add_edge(rsysname, rpnode, value=0.05, color='#DFFF00')

for f in edge_dataPortDescr:
    lswname = f[0]
    lswport = f[1]
    lswportstate = f[2]
    
    pattern = '\!Description'
    result = re.search(pattern, lswport)
    
    nt.add_node(lswname, lswname, size=100, shape='triangle', color='#1abc9c')
    if lswportstate == 'Up': 
        if result:
            nt.add_node(lswport, lswport, size=25, color='#EA580C')
            nt.add_edge(lswname, lswport, value=0.035, color='#EA580C')
        else:
            nt.add_node(lswport, lswport, size=25, color='#00FF00')
            nt.add_edge(lswname, lswport, value=0.035, color='#00FF00')
    if lswportstate == 'Down':
        if result:
            nt.add_node(lswport, lswport, size=25, color='#EA580C')
            nt.add_edge(lswname, lswport, value=0.035, color='#FF0000')
        else:
            nt.add_node(lswport, lswport, size=25, color='#FF0000')
            nt.add_edge(lswname, lswport, value=0.035, color='#FF0000')

nt.show_buttons()
nt.show('nx.html')
like image 659
counter_struck Avatar asked Sep 14 '25 19:09

counter_struck


2 Answers

Well, the documentation does not mention this, but I found the given invocation:

g = Network(width=1900, height=1000)
g.from_nx(your_network_graph)
for n in g.nodes:
    n["size"] = 100
    n["font"]={"size": 100}
g.barnes_hut()
g.toggle_physics(True)
g.write_html("viz.html")

Similarly, you can change the size of edge labels:

for e in g.edges:
    if "label" in e:
        e["font"]={"size": 100}
like image 142
etham Avatar answered Sep 17 '25 09:09

etham


The code in the question is rather elaborate, so the following snippet uses a simpler setup. The key idea is to generate fixed positions for the nodes (and labels), and then subset these positions based on some condition into separate positions for small and large fonts.

import networkx as nx

G = nx.Graph()
G.add_edge(1, 2)
G.add_edge(1, 3)
G.add_edge(1, 5)
G.add_edge(2, 3)

# generate layout
pos = nx.spring_layout(G)

# generate positions for labels
nodes_small_font = [1, 5]
pos_small = {k: v for k, v in pos.items() if k in nodes_small_font}

nodes_large_font = [2, 3]
pos_large = {k: v for k, v in pos.items() if k in nodes_large_font}

nx.draw(G, pos)
nx.draw_networkx_labels(G.subgraph(nodes_small_font), pos_small, font_size=35)
nx.draw_networkx_labels(G.subgraph(nodes_large_font), pos_large, font_size=75)
like image 34
SultanOrazbayev Avatar answered Sep 17 '25 09:09

SultanOrazbayev