Раскрашивание узлов по классам (и добавление класса в качестве vdim) в Holoviews с помощью networkx и bokeh

#python #networkx #bokeh #holoviews

#python #networkx #боке #holoviews

Вопрос:

итак, я пытаюсь раскрасить свои узлы в соответствии с категориями, скажем categories = ['a', 'b', 'c']

 for comb in data:
    edges.append((comb['comb'][0], comb['comb'][1], comb['count']))
      
graph = hv.Graph(edges, vdims='weight') 
graph = layout_nodes(graph, layout=nx.layout.fruchterman_reingold_layout, kwargs={'weight': 'weight'})
nodes_array = graph.nodes.array()
for node in nodes_array:
    (node) #add vdim to node here and set node_color to this vdim?
labels = hv.Labels(([i[0] for i in nodes_array], [i[1] for i in nodes_array], [i[2] for i in nodes_array]))

(graph.opts(width=800, height=800, node_color='weight')*labels.opts(text_font_size='8pt', text_color='blue')) 
 

что мне нужно, так это способ сделать это, я полагаю, мне нужно установить категорию для каждого узла, каким-то образом определить его как vdim, а затем установить node_color для этого vdim?

Я видел другие вопросы о конкретных узлах и тому подобное, но я не думаю, что смогу определить узлы (включая положение), поскольку мне нужно fruchterman_reingold_layout сделать это для меня.

(Бонус, если есть способ также изменить размер узла)

редактировать: Итак, я также попробовал добавить измерение через add_dimension , как показано в документации здесь: http://holoviews.org/user_guide/Dimensioned_Containers.html

graph.nodes.add_dimension('weight', dim_pos=3, dim_val=['a'] * 457) 457 — это количество моих узлов, так что это правильно, но я получаю следующую ошибку: ValueError: kdims: list length must be between 3 and 3 (inclusive) также я точно не знаю, что делать с результатом функции, я думаю, каким-то образом установить его как новые узлы?

Ответ №1:

Отвечая на мой собственный вопрос, я нашел способ добиться желаемого результата. Это скорее обходной путь, чем чистое решение, но оно работает, поэтому может быть полезным для других, пока не будет лучшего ответа.

 from holoviews.element.graphs import layout_nodes
import random
G = hv.Graph([
    ('a', 'b', 3),
    ('a', 'c', 0.2),
    ('c', 'd', 0.1),
    ('c', 'e', 0.7),
    ('c', 'f', 5),
    ('a', 'd', 0.3)
], vdims=['weight'])

G = layout_nodes(G, layout=nx.layout.fruchterman_reingold_layout, kwargs={'weight': 'weight'})
nodes_array = G.nodes.array()
newNodes_array = []
for node in nodes_array:
    newNodes_array.append((node[0], node[1], node[2], random.choice(['class1', 'class2', 'class3'])))
N = hv.Nodes(newNodes_array, vdims='class')

labels = hv.Labels(([i[0] for i in nodes_array], [i[1] for i in nodes_array], [i[2] for i in nodes_array]))
G*(N).opts(color = 'class', cmap='Set1')*labels
 

После G.nodes.array() применения требуемого копируется nx.layout.fruchterman_reingold_layout , поэтому затем можно добавить новое измерение к этим узлам и построить их вместе с графиком.
Вывод:

Выходной график