Skip to content

Add support for side panel layouts and SizeBar annotation - #14487

Merged
mattpap merged 42 commits into
branch-3.8from
mattpap/14323_side_panel_layouts
Aug 17, 2025
Merged

mattpap merged 42 commits into
branch-3.8from
mattpap/14323_side_panel_layouts

Conversation

@mattpap

@mattpap mattpap commented May 14, 2025 •

Copy link
Copy Markdown
Contributor

This is a very preliminary implementation of generic layouts in Plot's side and center panels. This will also allow to support layouts of annotations (Legend, ColorBar). This is a prerequisite for resolving issue #2603. This will eventually allow to simplify ColorBar's implementation.

Screencast.from.2025-05-14.15-40-57.webm
Code
import numpy as np
from typing import Any

from bokeh.layouts import column
from bokeh.plotting import figure, show

TOOLS="hover,crosshair,pan,wheel_zoom,zoom_in,zoom_out,box_zoom,undo,redo,reset,tap,save,box_select,poly_select,lasso_select,examine,fullscreen,help"

def f(b: int, **args: Any):
    N = 4000
    x = np.random.random(size=N) * 100
    y = np.random.random(size=N) * 100
    radii = np.random.random(size=N) * 1.5
    colors = np.array([(r, g, b) for r, g in zip(50+2*x, 30+2*y)], dtype=np.uint8)
    p = figure(**args)
    p.circle(x, y, radius=radii, fill_color=colors, fill_alpha=0.6, line_color=None)
    return p

p = f(b=50, tools=TOOLS)

p1 = f(b=125, width=200, height=200, tools="pan,wheel_zoom,box_select,hover", toolbar_location="above")
p2 = f(b=250, width=200, height=200, tools="pan,wheel_zoom,box_select,hover", toolbar_location="above")

p.add_layout(column([p1, p2]), "right")

show(p)

image

@mattpap mattpap added this to the 3.8 milestone May 14, 2025
@mattpap
mattpap force-pushed the mattpap/14323_side_panel_layouts branch from c1828af to a88513a Compare June 18, 2025 13:03
@mattpap
mattpap force-pushed the mattpap/14323_side_panel_layouts branch from a88513a to 9709d81 Compare June 25, 2025 22:33
@mattpap mattpap changed the title Add support for layouts in Plot's side panels Add support for side panel layouts and SizeBar annotation Jun 25, 2025
@mattpap

mattpap commented Jun 25, 2025 •

Copy link
Copy Markdown
Contributor Author

TODO:

  • actually resolve type errors in plot_canvas.ts
  • implement has_size_changed() in SizeBar (otherwise the component may overflow plot's layout temporarily)

@mattpap
mattpap force-pushed the mattpap/14323_side_panel_layouts branch from 9709d81 to 5b0fd30 Compare June 26, 2025 06:02
@droumis

droumis commented Jul 8, 2025

Copy link
Copy Markdown
Member

Is this nearly ready for review?

@mattpap

mattpap commented Jul 11, 2025

Copy link
Copy Markdown
Contributor Author

@droumis, it's pretty close. I will make it reviewable by Monday.

@mattpap
mattpap force-pushed the mattpap/14323_side_panel_layouts branch from 5b0fd30 to a79c46d Compare July 15, 2025 12:10

@philippjfr philippjfr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation looks fine to me. Main comment I have is about the missing documentation.

@mattpap
mattpap force-pushed the mattpap/14323_side_panel_layouts branch from a79c46d to 8d296d3 Compare July 27, 2025 23:27
@mattpap

mattpap commented Jul 29, 2025

Copy link
Copy Markdown
Contributor Author

This is tentatively ready. I'm still polishing some rough edges though.

@mattpap
mattpap force-pushed the mattpap/14323_side_panel_layouts branch from ebce5a6 to e7a48c2 Compare July 29, 2025 16:06
@droumis
droumis requested a review from philippjfr July 29, 2025 16:26
Comment thread bokehjs/src/lib/models/annotations/size_bar.ts Outdated
@mattpap
mattpap force-pushed the mattpap/14323_side_panel_layouts branch 2 times, most recently from 53311f3 to 364cb99 Compare August 6, 2025 00:19
Comment thread src/bokeh/models/annotations/legends.py Outdated
@mattpap
mattpap force-pushed the mattpap/14323_side_panel_layouts branch from 364cb99 to a76a4a8 Compare August 6, 2025 13:18
@Azaya89

Azaya89 commented Aug 6, 2025

Copy link
Copy Markdown
Member

I pushed some doc improvements.

I also tried running the example in examples/basic/annotations/size_bar.py but I got a blank canvas with this error in the console:

Error: could not resolve type 'SizeBar', which could be due to a widget or a custom model not being registered before first usage

Dependencies

Python version        :  3.13.5 | packaged by conda-forge | (main, Jun 16 2025, 08:24:05) [Clang 18.1.8 ]
IPython version       :  9.4.0
Tornado version       :  6.5.1
NumPy version         :  2.3.2
Bokeh version         :  3.8.0.dev3+10.ga47e3ac6
BokehJS static path   :  /Users/*/bokeh/src/bokeh/server/static
node.js version       :  v20.19.4
npm version           :  11.5.2
jupyter_bokeh version :  (not installed)
Operating system      :  macOS-15.0-arm64-arm-64bit-Mach-O

@mattpap

mattpap commented Aug 7, 2025

Copy link
Copy Markdown
Contributor Author

Error: could not resolve type 'SizeBar', which could be due to a widget or a custom model not being registered before first usage

Either you didn't build bokehjs correctly or incorrect version of bokehjs is being used by the example (e.g. you will need to run examples under devtools with caching disabled). For now I can refer you to https://docs.bokeh.org/en/latest/docs/dev_guide/setup.html, be we can also set up a session to go through bokeh's dev setup.

@mattpap mattpap mentioned this pull request Aug 7, 2025
1 of 3 tasks
@Azaya89

Azaya89 commented Aug 7, 2025

Copy link
Copy Markdown
Member

Either you didn't build bokehjs correctly or incorrect version of bokehjs is being used by the example (e.g. you will need to run examples under devtools with caching disabled). For now I can refer you to https://docs.bokeh.org/en/latest/docs/dev_guide/setup.html, be we can also set up a session to go through bokeh's dev setup.

I used a fresh set-up before running the example and I've tried disabling cache in the browser but still a blank page. I'm open to setting up a session to go through my setup. Maybe I'm missing something...

@mattpap
mattpap force-pushed the mattpap/14323_side_panel_layouts branch from 682d4e7 to 2185959 Compare August 9, 2025 07:06

@hoxbro hoxbro left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have left some comments.


I have a big concern, which is that the sizebar is only valid in the initial rendering; if I zoom in/out, the size does not update to match the actual size in the plot.

I'm also not sure how it would work when you set a radius_dimension=min on the circle glyph, and the axes are different scales. Though I haven't given it a go yet.

A smaller concern is, I actually want to have a border around the size bar, but I don't think it is a blocker.


Some bugs I also discovered when playing around with it:

  1. If you zoom in on the webpage, the sizebar disappears:
Screencast.From.2025-08-11.11-44-29.mp4
  1. It is not shown when saving the plot:
bokeh_plot

Comment thread bokehjs/src/lib/models/annotations/size_bar.ts
Comment thread bokehjs/src/lib/models/annotations/size_bar.ts Outdated
Comment thread bokehjs/src/lib/models/annotations/size_bar.ts
Comment thread bokehjs/src/lib/models/annotations/size_bar.ts Outdated
Comment thread src/bokeh/models/plots.py Outdated
Comment thread src/bokeh/models/plots.pyi Outdated
Comment thread bokehjs/src/lib/models/annotations/size_bar.ts Outdated
Comment thread bokehjs/src/lib/models/annotations/size_bar.ts Outdated
@mattpap

mattpap commented Aug 11, 2025

Copy link
Copy Markdown
Contributor Author

I have a big concern, which is that the sizebar is only valid in the initial rendering; if I zoom in/out, the size does not update to match the actual size in the plot.

I'm working on this, though a solution causes other issues.

@mattpap
mattpap force-pushed the mattpap/14323_side_panel_layouts branch from a003d31 to 21a2978 Compare August 17, 2025 21:43
@mattpap
mattpap merged commit 63b24fc into branch-3.8 Aug 17, 2025
@mattpap
mattpap deleted the mattpap/14323_side_panel_layouts branch August 17, 2025 23:30
@hoxbro

hoxbro commented Aug 18, 2025

Copy link
Copy Markdown
Contributor

They are, or maybe I don't understand this point.

I'm talking about these lines, which, as I read them, will not respect the user input, e.g., if bounds[0] is smaller than the smallest radius, likewise if bounds[1] is larger than the largest radius.

const r_min = Math.max(uniforms.min(glyph_view.radius), bounds[0])
const r_max = Math.min(uniforms.max(glyph_view.radius), bounds[1])

Use e.g. (10, float("+inf")) in Python or [10, Infinity] in JS/TS. "auto" keyword expands to [-Infinity, Infinity].

Not the most elegant way to do it, but OK.

Saving the image still does not work, [...], and we should open an issue for now.

Can you open an issue for this?

@github-actions

Copy link
Copy Markdown

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Nov 26, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow to place layouts in Plot's side and center panels Add a SizeBar guide to label relative scatter glyph sizes

6 participants