根据节点选择自定义边缘颜色Holoviews / Bokeh Chord图

时间:2020-07-18 15:09:18

标签: python-3.x pandas bokeh holoviews chord-diagram

我创建了一个holoviews和弦图,其中每个节点都与特定的组(社区)相关联。我有一个要求,每当我点击特定节点时,与之关联的所有边缘的颜色都应与该节点的颜色相同。

例如在此和弦图example chord中,如果我选择一个蓝色节点,则其边缘颜色应与节点颜色相同(即蓝色)。但是,Here单击蓝色节点时,得到的蓝色边缘很少,而橙色边缘则很少(基本上,边缘采用源节点的颜色)。有什么方法可以根据节点选择来自定义边缘的颜色?我看不到edge_selection_line_color可用的几个选项,例如字段,属性,值等,但无法像我的要求那样弄清楚如何使用它来自定义边缘颜色。我确信这是一项相当容易的任务,但无法弄清楚如何实现,因此我陷入其中。 还请让我知道是否可以使用散景CustomJS

附加源代码以供参考:

edge_data = [{"from": "Cronje", "to": "Lord Kitchener", "value": 1}, {"from": "Cronje", "to": "Lord Selborne", "value": 1}, {"from": "Cronje", "to": "George Godfrey", "value": 1}, {"from": "Cronje", "to": "Lord Milner", "value": 1}, {"from": "Cronje", "to": "Booker T. Washington", "value": 1}, {"from": "Cronje", "to": "Dada Abdulla", "value": 1}, {"from": "Cronje", "to": "Lord Lansdowne", "value": 1}, {"from": "Cronje", "to": "Escombe", "value": 1}, {"from": "Cronje", "to": "Messrs", "value": 1}, {"from": "Cronje", "to": "Lawley", "value": 1}, {"from": "Cronje", "to": "Sheth Haji Adam", "value": 1}, {"from": "Cronje", "to": "Lord Ripon", "value": 1}, {"from": "Cronje", "to": "Lord Elgin", "value": 1}, {"from": "Sheth Haji Adam", "to": "Lord Kitchener", "value": 1}, {"from": "Sheth Haji Adam", "to": "Lord Selborne", "value": 1}, {"from": "Sheth Haji Adam", "to": "George Godfrey", "value": 1}, {"from": "Sheth Haji Adam", "to": "Dada Abdulla", "value": 1}, {"from": "Sheth Haji Adam", "to": "Booker T. Washington", "value": 1}, {"from": "Sheth Haji Adam", "to": "Lord Milner", "value": 1}, {"from": "Sheth Haji Adam", "to": "Lord Lansdowne", "value": 1}, {"from": "Sheth Haji Adam", "to": "Escombe", "value": 1}, {"from": "Sheth Haji Adam", "to": "Messrs", "value": 1}, {"from": "Sheth Haji Adam", "to": "Lawley", "value": 1}, {"from": "Sheth Haji Adam", "to": "Lord Elgin", "value": 1}, {"from": "Sheth Haji Adam", "to": "Lord Ripon", "value": 1}, {"from": "Lord Selborne", "to": "Lord Elgin", "value": 1}, {"from": "Lord Selborne", "to": "George Godfrey", "value": 1}, {"from": "Lord Selborne", "to": "Merriman", "value": 1}, {"from": "Lord Selborne", "to": "Olive Schreiner", "value": 1}, {"from": "Lord Selborne", "to": "Dada Abdulla", "value": 1}, {"from": "Lord Selborne", "to": "Booker T. Washington", "value": 1}, {"from": "Lord Selborne", "to": "Lord Milner", "value": 1}, {"from": "Lord Selborne", "to": "Lord Kitchener", "value": 1}, {"from": "Lord Selborne", "to": "Lord Lansdowne", "value": 1}, {"from": "Lord Selborne", "to": "Escombe", "value": 1}, {"from": "Lord Selborne", "to": "Messrs", "value": 1}, {"from": "Lord Selborne", "to": "Lawley", "value": 1}, {"from": "Lord Selborne", "to": "John Molteno", "value": 1}, {"from": "Lord Selborne", "to": "Lord Ripon", "value": 1}, {"from": "George Godfrey", "to": "Dada Abdulla", "value": 1}, {"from": "George Godfrey", "to": "Booker T. Washington", "value": 1}, {"from": "George Godfrey", "to": "Lord Milner", "value": 1}, {"from": "George Godfrey", "to": "Lord Kitchener", "value": 1}, {"from": "George Godfrey", "to": "Lord Lansdowne", "value": 1}, {"from": "George Godfrey", "to": "Escombe", "value": 1}, {"from": "George Godfrey", "to": "Messrs", "value": 1}, {"from": "George Godfrey", "to": "Lawley", "value": 1}, {"from": "George Godfrey", "to": "Lord Elgin", "value": 1}, {"from": "George Godfrey", "to": "Lord Ripon", "value": 1}, {"from": "Merriman", "to": "Lord Lansdowne", "value": 1}, {"from": "Merriman", "to": "John Molteno", "value": 1}, {"from": "Merriman", "to": "Olive Schreiner", "value": 1}, {"from": "Olive Schreiner", "to": "Lord Lansdowne", "value": 1}, {"from": "Olive Schreiner", "to": "John Molteno", "value": 1}, {"from": "Dada Abdulla", "to": "Lord Kitchener", "value": 1}, {"from": "Dada Abdulla", "to": "Booker T. Washington", "value": 1}, {"from": "Dada Abdulla", "to": "Lord Milner", "value": 1}, {"from": "Dada Abdulla", "to": "Lord Lansdowne", "value": 1}, {"from": "Dada Abdulla", "to": "Escombe", "value": 1}, {"from": "Dada Abdulla", "to": "Messrs", "value": 1}, {"from": "Dada Abdulla", "to": "Lawley", "value": 1}, {"from": "Dada Abdulla", "to": "Lord Elgin", "value": 1}, {"from": "Dada Abdulla", "to": "Lord Ripon", "value": 1}, {"from": "Booker T. Washington", "to": "Lord Milner", "value": 1}, {"from": "Booker T. Washington", "to": "Lord Kitchener", "value": 1}, {"from": "Booker T. Washington", "to": "Lord Lansdowne", "value": 1}, {"from": "Booker T. Washington", "to": "Escombe", "value": 1}, {"from": "Booker T. Washington", "to": "Messrs", "value": 1}, {"from": "Booker T. Washington", "to": "Lawley", "value": 1}, {"from": "Booker T. Washington", "to": "Lord Elgin", "value": 1}, {"from": "Booker T. Washington", "to": "Lord Ripon", "value": 1}, {"from": "Lord Milner", "to": "Lord Kitchener", "value": 1}, {"from": "Lord Milner", "to": "Lord Lansdowne", "value": 1}, {"from": "Lord Milner", "to": "Escombe", "value": 1}, {"from": "Lord Milner", "to": "Messrs", "value": 1}, {"from": "Lord Milner", "to": "Lawley", "value": 1}, {"from": "Lord Milner", "to": "Lord Elgin", "value": 1}, {"from": "Lord Milner", "to": "Lord Ripon", "value": 1}, {"from": "Lord Kitchener", "to": "Lord Lansdowne", "value": 1}, {"from": "Lord Kitchener", "to": "Escombe", "value": 1}, {"from": "Lord Kitchener", "to": "Messrs", "value": 1}, {"from": "Lord Kitchener", "to": "Lawley", "value": 1}, {"from": "Lord Kitchener", "to": "Lord Elgin", "value": 1}, {"from": "Lord Kitchener", "to": "Lord Ripon", "value": 1}, {"from": "Lord Lansdowne", "to": "Escombe", "value": 1}, {"from": "Lord Lansdowne", "to": "Messrs", "value": 1}, {"from": "Lord Lansdowne", "to": "Lawley", "value": 1}, {"from": "Lord Lansdowne", "to": "John Molteno", "value": 1}, {"from": "Lord Lansdowne", "to": "Lord Elgin", "value": 1}, {"from": "Lord Lansdowne", "to": "Lord Ripon", "value": 1}, {"from": "Escombe", "to": "Messrs", "value": 1}, {"from": "Escombe", "to": "Lawley", "value": 1}, {"from": "Escombe", "to": "Lord Elgin", "value": 1}, {"from": "Escombe", "to": "Lord Ripon", "value": 1}, {"from": "Messrs", "to": "Lawley", "value": 1}, {"from": "Messrs", "to": "Lord Elgin", "value": 1}, {"from": "Messrs", "to": "Lord Ripon", "value": 1}, {"from": "Lawley", "to": "Lord Elgin", "value": 1}, {"from": "Lawley", "to": "Lord Ripon", "value": 1}, {"from": "Lord Elgin", "to": "Lord Ripon", "value": 1}]

community_data = [{"person": "Cronje", "community": "0"}, {"person": "Sheth Haji Adam", "community": "0"}, {"person": "Lord Selborne", "community": "1"}, {"person": "George Godfrey", "community": "0"}, {"person": "Merriman", "community": "1"}, {"person": "Olive Schreiner", "community": "1"}, {"person": "Dada Abdulla", "community": "0"}, {"person": "Booker T. Washington", "community": "0"}, {"person": "Lord Milner", "community": "0"}, {"person": "Lord Kitchener", "community": "0"}, {"person": "Lord Lansdowne", "community": "1"}, {"person": "Escombe", "community": "0"}, {"person": "Messrs", "community": "0"}, {"person": "Lawley", "community": "0"}, {"person": "John Molteno", "community": "1"}, {"person": "Lord Elgin", "community": "0"}, {"person": "Lord Ripon", "community": "0"}]

import pandas as pd
import holoviews as hv
from holoviews import opts, dim
import numpy as np
hv.extension('bokeh')
hv.output(size=300)

##Read the edge data and community data for the chordial
df_json = pd.DataFrame(edge_data)
com_json = pd.DataFrame(community_data)

##Creating pandas dataframe from edge-data with columns source, target and value
df_links = pd.DataFrame(columns = ['source', 'target', 'value'])
df_links['source'] = df_json['from'].values.tolist()
df_links['target'] = df_json['to'].values.tolist()
df_links['value'] = df_json['value'].values.tolist()

##Creating pandas dataframe from community data to associate each node with a particular community
df_nodes = pd.DataFrame(columns=['index', 'source', 'community'])
df_nodes['source'] =  com_json['person'].values.tolist()
df_nodes['community'] = com_json['community'].values.tolist()
df_nodes = df_nodes.sort_values('community')
df_nodes['index'] = [x for x in range(0, len(df_nodes.values))]

##Creating a mapper dictionary to assign each node to a numerical unique value
mapper = {}
df_dict = df_nodes.to_dict()
for items, values in df_dict['index'].items():
    mapper[df_dict['source'][items]] = values
    
##Joining edge-data-frame with community data-frame to assign edge source with the source community    
df_edge_with_community = pd.merge(df_links, df_nodes, on='source')
del df_edge_with_community['index']
df_edge_with_community.rename(columns={'community': 'edge_community'}, inplace=True)

##Assigning each node to numerical value
df_edge_with_community['source'] = df_edge_with_community['source'].map(mapper)
df_edge_with_community['target'] = df_edge_with_community['target'].map(mapper)

##Creating hv dataset from df_nodes
nodes = hv.Dataset(df_nodes, 'index')

##Creating Chordials
chord = hv.Chord((df_edge_with_community, nodes)).select(value=(1, None))
chord.opts(
    opts.Chord(cmap='Category10', edge_cmap='Category10', edge_color=dim('edge_community').str(),
               labels='source',  label_text_font_size='10px',label_text_font_style='bold',  node_color=dim('community').str(),
               edge_alpha= 0.8, node_selection_fill_color=None, edge_nonselection_line_alpha=0, edge_line_width=5,
              edge_hover_line_color=None )) 

0 个答案:

没有答案