Scrolldown window where multiple options can be selected

Hello everyone,

I‘m looking for a scrolldown window (or something similar) in which I can select multiple parameters. To motivate this, here is an example:

I would like to color the given nodes of a graph in red. The issue is that I need an interactive widget, where I have the option to select multiple nodes at once (up to all nodes). I‘m looking for something like a scrolldown window in which I can select multiple nodes. Without this type of widget, any interactive panel would get quite crowded for a sufficiently large graph because all nodes need to be available to be selected.

Below you can find the code for that example (although it can currently only color one node by using a slider).

I‘m not too familiar with panel yet, so I apologize if the answer is obvious. Thanks in advance for any help!

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

# produces a small graph and colors one of the nodes red and the others black
# Ideally, I would like to select multiple nodes from the given node set to be colored red
def hv_graph(color_these_nodes):
	# set up the graph 
    node_indices = np.arange(3, dtype=np.int32)
    source = np.zeros(3, dtype=np.int32)
    target = node_indices

    # color all given nodes
    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 in [color_these_nodes]:  # color the chosen node red
            node_colors.append("red")
        else:
            node_colors.append("black")  # color all other nodes with any other color

    # create 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)).opts(node_color='color')
    return graph

all_nodes = [0, 1, 2]  # the user should be able to pick any (also multiple ones) of these nodes to be highlighted
h = pn.interact(hv_graph, color_these_nodes=all_nodes)
h.save('graph.html', embed=True)
1 Like

Hi @optmat

Great question. You can see the available widgets in the Panel reference Gallery. It sounds like the one you are looking for is the MultiSelect widget.

import panel as pn
import numpy as np
import holoviews as hv

pn.extension()

# produces a small graph and colors one of the nodes red and the others black
# Ideally, I would like to select multiple nodes from the given node set to be colored red
def hv_graph(color_these_nodes):
    # set up the graph
    color_these_nodes = list(color_these_nodes)
    node_indices = np.arange(3, dtype=np.int32)
    source = np.zeros(3, dtype=np.int32)
    target = node_indices

    # color all given nodes
    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 in color_these_nodes:  # color the chosen node red
            node_colors.append("red")
        else:
            node_colors.append("black")  # color all other nodes with any other color

    # create 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)).opts(node_color="color")
    return graph


all_nodes = pn.widgets.MultiSelect(options=[0, 1, 2], name="Node(s)")


h = pn.bind(hv_graph, color_these_nodes=all_nodes)
layout = pn.Column(all_nodes, h).servable()
1 Like

@Marc Thanks, that’s what I was looking for :slight_smile:
I can see from your picture that your solution works, but unfortunately mine doesn’t because It doesn’t respond to the selected values.

Maybe its because I saved the result into an html file. I used layout.save("result.html", embed =True) to save the application.
Is that wrong? Should I use another command to save the result? I’ve also tried it with multiple browsers, but the same problem arises.

1 Like

Hi @optmat

When you save you will get a snapshot of what the application looks like with one set of selected values.

Normally you would have to run the app on a server with panel serve to get interactivity. There are some ways to get around it.

  • Embedding. Works if your widgets don’t have a lot of different combinations.
  • PyScript. Python in the browser. Works for some use cases and if your use case can afford a longer initial loading time.
1 Like

Thanks again @Marc, I think I get the idea. I’ve tried to use .embed(), but I’m still not quite sure yet how to add it in my example to get a workable html file (or something similar). Could you maybe help me out again?