Skip to content

Instantly share code, notes, and snippets.

@colincowie
Created March 16, 2025 20:27
Show Gist options
  • Select an option

  • Save colincowie/3d877f05340eff6c8f8931528e262673 to your computer and use it in GitHub Desktop.

Select an option

Save colincowie/3d877f05340eff6c8f8931528e262673 to your computer and use it in GitHub Desktop.
CSV to PyVis Network using FontAwesome Icons
import pandas as pd
from pyvis.network import Network
# Read the CSV file
csv_file = "demo.csv" # Replace with your actual file path
data = pd.read_csv(csv_file)
# Ensure 'from' and 'to' columns are strings and handle missing values
data['from'] = data['from'].fillna('').astype(str).str.strip()
data['to'] = data['to'].fillna('').astype(str).str.strip()
# Initialize the PyVis network
graph = Network(height='750px', width='100%', bgcolor='#222222', font_color='white')
# Pre-process nodes to collect icon and color information
node_icons = {}
for index, row in data.iterrows():
from_node = row['from']
# Skip empty nodes
if not from_node:
continue
from_icon = row.get('from_icon', None)
from_color = row.get('from_color', "#F5A623") # Default color if not set
# Process FontAwesome icons
if pd.notna(from_icon) and from_icon.startswith("\\u"):
try:
unicode_icon = chr(int(from_icon.replace("\\u", "0x"), 16))
node_icons[from_node] = {"icon": {"face": "FontAwesome", "code": unicode_icon, "color": from_color}}
except ValueError:
node_icons[from_node] = {"icon": None}
else:
node_icons[from_node] = {"icon": None}
# Collect all unique non-empty nodes
all_nodes = set(data['from']).union(set(data['to'])) - {''} # Remove empty strings
# Add nodes to the graph
for node in all_nodes:
if node in node_icons:
icon_settings = node_icons[node]['icon']
graph.add_node(node, label=node, title=node, shape='icon' if icon_settings else 'dot', icon=icon_settings)
else:
graph.add_node(node, label=node, title=node, shape='dot')
# Iterate through the DataFrame and add edges (ignore empty and self-looping edges)
for index, row in data.iterrows():
if row['from'] and row['to'] and row['from'] != row['to']: # Avoid self-loops
graph.add_edge(row['from'], row['to'])
# Customize the visualization
graph.force_atlas_2based()
# Save and modify the HTML file
html_file = "graph.html"
graph.write_html(html_file)
# Inject FontAwesome library into the HTML
with open(html_file, "r", encoding="utf-8") as f:
html_content = f.read()
fontawesome_link = '<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">'
html_content = html_content.replace("</head>", f"{fontawesome_link}</head>")
with open(html_file, "w", encoding="utf-8") as f:
f.write(html_content)
print(f"Report saved to {html_file}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment