How to display a FloatPanel on button click?

panel==1.0.0rc8
bokeh>=3.1.1,<3.2.0
holoviews>=1.16.0a2

Good evening,
Someone knows how to display a FloatPanel on button click within the same data app? I would like to show an histogram using a FloatPanel window.

Example:

This is what i’ve tested so far in my data APP:

You can find the full code of the data APP here:
s2-panel-app

1 Like

Can you share a minimal, reproducible example (MRE) of what you are doing in your big script?

In general, a complete script can be copied/pasted and immediately run as-is with no modifications and should not be larger than 30 lines.

1 Like

Here is a small example of what I am trying to do:

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

pn.extension()


def plot_image(image_size):
    """
    A function that plots a randomly generated image
    and assigns it to the panel state cache.
    """

    # Generate some random data
    rand_image = np.random.normal(0, 1, size=(image_size, image_size))

    # Assign the array to the panel state cache
    pn.state.cache["image"] = rand_image

    return hv.Image(rand_image).opts(cmap="Reds")


def plot_hist(event):
    """
    TODO: Show the histogram of the image in a FloatPanel on button click.
    """

    # Calculate the histogram of the image
    frequencies, edges = np.histogram(pn.state.cache["image"])

    # Plot the histogram
    hist_plot = hv.Histogram((edges, frequencies))

    # Embed the histogram in a FloatPanel
    floatpanel = pn.layout.FloatPanel(hist_plot, margin=20)

    # How to show this dialog on button click?
    return pn.Column(floatpanel, width=400, height=400)


# Image size slider
size_slider = pn.widgets.IntSlider(name="Image size", start=50, end=200, step=1)

# Bind the slider to the image plot
image_bind = pn.bind(plot_image, image_size=size_slider)

# Histogram button
show_floatpanel_bt = pn.widgets.Button(name="Show Histogram")
show_floatpanel_bt.on_click(plot_hist)

# Create the dashboard and turn into a deployable application
pn.template.FastListTemplate(
    main=[pn.Column(image_bind, size_slider, show_floatpanel_bt)]
).servable()

I would use a placeholder like this:


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

pn.extension("floatpanel")
hv.renderer("bokeh").webgl = False


def plot_image(image_size):
    """
    A function that plots a randomly generated image
    and assigns it to the panel state cache.
    """

    # Generate some random data
    rand_image = np.random.normal(0, 1, size=(image_size, image_size))

    # Assign the array to the panel state cache
    pn.state.cache["image"] = rand_image

    return hv.Image(rand_image).opts(cmap="Reds")


def plot_hist(event):
    """
    TODO: Show the histogram of the image in a FloatPanel on button click.
    """

    # Calculate the histogram of the image
    frequencies, edges = np.histogram(pn.state.cache["image"])

    # Plot the histogram
    hist_plot = hv.Histogram((edges, frequencies))

    # Embed the histogram in a FloatPanel
    floatpanel = pn.layout.FloatPanel(hist_plot, margin=20)

    # How to show this dialog on button click?
    placeholder[:] = [floatpanel]


placeholder = pn.Column(height=0, width=0)

# Image size slider
size_slider = pn.widgets.IntSlider(name="Image size", start=50, end=200, step=1)

# Bind the slider to the image plot
image_bind = pn.bind(plot_image, image_size=size_slider)

# Histogram button
show_floatpanel_bt = pn.widgets.Button(name="Show Histogram")
show_floatpanel_bt.on_click(plot_hist)

# Create the dashboard and turn into a deployable application
pn.template.FastListTemplate(
    main=[pn.Column(placeholder, image_bind, size_slider, show_floatpanel_bt)],
).servable()

4 Likes

Thanks @Hoxbro! Now it works!!! :+1:

I made only a small change to the code by setting the “contained” option to False:

# Embed the histogram in a FloatPanel
floatpanel = pn.layout.FloatPanel(hist_plot, contained=False, position="center")
1 Like