【问题标题】:In a network graph, how do I highlight the network components when hovering over them?在网络图中,将鼠标悬停在网络组件上时如何突出显示它们?
【发布时间】:2019-05-17 07:30:57
【问题描述】:

我已经制作了一个网络图。现在我想添加 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)

【问题讨论】:

    标签: python plotly data-visualization networkx


    【解决方案1】:

    您可以使用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)
    

    【讨论】:

    • 是的,我确实研究了散景,因为我知道到目前为止 plotly 并没有内置的方法来做到这一点。虽然我在使用散景时获得了悬停高亮功能,但我无法弄清楚如何更改散景网络图中的节点大小。我刚刚发布了一个关于它的问题:stackoverflow.com/questions/56182861/… 如果你能帮助我,那就太好了。
    • 在那里回答:)
    猜你喜欢
    • 2013-12-11
    • 2010-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多