问题
I have created a holoviews chord plot where each node is associated with particular group(community). I have a requirement that whenever I tap on a particular node all the edge associated with it should be same color as the color of the node.
For example in this chord diagram example chord If I select a blue node the edge color should be same as node color(i.e blue). But Here when I click on a blue node I am getting few edges of of blue and few edges of orange color(basically the edge takes the color of it's source node). Is there any way to customize the color of the edges depending upon the node selection? I can see few options available for the edge_selection_line_color
like field, attr, value etc but could not figure out how to use this for customizing the edge color like my requirement. I am sure that it is fairly easy task but could not figure out how to achieve and I am stuck in it.
Also let me know if it is possible using bokeh CustomJS
.
Attaching the source code for reference:
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 ))
来源:https://stackoverflow.com/questions/62970139/customize-edge-color-based-on-node-selection-holoviews-bokeh-chord-diagram