☰Read-only archive⌕
Looking for help with Bokeh?

This is a read-only archive. Ask questions and join the conversation on GitHub.

Visit Community Support on GitHub →
Archived discussions · Captured October 28, 2026

Bokeh tap to enlarger a plot within a grid of plot

Community Supportbokeh
Bobokeh
Bobokeh

Hello,
I am trying to create a general function that would help me plot a grid of figures (rgb images in the future), and when I click on a specific figure of the grid it would enlarge it and set it in front of the screen, if I then would double click (or a leave button) it would return to the grid. I can accomplish that using matplolib but with the new jupyter version it cannot be done on the notebook itself. So far I have only been able to do the following:

from bokeh.io import output_notebook, show
from bokeh import events
from bokeh.layouts import gridplot, column, layout
from bokeh.plotting import figure
from bokeh.models import CustomJS

output_notebook()

import numpy as np

def create_random_image():
    return np.random.rand(150, 150)

images = [create_random_image() for _ in range(4)]

plots = []
for i, image in enumerate(images):
    p = figure(title=f'Image {i+1}', tools='tap')
    p.image(image=[image], x=0, y=0, dw=10, dh=10, palette="Greys256")
    p.axis.visible = False
    p.grid.visible = False
    p.width = image.shape[0]
    p.height = image.shape[1]
    p.toolbar.logo = None  
    plots.append(p)

enlarge = CustomJS(args=dict(plots=plots), code="""
    for (let i = 0; i < plots.length; i++) {
        let p = plots[i];
        // Reset all plots to their original size
        p.width = 2 * p.width;
        p.height = 2 * p.height;
    }
""")

enlarge_bis = CustomJS(args=dict(plots=plots), code="""
    // Enlarge the clicked plot
    const selected_plot = cb_obj;
    show(selected_plot)
    selected_plot.width = 2 * selected_plot.width;
    selected_plot.height = 2 * selected_plot.height;""")

for plot in plots:
    plot.js_on_event(events.DoubleTap, enlarge)

grid = gridplot([[plots[0], plots[1]], [plots[2], plots[3]]])

show(grid)

when I double click it doubles the width and height of every figures. I have tried to enlarge the clicked plot only but nothing happends when I try it. How much wrong am I?

⌁   Link to post
Bryan
Bryan

show is only a Python API function, it cannot be called from JS code (i.e. from CustomJS callbacks) so that is never going to work. Additionally changing the size of one plot inside a grid layout is going to affect the entire existing layout, which you also probably do not want.

To be honest, I am not really sure that there is a good or simple way to achieve what you are looking for. I’d encourage you to open a GitHub Issue to start a discussion about how something like this might be supported by future development. Other core devs might also chime in with any potential workarounds I haven’t thought of. But in the immediate term, you might need to consider other libraries if this is a hard requirement.

⌁   Link to post
nmasnadi
nmasnadi

This is not exactly what you want but might get you closer to your goal:

from bokeh.io import output_notebook, show
from bokeh import events
from bokeh.layouts import gridplot, column, layout, row
from bokeh.plotting import figure
from bokeh.models import CustomJS, ColumnDataSource

output_notebook()

import numpy as np

def create_random_image():
    return np.random.rand(150, 150)

images = [create_random_image() for _ in range(4)]
sources = {}

plots = []
for i, image in enumerate(images):
    p = figure(title=f'Image {i+1}', tools='tap')
    p.image(image=[image], x=0, y=0, dw=10, dh=10, palette="Greys256")
    p.axis.visible = False
    p.grid.visible = False
    p.width = image.shape[0]
    p.height = image.shape[1]
    p.toolbar.logo = None  
    plots.append(p)
    sources[f'Image {i+1}'] = ColumnDataSource(
        data={
            'image': [image],
            'x': [0],
            'y': [0],
            'dw': [10],
            'dh': [10],
        }
    )

source_main = ColumnDataSource(
    data={
        'image': [images[0]],
        'x': [0],
        'y': [0],
        'dw': [10],
        'dh': [10],
    }
)

main_plot = figure(width=2*image.shape[0], height=2*image.shape[1], title='Image 1')
main_plot.image(image='image', x='x', y='y', dh='dh', dw='dw', palette="Greys256", source=source_main)
main_plot.axis.visible = False
main_plot.grid.visible = False
main_plot.toolbar.logo = None

enlarge = CustomJS(
    args=dict(sources=sources, source_main=source_main, main_plot=main_plot),
    code="""
    const selected_plot = cb_obj.origin.title.text;
    console.log(main_plot.title.text)
    main_plot.title.text = selected_plot
    source_main.data = sources[selected_plot].data    
    """
)

for plot in plots:
    plot.js_on_event(events.Tap, enlarge)

grid = row([
    column([
        row(plots[0], plots[1]),
        row(plots[2], plots[3]),
    ]),
    row(main_plot)]
)

show(grid)

⌁   Link to post

End of archived discussion · Replies are disabled