我制作了一张网络图。现在我想添加3个功能-
当悬停在一条边上时,它应突出显示与该边相连的节点
当悬停在节点上时,它应突出显示所有节点以及连接到该节点的边缘
在网络中选择一个子区域时(通过拖动鼠标),而不是放大图形,而是应突出显示该选定子区域中的节点和边
我该怎么做?我找到了this pen,但是我不知道如何针对图中的每个节点以自动化的方式将其适应Python。
这是我的代码:
import plotly.graph_objs as go
import networkx as nx
from plotly.offline import download_plotlyjs, init_notebook_mode, iplot, plot
init_notebook_mode(connected=True)
#create graph G
G = nx.karate_club_graph()
# adjust node size according to degree, etc
d = nx.degree(G)
node_sizes = []
for i in d:
_, value = i
node_sizes.append(3*value+5)
#get a x,y position for each node
pos = nx.circular_layout(G)
#add a pos attribute to each node
for node in G.nodes:
G.nodes[node]['pos'] = list(pos[node])
pos=nx.get_node_attributes(G,'pos')
dmin=1
ncenter=0
for n in pos:
x,y=pos[n]
d=(x-0.5)**2+(y-0.5)**2
if d<dmin:
ncenter=n
dmin=d
p=nx.single_source_shortest_path_length(G,ncenter)
#Create Edges
edge_trace = go.Scatter(
x=[],
y=[],
line=dict(width=0.5,color='#888'),
hoverinfo='none',
mode='lines')
edge_trace['line'] = dict(width=0.5,color='#FF0000')
for edge in G.edges():
x0, y0 = G.node[edge[0]]['pos']
x1, y1 = G.node[edge[1]]['pos']
edge_trace['x'] += tuple([x0, x1, None])
edge_trace['y'] += tuple([y0, y1, None])
node_trace = go.Scatter(
x=[],
y=[],
text=[],
mode='markers',
hoverinfo='text',
marker=dict(
showscale=True,
# colorscale options
#'Greys' | 'YlGnBu' | 'Greens' | 'YlOrRd' | 'Bluered' | 'RdBu' |
#'Reds' | 'Blues' | 'Picnic' | 'Rainbow' | 'Portland' | 'Jet' |
#'Hot' | 'Blackbody' | 'Earth' | 'Electric' | 'Viridis' |
colorscale='Viridis',
reversescale=True,
color=[],
size=node_sizes,
colorbar=dict(
thickness=15,
title='Node Connections',
xanchor='left',
titleside='right'
),
line=dict(width=2)))
for node in G.nodes():
x, y = G.node[node]['pos']
node_trace['x'] += tuple([x])
node_trace['y'] += tuple([y])
#add color to node points
for node, adjacencies in enumerate(G.adjacency()):
node_trace['marker']['color']+=tuple([len(adjacencies[1])])
node_info = 'Name: ' + str(adjacencies[0]) + '<br># of connections: '+str(len(adjacencies[1]))
node_trace['text']+=tuple([node_info])
f = go.Figure(data=[edge_trace, node_trace],
layout=go.Layout(
title='<br>Network Graph of Karate Club',
titlefont=dict(size=16),
showlegend=False,
hovermode='closest',
width=880,
height=800,
margin=dict(b=20,l=5,r=5,t=40),
annotations=[ dict(
showarrow=False,
xref="paper", yref="paper",
x=0.005, y=-0.002 ) ],
xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
yaxis=dict(showgrid=False, zeroline=False, showticklabels=False)
)
)
iplot(f)
答案 0 :(得分:0)
您可以使用bokeh库。它具有用于图形可视化的良好子模块。 Here是一些图表示例。您的问题可以通过以下代码解决:
import networkx as nx
from bokeh.io import show, output_file
from bokeh.models import Plot, Range1d, MultiLine, Circle
from bokeh.models import HoverTool, TapTool, BoxSelectTool
from bokeh.models.graphs import from_networkx
from bokeh.models.graphs import NodesAndLinkedEdges, EdgesAndLinkedNodes
from bokeh.palettes import Spectral4
G = nx.gnp_random_graph(20, 0.1)
plot = Plot(
plot_width=400,
plot_height=400,
x_range=Range1d(-1.1,1.1),
y_range=Range1d(-1.1,1.1)
)
plot.title.text = "WAKA"
plot.add_tools(
HoverTool(tooltips=None),
TapTool(),
BoxSelectTool()
)
graph_renderer = from_networkx(
G,
nx.circular_layout,
scale=1,
center=(0,0)
)
graph_renderer.node_renderer.glyph = Circle(
size=15,
fill_color=Spectral4[0]
)
graph_renderer.node_renderer.selection_glyph = Circle(
size=25,
fill_color=Spectral4[2]
)
graph_renderer.node_renderer.hover_glyph = Circle(
size=20,
fill_color=Spectral4[1]
)
graph_renderer.edge_renderer.glyph = MultiLine(
line_color="#CCCCCC",
line_alpha=0.8,
line_width=3
)
graph_renderer.edge_renderer.selection_glyph = MultiLine(
line_color=Spectral4[2],
line_width=7
)
graph_renderer.edge_renderer.hover_glyph = MultiLine(
line_color=Spectral4[1],
line_width=5
)
graph_renderer.selection_policy = NodesAndLinkedEdges()
graph_renderer.inspection_policy = EdgesAndLinkedNodes()
plot.renderers.append(graph_renderer)
output_file("waka.html")
show(plot)