vrproject

Complex Network Analysis VR-project
git clone git://popovic.xyz/vrproject.git
Log | Files | Refs | LICENSE

nxplot_3d.py (9952B)


      1 #!/usr/bin/evn python3.10
      2 
      3 import matplotlib.pyplot as plt
      4 import matplotlib.cm as cm
      5 
      6 import plotly
      7 import plotly.graph_objs as pgo
      8 
      9 def get_trace_nodes_3D_legend(posG, info, color, size, legend_names = None, linewidth=0.000001, opac = 0.9):
     10     '''
     11     Get trace of nodes for plotting in 3D.
     12     Input:
     13     - posG = dictionary with nodes as keys and coordinates as values.
     14     - info = hover information for each node, e.g. a dictionary with node IDs and values = hover information
     15     - color = a dictionary of key = association name for each color (for legend) and value = hex color
     16     - size = a dictionary with node Ids and values=sizes of nodes
     17     - legend_names = list of values e.g. strings for each color
     18     - linewidth = float; contour of nodes
     19     - opac = transparency of nodes
     20 
     21     Return a trace for plotly graph objects plot including a legend.
     22     '''
     23 
     24     # dividing traces based on unique colors > for legend
     25     color_dict = {}
     26     for i in set(color.values()):
     27         sublist = []
     28         for k,v in color.items():
     29             if v == i:
     30                 sublist.append(k)
     31         color_dict[i]= sublist
     32 
     33     d_col_pos = {}
     34     for i,j_list in color_dict.items():
     35         sub = {}
     36         for ix,(k,v) in enumerate(posG.items()):
     37             if k in j_list:
     38                 #sub[ix] = v
     39                 sub[k] = v
     40             d_col_pos[i] = sub
     41     d_col_pos_ordered = dict(sorted(d_col_pos.items(),reverse=True))
     42 
     43     # creating traces
     44     traces = []
     45 
     46     if legend_names is not None and len(legend_names) == len(set(color.values())):
     47 
     48         for elem,(col, dct) in enumerate(d_col_pos_ordered.items()):
     49 
     50             ids = list(dct.keys())
     51             coords = list(dct.values())
     52 
     53             l_info_sorted_to_ids = [(info[key]) for key in ids] #{key:info[key] for key in ids}
     54             #l_info_sorted_to_ids = list(info_sorted_to_ids.values())
     55 
     56             l_size_sorted_to_ids = [(size[key]) for key in ids] #{key:size[key] for key in ids}
     57             #l_size_sorted_to_ids = list(size_sorted_to_ids.values())
     58 
     59             trace = pgo.Scatter3d(x=[i[0] for i in coords],
     60                                   y=[i[1] for i in coords],
     61                                   z=[i[2] for i in coords],
     62                                   mode = 'markers',
     63                                   text = l_info_sorted_to_ids,
     64                                   hoverinfo = 'text',
     65                                        marker = dict(
     66                             color = col,
     67                             size = l_size_sorted_to_ids,
     68                             symbol = 'circle',
     69                             line = dict(width = linewidth,
     70                                     color = 'dimgrey'),
     71                             opacity = float(col[4:][1:-1].split(', ')[-1]),
     72                         ),
     73                     name = "Group: "+str(list(legend_names.values())[elem])
     74                     )
     75             traces.append(trace)
     76         return traces
     77 
     78     else:
     79         for elem,(col, dct) in enumerate(d_col_pos_ordered.items()):
     80 
     81             ids = list(dct.keys())
     82             coords = list(dct.values())
     83 
     84             l_info_sorted_to_ids = [(info[key]) for key in ids] #{key:info[key] for key in ids}
     85             #l_info_sorted_to_ids = list(info_sorted_to_ids.values())
     86 
     87             l_size_sorted_to_ids = [(size[key]) for key in ids] #{key:size[key] for key in ids}
     88             #l_size_sorted_to_ids = list(size_sorted_to_ids.values())
     89 
     90             trace = pgo.Scatter3d(x=[i[0] for i in coords],
     91                                   y=[i[1] for i in coords],
     92                                   z=[i[2] for i in coords],
     93                                   mode = 'markers',
     94                                   text = l_info_sorted_to_ids,
     95                                   hoverinfo = 'text',
     96                                        marker = dict(
     97                             color = col,
     98                             size = l_size_sorted_to_ids,
     99                             symbol = 'circle',
    100                             line = dict(width = linewidth,
    101                                     color = 'dimgrey'),
    102                             opacity = float(col[4:][1:-1].split(', ')[-1])/100,
    103                         ),
    104                     name = "Group: "+str(elem)
    105                     )
    106             traces.append(trace)
    107         return traces
    108 
    109 
    110 def get_trace_edges_3D(G, posG, color = '#C7C7C7', opac = 0.1, linewidth=0.1):
    111     '''
    112     Get trace of edges for plotting in 3D.
    113     Input:
    114     - G = Graph
    115     - posG = dictionary with nodes as keys and coordinates as values.
    116     - color = string; hex color
    117     - opac = transparency of edges e.g. 1.2
    118     - linewidth = float;
    119 
    120     Return a trace for plotly graph objects plot.
    121     '''
    122 
    123     edge_x = []
    124     edge_y = []
    125     edge_z = []
    126     for edge in G.edges():
    127             x0, y0, z0 = posG[edge[0]]
    128             x1, y1, z1 = posG[edge[1]]
    129             edge_x.append(x0)
    130             edge_x.append(x1)
    131             edge_x.append(None)
    132             edge_y.append(y0)
    133             edge_y.append(y1)
    134             edge_y.append(None)
    135             edge_z.append(z0)
    136             edge_z.append(z1)
    137             edge_z.append(None)
    138 
    139     trace_edges = pgo.Scatter3d(
    140                                 x = edge_x,
    141                                 y = edge_y,
    142                                 z = edge_z,
    143                                 mode = 'lines', hoverinfo='none',
    144                                 line = dict(width = linewidth, color = color),
    145                                 opacity = opac,
    146                                 name = "Links"
    147                         )
    148 
    149     return trace_edges
    150 
    151 
    152 # -------------------------------------------------------------------------------------
    153 # -------------------------------------------------------------------------------------
    154 
    155 # P L O T T I N G
    156 
    157 # -------------------------------------------------------------------------------------
    158 # -------------------------------------------------------------------------------------
    159 
    160 
    161 
    162 def plot_3D(data, path, fname, scheme='light',annotat=None, show_leg=True, auto_open=True):
    163     '''
    164     Create a 3D plot from traces using plotly.
    165     Input:
    166     - data = list of traces
    167     - filename = string
    168     - scheme = 'light' or 'dark'
    169     - annotations = None or plotly annotations
    170 
    171     Return plot in 3D and file, saved as html.
    172     '''
    173 
    174     fig = pgo.Figure()
    175 
    176     for i in data:
    177         fig.add_trace(i)
    178 
    179     if scheme == 'dark' and annotat==None:
    180         fig.update_layout(template='plotly_dark',
    181                           showlegend=show_leg, autosize = True,
    182                           scene=dict(
    183                               xaxis_title='',
    184                               yaxis_title='',
    185                               zaxis_title='',
    186                               xaxis=dict(nticks=0,tickfont=dict(
    187                                     color='black')),
    188                               yaxis=dict(nticks=0,tickfont=dict(
    189                                     color='black')),
    190                               zaxis=dict(nticks=0,tickfont=dict(
    191                                     color='black')),
    192                             dragmode="turntable"
    193                         ))
    194 
    195     elif scheme == 'dark':
    196         fig.update_layout(template='plotly_dark',
    197                           showlegend=show_leg, autosize = True,
    198                                   scene=dict(
    199                                       xaxis_title='',
    200                                       yaxis_title='',
    201                                       zaxis_title='',
    202                                       xaxis=dict(nticks=0,tickfont=dict(
    203                                             color='black')),
    204                                       yaxis=dict(nticks=0,tickfont=dict(
    205                                             color='black')),
    206                                       zaxis=dict(nticks=0,tickfont=dict(
    207                                             color='black')),
    208                                     dragmode="turntable",
    209                                     annotations=annotat,
    210                                 ))
    211 
    212     elif scheme == 'light' and annotat==None:
    213         fig.update_layout(template='plotly_white',
    214                           showlegend=show_leg, width=1200, height=1200,
    215                           scene=dict(
    216                               xaxis_title='',
    217                               yaxis_title='',
    218                               zaxis_title='',
    219                               xaxis=dict(nticks=0,tickfont=dict(
    220                                     color='white')),
    221                               yaxis=dict(nticks=0,tickfont=dict(
    222                                     color='white')),
    223                               zaxis=dict(nticks=0,tickfont=dict(
    224                                     color='white')),
    225                             dragmode="turntable",
    226                         ))
    227 
    228     elif scheme == 'light':
    229         fig.update_layout(template='plotly_white',
    230                           showlegend=show_leg, width=1200, height=1200,
    231                           scene=dict(
    232                               xaxis_title='',
    233                               yaxis_title='',
    234                               zaxis_title='',
    235                               xaxis=dict(nticks=0,tickfont=dict(
    236                                     color='white')),
    237                               yaxis=dict(nticks=0,tickfont=dict(
    238                                     color='white')),
    239                               zaxis=dict(nticks=0,tickfont=dict(
    240                                     color='white')),
    241                             dragmode="turntable",
    242                             annotations = annotat
    243                         ))
    244     else:
    245         print('Oops, something went wrong. Please check input parameters.')
    246 
    247     fig.update_xaxes(visible=False)
    248     fig.update_yaxes(visible=False)
    249     fig.write_html(path+fname+'.html')
    250 
    251     return plotly.offline.plot(fig, filename = path+fname+'.html', auto_open=auto_open)