Bokeh为Networkx图形添加边标签/边属性

2024-09-30 14:26:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图使用bokeh可视化网络图。我可以添加更多信息和功能,例如:

  • 按度调整节点大小和着色
  • 按模块化类调整节点大小和着色
  • 将鼠标悬停在节点和边上时添加响应高亮显示
  • 添加节点标签

我无法在图形中添加边缘标签/属性

这是我的网络

# #!pip install bokeh
import networkx
import seaborn as sns

from bokeh.io import output_notebook, show, save
from bokeh.models import Range1d, Circle, ColumnDataSource, MultiLine, EdgesAndLinkedNodes, NodesAndLinkedEdges, LabelSet
from bokeh.models import GraphRenderer, StaticLayoutProvider, LinearColorMapper
from bokeh.plotting import figure
from bokeh.plotting import from_networkx
from bokeh.palettes import Blues8, Reds8, Purples8, Oranges8, Viridis8, Spectral8
from bokeh.transform import linear_cmap
from networkx.algorithms import community
import networkx as nx

节点数据

G.nodes(data=True)
NodeDataView({1405394338: {}, 1354581834: {}, 1334448011: {}, 1367797753: {}, 1244950426: {}})

边缘数据

G.edges(data=True)
EdgeDataView([(1405394338, 1367797753, {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM', 'Phone': 5392353776, 'VIN': '1C3CDZBG9DN5907'}), (1405394338, 1334448011, {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM', 'Phone': 5392353776}), (1405394338, 1244950426, {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM'}), (1405394338, 1354581834, {'Phone': 5392353776}), (1354581834, 1367797753, {'Phone': 5392353776}), (1354581834, 1334448011, {'Phone': 5392353776}), (1334448011, 1367797753, {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM', 'Phone': 5392353776}), (1334448011, 1244950426, {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM'}), (1367797753, 1244950426, {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM'})])

我试图将这些边属性添加到交互式bokeh图中

edge_labels = list(G.edges(data=True))

d = {x[:2]: x[2:][0] for x in edge_labels}

d

bokeh交互式图形网络的完整工作示例

# Calculate degree for each node and add as node attribute
degrees = dict(networkx.degree(G))
networkx.set_node_attributes(G, name='degree', values=degrees)

# Slightly adjust degree so that the nodes with very small degrees are still visible
number_to_adjust_by = 5
adjusted_node_size = dict([(node, degree+number_to_adjust_by) for node, degree in networkx.degree(G)])
networkx.set_node_attributes(G, name='adjusted_node_size', values=adjusted_node_size)

# Calculate communities
communities = community.greedy_modularity_communities(G)

#Choose colors for node and edge highlighting
node_highlight_color = 'orange'
edge_highlight_color = 'black'

#Choose attributes from G network to size and color by — setting manual size (e.g. 10) or color (e.g. 'skyblue') also allowed
size_by_this_attribute = 'adjusted_node_size'
# color_by_this_attribute = 'modularity_color'

#Pick a color palette — Blues8, Reds8, Purples8, Oranges8, Viridis8
color_palette = Viridis8

#Choose a title!
title = 'Network Analysis'

#Establish which categories will appear when hovering over each node
HOVER_TOOLTIPS = [
       ("Node", "@index"),
        ("Degree", "@degree"),
        #  ("Modularity Class", "@modularity_class"),
        # ("Modularity Color", "$color[swatch]:modularity_color"),
]

#Create a plot — set dimensions, toolbar, and title
plot = figure(tooltips = HOVER_TOOLTIPS,
              tools="pan,wheel_zoom,save,reset", active_scroll='wheel_zoom', plot_width=800, plot_height=1000,
            x_range=Range1d(-10.1, 10.1), y_range=Range1d(-10.1, 10.1), title=title)

#Create a network graph object
# https://networkx.github.io/documentation/networkx-1.9/reference/generated/networkx.drawing.layout.spring_layout.html
network_graph = from_networkx(G, networkx.spring_layout, scale=10, center=(0, 0))

#Set node sizes and colors according to node degree (color as category from attribute)
network_graph.node_renderer.glyph = Circle(size=size_by_this_attribute) #, fill_color=color_by_this_attribute)
#Set node highlight colors
network_graph.node_renderer.hover_glyph = Circle(size=size_by_this_attribute, fill_color=node_highlight_color, line_width=2)
network_graph.node_renderer.selection_glyph = Circle(size=size_by_this_attribute, fill_color=node_highlight_color, line_width=2)

#Set edge opacity and width
network_graph.edge_renderer.glyph = MultiLine(line_alpha=0.3, line_width=1)
#Set edge highlight colors
network_graph.edge_renderer.selection_glyph = MultiLine(line_color=edge_highlight_color, line_width=2)
network_graph.edge_renderer.hover_glyph = MultiLine(line_color=edge_highlight_color, line_width=2)

#Highlight nodes and edges
network_graph.selection_policy = NodesAndLinkedEdges()
network_graph.inspection_policy = NodesAndLinkedEdges()

plot.renderers.append(network_graph)

#Add Labels
x, y = zip(*network_graph.layout_provider.graph_layout.values())
node_labels = list(G.nodes())
source = ColumnDataSource({'x': x, 'y': y, 'name': [node_labels[i] for i in range(len(x))]})
labels = LabelSet(x='x', y='y', text='name', source=source, background_fill_color='white', text_font_size='10px', background_fill_alpha=.7)
plot.renderers.append(labels)

show(plot)
# save(plot, filename=f"{title}.html")

我正在尝试将这些标签属性添加到图形中

{(1334448011, 1244950426): {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM'},
 (1334448011, 1367797753): {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM',
                            'Phone': 5392353776},
 (1354581834, 1334448011): {'Phone': 5392353776},
 (1354581834, 1367797753): {'Phone': 5392353776},
 (1367797753, 1244950426): {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM'},
 (1405394338, 1244950426): {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM'},
 (1405394338, 1334448011): {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM',
                            'Phone': 5392353776},
 (1405394338, 1354581834): {'Phone': 5392353776},
 (1405394338, 1367797753): {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM',
                            'Phone': 5392353776,
                            'VIN': '1C3CDZBG9DN5907'}}

如何将边缘标签添加到交互式图形中


Tags: fromimportnetworkxcomnodesizeemailbokeh