Vertical & horizontal alignment of divs & figures

I’m wondering how one can align some figures vertically while at same time a div is aligned in center of each figure?

import numpy as np
from bokeh.io import curdoc
from bokeh.layouts import column, row, layout, grid
from bokeh.models import ColumnDataSource, Div
from bokeh.plotting import figure

x = np.array([0,1,2,3,4])
y1 = np.array([0,1,2,3,4])
y2 = y1*10
y3 = y2*10

src = ColumnDataSource(data={"x": x, "y1": y1, "y2": y2, "y3": y3})

p1 = figure(sizing_mode="stretch_both")
p1.line(x="x", y="y1", source=src)
p2 = figure(sizing_mode="stretch_both")
p2.line(x="x", y="y2", source=src)
p3 = figure(sizing_mode="stretch_both")
p3.line(x="x", y="y3", source=src)

div1 = Div(text="""Div 1""", align="center")
div2 = Div(text="""Div 10""", align="center")
div3 = Div(text="""Div 100""", align="center")

app_layout = column(
    row(div1, p1, sizing_mode="stretch_both"),
    row(div2, p2, sizing_mode="stretch_both"),
    row(div3, p3, sizing_mode="stretch_both"),
    sizing_mode="stretch_both",
)

curdoc().add_root(app_layout)

You’ll need to make the Div all be the same width, but also you have axis labels of different lengths. If you are expecting the y-axis rules to also line up you will need to take care of that, too. There are a few options:

  • set min_border_left on all the plots to force the same minumum space for every label (choose a value big enough for the longest label on any plot)
  • rotate the y-axis ticks so that they always take up the same amount of space horizontally (i.e. the height of of the font)
  • move the axis to the right side

This worked for me:

p1 = figure(sizing_mode="stretch_both", min_border_left=80)
p1.line(x="x", y="y1", source=src)
p2 = figure(sizing_mode="stretch_both", min_border_left=80)
p2.line(x="x", y="y2", source=src)
p3 = figure(sizing_mode="stretch_both", min_border_left=80)
p3.line(x="x", y="y3", source=src)

div1 = Div(text="""Div 1""", align="center", width=50)
div2 = Div(text="""Div 10""", align="center", width=50)
div3 = Div(text="""Div 100""", align="center", width=50)