Change node color of a graph

Hello everyone,

I’m trying to interactively highlight a node of a graph in a diffferent color after the graph has been created.

This question provides a more concrete example than in my previously posted question in https://discourse.holoviz.org/t/how-to-add-node-attribute-after-a-graph-has-been-created/4128. I hope you might have an idea how to code this.

The code below shows what I mean:

import panel as pn
import numpy as np
import holoviews as hv
pn.extension()

def hv_graph():
	# set up the graph 
    node_indices = np.arange(3, dtype=np.int32)
    source = np.zeros(3, dtype=np.int32)
    target = node_indices
    # create graph
    x, y = [0, 1, 1], [0, 1, 2]  # some coordinates
    nodes = hv.Nodes((x, y, node_indices),)
    graph = hv.Graph(((source, target), nodes))
    return graph

def adjust_graph(graph, highlight_node):
    node_indices = graph.nodes.data["index"].values
    # set node colors
    node_colors = []
    for node in node_indices:
        # below the squared brackets are required as this example only allows one node to be colored
        if node == highlight_node:  # color the chosen node red
            node_colors.append("red")
        else:
            node_colors.append("black")  # color all other nodes with any other color
    graph.nodes.data["color"] = node_colors
    graph = graph.opts(node_color='color')
    return graph

def both_function_combined_works(highlight_node):
    node_indices = np.arange(3, dtype=np.int32)
    # set node colors
    node_colors = []
    for node in node_indices:
        # below the squared brackets are required as this example only allows one node to be colored
        if node == highlight_node:  # color the chosen node red
            node_colors.append("red")
        else:
            node_colors.append("black")  # color all other nodes with any other color
    # set up the graph
    source = np.zeros(3, dtype=np.int32)
    target = node_indices
    # create graph, this time with the node color integrated directly into the graph
    x, y = [0, 1, 1], [0, 1, 2]  # some coordinates
    nodes = hv.Nodes((x, y, node_indices, node_colors), vdims='color')
    graph = hv.Graph(((source, target), nodes))
    graph = graph.opts(node_color='color')
    return graph


## works
h = pn.interact(both_function_combined_works, highlight_node=[0, 1, 2])
h.save('works.html', embed=True)
#
## doesn't work for some reason
# error message:
# (BAD_COLUMN_NAME): Glyph refers to nonexistent column name.
# This could either be due to a misspelling or typo, or due to an expected #column being missing.
graph = hv_graph()
def adjust_helper(highlight_node):
    return adjust_graph(graph, highlight_node)
h2 = pn.interact(adjust_helper, highlight_node=[0, 1, 2])
h2.save('does_not_work.html', embed=True)

If the color is directly specified as the graph is created then its easy. This is shown below in the function both_function_combined_works() (saved in 'works.html).
However, first creating the graph with hv_graph() and then adjusting the color in the function adjust_graph() results in the following error (result saved in 'does_not_work.html').

ERROR:bokeh.core.validation.check:E-1001 (BAD_COLUMN_NAME): Glyph refers to nonexistent column name. This could either be due to a misspelling or typo, or due to an expected column being missing. : key "fill_color" value "color", key "hatch_color" value "color" [renderer: GlyphRenderer(id='2023', ...)]

This must be because graph.nodes.data["color"] = node_colors is an insufficient way to specify a graph attribute after the fact. For example graph.nodes.columns() does not show color as a column, whereas graph.nodes.data does.

So how do I resolve this error and get my code to work in that case?

I hope my question is clear. Feel free to ask if anything is confusing.