可视化图形节点中的时间序列数据 [英] Visualizing time series data of graph nodes in plotly

查看:84
本文介绍了可视化图形节点中的时间序列数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Networkx中创建了一个图形,并使用plotly进行了绘制

代码:

 将numpy导入为np将熊猫作为pd导入将networkx导入为nx导入matplotlib.pyplot作为plt随地导入plotly.graph_objects从pprint导入pprint从集合中导入OrderedDictdef get_edge_trace(G):edge_x = []edge_y = []对于G.edges()中的edge:x0,y0 = G.nodes [edge [0]] ['pos']x1,y1 = G.nodes [edge [1]] ['pos']edge_x.append(x0)edge_x.append(x1)edge_x.append(无)edge_y.append(y0)edge_y.append(y1)edge_y.append(无)edge_trace = go.Scatter(x = edge_x,y = edge_y,line = dict(width = 0.5,color ='#888'),hoverinfo ='none',mode ='lines')返回edge_tracedef get_node_trace(G):node_x = []node_y = []对于G.nodes()中的节点:x,y = G.nodes [node] ['pos']node_x.append(x)node_y.append(y)node_trace = go.Scatter(x = node_x,y = node_y,模式=标记",hoverinfo ='文字',marker = dict(showscale =真,#色阶选项#'灰色'|'YlGnBu'|'绿色'|'YlOrRd'|'Bluered'|"RdBu" |#'Reds'|'布鲁斯'|野餐" |彩虹'波特兰'|'喷气机'|#'热'|'黑体'|地球" |电动" |'Viridis'|colorscale ='YlGnBu',reversescale = True,颜色= [],尺寸= 10,colorbar = dict(厚度= 15,title =节点连接",xanchor ='左',titleside ='正确'),line_width = 2))返回node_trace如果__name__ =='__main__':尾巴= [1、2、3]头= [2,3,4]xpos = [0,1,2,3]ypos = [0,0,0,0]xpos_ypos = [[x,y)表示zip(xpos,ypos)中的x,y]ed_ls = [[(x,y)for zip(tail,head)中的x,y]G = nx.OrderedDiGraph()G.add_edges_from(ed_ls)pos = OrderedDict(zip(G.nodes,xpos_ypos))nx.draw(G,pos = pos,with_labels = True)nx.set_node_attributes(G,pos,'pos')plt.show()#转换为绘图edge_trace = get_edge_trace(G)node_trace = get_node_trace(G)pprint(edge_trace)pprint(node_trace)fig = go.Figure(data = [edge_trace,node_trace],layout = go.Layout(title ='< br>使用Python制作的网络图',titlefont_size = 16,showlegend = False,hovermode ='closest',margin = dict(b = 20,l = 5,r = 5,t = 40),注解= [dict(text ="Python代码:< a href ='https://plot.ly/ipython-notebooks/network-graphs/'> https://plot.ly/ipython-notebooks/network-graphs/</a>",showarrow =假,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)))fig.write_html('plot.html',auto_open = True) 

输出:

上图中各节点的时间序列数据是从如下绘制的数据帧列中读取的

 直接导入plotly.graph_objects将numpy导入为np将熊猫作为pd导入df = pd.DataFrame(np.random.randint(0,100,size =(20,5)),column = list('tABCD'))无花果= go.Figure()fig.add_trace(go.Scatter(x = df.t,y = df ['A'],name ="1",line_color ='deepskyblue',透明度= 0.8))fig.add_trace(go.Scatter(x = df.t,y = df ['B'],name ="2",line_color ='dimgray',透明度= 0.8))fig.add_trace(go.Scatter(x = df.t,y = df ['C'],name ="3",line_color ='蓝色',透明度= 0.8))fig.add_trace(go.Scatter(x = df.t,y = df ['D'],name ="4",line_color ='红色',透明度= 0.8))fig.write_html('ts.html',auto_open = True) 

我想链接以上两个图,即我想使图互动.例如,我想有两个子图,其时序图在左侧,Networkx图在右侧.我想显示与在Networkx图上选择的节点相对应的时间序列图.例如,如果选择标记为1和4的节点,则对应于 name = 1 name = 4 的时间序列数据应显示在左侧.

有关如何执行此操作的任何建议都会很有帮助.

我找到了

我想知道如何更新下面提供的用于添加子图的解决方案

解决方案

编写 post_script ,这是Java代码,创建后将添加到结果div中.

post_script 中,

  • plotly_click 事件
  • 添加事件监听器
  • 检查点击的点是否是标记
  • 相应散点图的
  • 切换 visible 属性从 true 'legendonly'

 将numpy导入为np将熊猫作为pd导入将networkx导入为nx随地导入plotly.graph_objects从plotly.subplots导入make_subplots从pprint导入pprint从集合中导入OrderedDictdef get_edge_trace(G):edge_x = []edge_y = []对于G.edges()中的edge:x0,y0 = G.nodes [edge [0]] ["pos"]x1,y1 = G.nodes [edge [1]] ["pos"]edge_x.append(x0)edge_x.append(x1)edge_x.append(无)edge_y.append(y0)edge_y.append(y1)edge_y.append(无)edge_trace = go.Scatter(x = edge_x,y = edge_y,line = dict(width = 0.5,color =#888"),hoverinfo ="none",showlegend = False,xaxis ="x2",yaxis ="y2",mode ="lines",)返回edge_tracedef get_node_trace(G):node_x = []node_y = []对于G.nodes()中的节点:x,y = G.nodes [node] ["pos"]node_x.append(x)node_y.append(y)node_trace = go.Scatter(x = node_x,y = node_y,mode ="markers",hoverinfo ="text",xaxis ="x2",yaxis ="y2",showlegend = False,marker = dict(showscale =真,#色阶选项#'灰色'|'YlGnBu'|'绿色'|'YlOrRd'|'Bluered'|"RdBu" |#'Reds'|'布鲁斯'|野餐" |彩虹'波特兰'|'喷气机'|#'热'|'黑体'|地球" |电动" |'Viridis'|colorscale ="YlGnBu",reversescale = True,颜色= [],尺寸= 10,colorbar = dict(厚度= 15,title =节点连接",titleside ="right",x = 0.95,),line_width = 2,),)返回node_trace如果__name__ =="__main__":尾巴= [1、2、3]头= [2,3,4]xpos = [0,1,2,3]ypos = [0,0,0,0]xpos_ypos = [[x,y)表示zip(xpos,ypos)中的x,y]ed_ls = [[(x,y)for zip(tail,head)中的x,y]G = nx.OrderedDiGraph()G.add_edges_from(ed_ls)pos = OrderedDict(zip(G.nodes,xpos_ypos))nx.draw(G,pos = pos,with_labels = True)nx.set_node_attributes(G,pos,"pos")无花果= make_subplots(行= 1,列= 2)fig.layout.update(字典(title =< br>使用Python制作的网络图",titlefont_size = 16,hovermode ="closest",#margin = dict(b = 20,l = 5,r = 5,t = 40),注释= [字典(text ="Python代码:< a href ='https://plot.ly/ipython-notebooks/network-graphs/'> https://plot.ly/ipython-notebooks/network-graphs/</a>",showarrow =假,xref ="paper",yref ="paper",x = 0,y = 0,yshift = -0.1,)],yaxis = dict(domain = [0.1,1]),xaxis = dict(domain = [0,0.6]),xaxis2 = dict(域= [0.7,0.94],showgrid =假,zeroline = False,showticklabels =假,),yaxis2 = dict(showgrid = False,zeroline = False,showticklabels = False),))df = pd.DataFrame(np.random.randint(0,100,size =(20,5)),column = list("tABCD"))数据= [go.Scatter(x = df.t,y = df ["A"],名称="1",line_color ="deepskyblue",不透明度= 0.8),go.Scatter(x = df.t,y = df ["B"],名称="2",line_color ="dimgray",不透明度= 0.8),go.Scatter(x = df.t,y = df ["C"],名称="3",line_color ="blue",不透明度= 0.8),go.Scatter(x = df.t,y = df ["D"],name ="4",line_color ="red",opacity = 0.8),]fig.add_traces(数据=数据,行= [1,1,1,1],cols = [1,1,1,1])fig.add_traces(数据= [get_edge_trace(G),get_node_trace(G),],行= [1,1],cols = [2,2])post_script ="gd = document.getElementById('{plot_id}');gd.on('plotly_click',function(data){var pn ='',tn ='',isNodeClick = false;for(var i = 0; i< data.points.length; i ++){pn = data.points [i] .pointNumber;tn = data.points [i] .curveNumber;if(data.points [i] .fullData.mode ==='标记'){isNodeClick = true;}};如果(!isNodeClick)返回;var visible = gd.calcdata [pn] [0] .trace.visible;const update = {''visible':visible === true?'legendonly':true}Plotly.restyle(gd,update,[pn]);返回false;});"fig.write_html("plot.html",post_script = post_script,auto_open = True) 

I've a graph created in Networkx and plotted using plotly

Code:

import numpy as np
import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt
import plotly.graph_objects as go

from pprint import pprint
from collections import OrderedDict


def get_edge_trace(G):
    edge_x = []
    edge_y = []
    for edge in G.edges():
        x0, y0 = G.nodes[edge[0]]['pos']
        x1, y1 = G.nodes[edge[1]]['pos']
        edge_x.append(x0)
        edge_x.append(x1)
        edge_x.append(None)
        edge_y.append(y0)
        edge_y.append(y1)
        edge_y.append(None)

    edge_trace = go.Scatter(
        x=edge_x, y=edge_y,
        line=dict(width=0.5, color='#888'),
        hoverinfo='none',
        mode='lines')
    return edge_trace


def get_node_trace(G):
    node_x = []
    node_y = []
    for node in G.nodes():
        x, y = G.nodes[node]['pos']
        node_x.append(x)
        node_y.append(y)

    node_trace = go.Scatter(
        x=node_x, y=node_y,
        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='YlGnBu',
            reversescale=True,
            color=[],
            size=10,
            colorbar=dict(
                thickness=15,
                title='Node Connections',
                xanchor='left',
                titleside='right'
            ),
            line_width=2))

    return node_trace


if __name__ == '__main__':

    tail = [1, 2, 3]
    head = [2, 3, 4]

    xpos = [0, 1, 2, 3]
    ypos = [0, 0, 0, 0]
    xpos_ypos = [(x, y) for x, y in zip(xpos, ypos)]

    ed_ls = [(x, y) for x, y in zip(tail, head)]
    G = nx.OrderedDiGraph()
    G.add_edges_from(ed_ls)


    pos = OrderedDict(zip(G.nodes, xpos_ypos))
    nx.draw(G, pos=pos, with_labels=True)
    nx.set_node_attributes(G, pos, 'pos')

    plt.show()

    # convert to plotly graph
    edge_trace = get_edge_trace(G)
    node_trace = get_node_trace(G)

    pprint(edge_trace)
    pprint(node_trace)

    fig = go.Figure(data=[edge_trace, node_trace],
                    layout=go.Layout(
                        title='<br>Network graph made with Python',
                        titlefont_size=16,
                        showlegend=False,
                        hovermode='closest',
                        margin=dict(b=20, l=5, r=5, t=40),
                        annotations=[dict(
                            text="Python code: <a href='https://plot.ly/ipython-notebooks/network-graphs/'> https://plot.ly/ipython-notebooks/network-graphs/</a>",
                            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))
                    )
    fig.write_html('plot.html', auto_open=True)

Output:

The time-series data of nodes in the above graph is read from data frame columns plotted as below

import plotly.graph_objects as go
import numpy as np
import pandas as pd

df = pd.DataFrame(np.random.randint(0, 100, size=(20, 5)), columns=list('tABCD'))

fig = go.Figure()
fig.add_trace(go.Scatter(
                x=df.t,
                y=df['A'],
                name="1",
                line_color='deepskyblue',
                opacity=0.8))

fig.add_trace(go.Scatter(
                x=df.t,
                y=df['B'],
                name="2",
                line_color='dimgray',
                opacity=0.8))

fig.add_trace(go.Scatter(
                x=df.t,
                y=df['C'],
                name="3",
                line_color='blue',
                opacity=0.8))

fig.add_trace(go.Scatter(
                x=df.t,
                y=df['D'],
                name="4",
                line_color='red',
                opacity=0.8))

fig.write_html('ts.html', auto_open=True)

I want to link the above two plots, i.e. I want to make the plots interactive. For instance, I'd like to have two subplots with time-series plot on the left and Networkx graph on the right. I would like to display the time-series plots corresponding to the nodes that are selected on the Networkx graph. Example, if nodes labelled 1 and 4 are selected, the time-series data corresponding to name= 1 and name = 4 should be displayed on the left.

Any suggestions on how to do this will be really helpful.

EDIT: I found this, we could select and deselect lines in the plot by clicking on the legend. Likewise, I'd like to select and deselect lines by clicking on the nodes in Networkx graph.

EDIT2: For creating subplots

import plotly.graph_objects as go
import numpy as np
import pandas as pd
from plotly.subplots import make_subplots

df = pd.DataFrame(np.random.randint(0, 100, size=(20, 5)), columns=list('tABCD'))
df2 = pd.DataFrame(np.random.randint(0, 100, size=(20, 5)), columns=list('tABCD'))

fig = go.Figure()
fig = make_subplots(rows=1, cols=2)

fig.add_trace(go.Scatter(
                x=df.t,
                y=df['A'],
                name="1",
                line_color='deepskyblue',
                opacity=0.8,
                legendgroup='group1'),
                row=1, col=1
                )

fig.add_trace(go.Scatter(
                x=df.t,
                y=df['B'],
                name="2",
                line_color='dimgray',
                opacity=0.8,
                legendgroup='group2'),
                row=1, col=1
                )

fig.add_trace(go.Scatter(
                x=df.t,
                y=df['C'],
                name="3",
                line_color='blue',
                opacity=0.8,
                legendgroup='group3'),
                row=1, col=1
                )

fig.add_trace(go.Scatter(
                x=df.t,
                y=df['D'],
                name="4",
                line_color='red',
                opacity=0.8,
                legendgroup='group4'),
                row=1, col=1
                )

fig.add_trace(go.Scatter(
                x=df2.t,
                y=df2['A'],
                name="1",
                line_color='deepskyblue',
                opacity=0.8,
                legendgroup='group1',
                showlegend=False),
                row=1, col=2
                )

fig.add_trace(go.Scatter(
                x=df2.t,
                y=df2['B'],
                name="2",
                line_color='dimgray',
                opacity=0.8,
                legendgroup='group2',
                showlegend=False),
                row=1, col=2
                )

fig.add_trace(go.Scatter(
                x=df2.t,
                y=df2['C'],
                name="3",
                line_color='blue',
                opacity=0.8,
                legendgroup='group3',
                showlegend=False),
                row=1, col=2
                )

fig.add_trace(go.Scatter(
                x=df2.t,
                y=df2['D'],
                name="4",
                line_color='red',
                opacity=0.8,
                legendgroup='group4',
                showlegend=False),
                row=1, col=2
                )

fig.write_html('ts.html', auto_open=True)

I would like to know how to update the solution provided below for adding subplots

解决方案

Write post_script which is Javascript code that will be added in the resulting div after it's created.

In post_script,

  • add an event listener for plotly_click event
  • check if clicked point is a marker
  • toggle visible property of corresponding scatter plot from true to 'legendonly'

import numpy as np
import pandas as pd
import networkx as nx
import plotly.graph_objects as go
from plotly.subplots import make_subplots

from pprint import pprint
from collections import OrderedDict


def get_edge_trace(G):
    edge_x = []
    edge_y = []
    for edge in G.edges():
        x0, y0 = G.nodes[edge[0]]["pos"]
        x1, y1 = G.nodes[edge[1]]["pos"]
        edge_x.append(x0)
        edge_x.append(x1)
        edge_x.append(None)
        edge_y.append(y0)
        edge_y.append(y1)
        edge_y.append(None)

    edge_trace = go.Scatter(
        x=edge_x,
        y=edge_y,
        line=dict(width=0.5, color="#888"),
        hoverinfo="none",
        showlegend=False,
        xaxis="x2",
        yaxis="y2",
        mode="lines",
    )
    return edge_trace


def get_node_trace(G):
    node_x = []
    node_y = []
    for node in G.nodes():
        x, y = G.nodes[node]["pos"]
        node_x.append(x)
        node_y.append(y)

    node_trace = go.Scatter(
        x=node_x,
        y=node_y,
        mode="markers",
        hoverinfo="text",
        xaxis="x2",
        yaxis="y2",
        showlegend=False,
        marker=dict(
            showscale=True,
            # colorscale options
            # 'Greys' | 'YlGnBu' | 'Greens' | 'YlOrRd' | 'Bluered' | 'RdBu' |
            # 'Reds' | 'Blues' | 'Picnic' | 'Rainbow' | 'Portland' | 'Jet' |
            # 'Hot' | 'Blackbody' | 'Earth' | 'Electric' | 'Viridis' |
            colorscale="YlGnBu",
            reversescale=True,
            color=[],
            size=10,
            colorbar=dict(
                thickness=15,
                title="Node Connections",
                titleside="right",
                x=0.95,
            ),
            line_width=2,
        ),
    )

    return node_trace


if __name__ == "__main__":

    tail = [1, 2, 3]
    head = [2, 3, 4]

    xpos = [0, 1, 2, 3]
    ypos = [0, 0, 0, 0]
    xpos_ypos = [(x, y) for x, y in zip(xpos, ypos)]

    ed_ls = [(x, y) for x, y in zip(tail, head)]
    G = nx.OrderedDiGraph()
    G.add_edges_from(ed_ls)

    pos = OrderedDict(zip(G.nodes, xpos_ypos))
    nx.draw(G, pos=pos, with_labels=True)
    nx.set_node_attributes(G, pos, "pos")

    fig = make_subplots(rows=1, cols=2)
    fig.layout.update(
        dict(
            title="<br>Network graph made with Python",
            titlefont_size=16,
            hovermode="closest",
            # margin=dict(b=20, l=5, r=5, t=40),
            annotations=[
                dict(
                    text="Python code: <a href='https://plot.ly/ipython-notebooks/network-graphs/'> https://plot.ly/ipython-notebooks/network-graphs/</a>",
                    showarrow=False,
                    xref="paper",
                    yref="paper",
                    x=0,
                    y=0,
                    yshift=-0.1,
                )
            ],
            yaxis=dict(domain=[0.1, 1]),
            xaxis=dict(domain=[0, 0.6]),
            xaxis2=dict(
                domain=[0.7, 0.94],
                showgrid=False,
                zeroline=False,
                showticklabels=False,
            ),
            yaxis2=dict(showgrid=False, zeroline=False, showticklabels=False),
        )
    )

    df = pd.DataFrame(
        np.random.randint(0, 100, size=(20, 5)), columns=list("tABCD")
    )

    data = [
        go.Scatter(
            x=df.t, y=df["A"], name="1", line_color="deepskyblue", opacity=0.8
        ),
        go.Scatter(
            x=df.t, y=df["B"], name="2", line_color="dimgray", opacity=0.8
        ),
        go.Scatter(
            x=df.t, y=df["C"], name="3", line_color="blue", opacity=0.8
        ),
        go.Scatter(x=df.t, y=df["D"], name="4", line_color="red", opacity=0.8),
    ]

    fig.add_traces(data=data, rows=[1, 1, 1, 1], cols=[1, 1, 1, 1])

    fig.add_traces(
        data=[get_edge_trace(G), get_node_trace(G),], rows=[1, 1], cols=[2, 2]
    )

    post_script = """
    gd = document.getElementById('{plot_id}');
    gd.on('plotly_click', function(data) {
        var pn='',
        tn='',
        isNodeClick=false;
        for (var i=0; i < data.points.length; i++){
            pn = data.points[i].pointNumber;
            tn = data.points[i].curveNumber;
            if(data.points[i].fullData.mode === 'markers') {
                isNodeClick = true;
            }
        };
        if (!isNodeClick) return;
        var visible = gd.calcdata[pn][0].trace.visible;
        const update = {'visible': visible === true ? 'legendonly': true}
        Plotly.restyle(gd, update, [pn]);
        return false;
    });
    """
    fig.write_html("plot.html", post_script=post_script, auto_open=True)

这篇关于可视化图形节点中的时间序列数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆