or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

client-server.mdcolors-transforms.mdcommand-line.mddocument-management.mdembedding-integration.mdevents-interactivity.mdindex.mdio-operations.mdlayouts.mdmodels-data-sources.mdplotting-interface.mdserver-applications.mdwidgets.md

layouts.mddocs/

0

# Layouts

1

2

Functions and classes for arranging multiple plots, widgets, and other components into complex layouts. The layout system enables creation of dashboards, multi-panel displays, and sophisticated interactive applications with precise control over component positioning and sizing.

3

4

## Capabilities

5

6

### Basic Layout Functions

7

8

Core functions for arranging components horizontally and vertically.

9

10

```python { .api }

11

def row(*children, **kwargs):

12

"""

13

Arrange plots/widgets horizontally in a row.

14

15

Parameters:

16

- children: Plot objects, widgets, or other layoutable components

17

- sizing_mode: 'fixed', 'stretch_width', 'stretch_height', 'stretch_both', 'scale_width', 'scale_height', 'scale_both'

18

- width: Total width in pixels (when sizing_mode='fixed')

19

- height: Total height in pixels (when sizing_mode='fixed')

20

- margin: Margin around the layout (int or tuple)

21

- spacing: Spacing between children in pixels

22

- css_classes: List of CSS class names

23

- name: Optional name for the layout

24

- tags: List of arbitrary values for user annotation

25

26

Returns:

27

Row: Layout object containing the arranged components

28

"""

29

30

def column(*children, **kwargs):

31

"""

32

Arrange plots/widgets vertically in a column.

33

34

Parameters:

35

- children: Plot objects, widgets, or other layoutable components

36

- sizing_mode: Layout sizing behavior

37

- width: Total width in pixels

38

- height: Total height in pixels

39

- margin: Margin around the layout

40

- spacing: Spacing between children in pixels

41

- css_classes: List of CSS class names

42

- name: Optional name for the layout

43

- tags: List of arbitrary values

44

45

Returns:

46

Column: Layout object containing the arranged components

47

"""

48

```

49

50

### Grid Layouts

51

52

Functions for creating grid-based arrangements of plots and components.

53

54

```python { .api }

55

def gridplot(children, sizing_mode='fixed', toolbar_location='above',

56

ncols=None, plot_width=None, plot_height=None,

57

toolbar_options=None, merge_tools=True, **kwargs):

58

"""

59

Create grid of plots with optional shared tools.

60

61

Parameters:

62

- children: 2D list/array of plot objects (None for empty cells)

63

- sizing_mode: Layout sizing behavior

64

- toolbar_location: 'above', 'below', 'left', 'right', None

65

- ncols: Number of columns (if children is 1D list)

66

- plot_width: Width for plots without explicit width

67

- plot_height: Height for plots without explicit height

68

- toolbar_options: Dict of toolbar configuration options

69

- merge_tools: Whether to merge plot tools into shared toolbar

70

71

Returns:

72

GridBox: Grid layout containing the plots

73

74

Example children format:

75

[[plot1, plot2], [plot3, None]] # 2x2 grid with empty bottom-right

76

"""

77

78

def grid(children, sizing_mode='fixed', **kwargs):

79

"""

80

Create flexible grid layout without plot-specific features.

81

82

Parameters:

83

- children: 2D list of any layoutable components

84

- sizing_mode: Layout sizing behavior

85

86

Returns:

87

GridBox: Grid layout containing the components

88

"""

89

```

90

91

### Advanced Layout Function

92

93

Function for creating complex nested layouts.

94

95

```python { .api }

96

def layout(children, sizing_mode='fixed', **kwargs):

97

"""

98

Create flexible nested layout from lists and tuples.

99

100

Parameters:

101

- children: Nested structure of lists/tuples containing components

102

Lists create columns, tuples create rows

103

- sizing_mode: Layout sizing behavior

104

105

Returns:

106

LayoutDOM: Appropriate layout object based on structure

107

108

Examples:

109

layout([plot1, plot2]) # Column of two plots

110

layout([[plot1, plot2]]) # Row of two plots

111

layout([plot1, [plot2, plot3]]) # plot1 above horizontal row

112

"""

113

```

114

115

### Layout Model Classes

116

117

Classes for programmatic layout construction and advanced configuration.

118

119

```python { .api }

120

class LayoutDOM(Model):

121

"""Base class for all layout components."""

122

width: Optional[int]

123

height: Optional[int]

124

min_width: Optional[int]

125

min_height: Optional[int]

126

max_width: Optional[int]

127

max_height: Optional[int]

128

margin: Margin # int or (top, right, bottom, left) tuple

129

width_policy: SizingPolicy # 'auto', 'min', 'fit', 'max'

130

height_policy: SizingPolicy

131

aspect_ratio: Optional[Union[float, str]] # float or 'auto'

132

sizing_mode: SizingMode

133

visible: bool

134

disabled: bool

135

css_classes: List[str]

136

name: Optional[str]

137

tags: List[Any]

138

139

class Row(LayoutDOM):

140

"""Horizontal arrangement of components."""

141

children: List[LayoutDOM]

142

spacing: int # Spacing between children in pixels

143

144

class Column(LayoutDOM):

145

"""Vertical arrangement of components."""

146

children: List[LayoutDOM]

147

spacing: int

148

149

class GridBox(LayoutDOM):

150

"""Grid arrangement of components."""

151

children: List[Tuple[LayoutDOM, int, int]] # (component, row, col)

152

nrows: int

153

ncols: int

154

spacing: Union[int, Tuple[int, int]] # (row_spacing, col_spacing)

155

156

class Spacer(LayoutDOM):

157

"""Empty space component for layouts."""

158

# Inherits all sizing properties from LayoutDOM

159

# Used to create flexible spacing in layouts

160

```

161

162

### Tabbed Layouts

163

164

Classes for creating tabbed interfaces.

165

166

```python { .api }

167

class Panel(Model):

168

"""Individual tab panel."""

169

child: LayoutDOM # Content of the tab

170

title: str # Tab title text

171

closable: bool # Whether tab can be closed

172

173

class Tabs(LayoutDOM):

174

"""Tabbed layout container."""

175

tabs: List[Panel]

176

active: int # Index of active tab

177

tabs_location: Location # 'above', 'below', 'left', 'right'

178

179

# Callback hooks

180

def on_change(self, attr, *callbacks): ...

181

```

182

183

## Usage Examples

184

185

### Basic Row and Column Layouts

186

187

```python

188

from bokeh.layouts import row, column

189

from bokeh.plotting import figure, show

190

import numpy as np

191

192

# Create some plots

193

x = np.linspace(0, 4*np.pi, 100)

194

195

p1 = figure(width=300, height=300, title="sin(x)")

196

p1.line(x, np.sin(x))

197

198

p2 = figure(width=300, height=300, title="cos(x)")

199

p2.line(x, np.cos(x), color='red')

200

201

p3 = figure(width=300, height=300, title="tan(x)")

202

p3.line(x, np.tan(x), color='green')

203

204

# Arrange in row

205

layout1 = row(p1, p2, p3)

206

207

# Arrange in column

208

layout2 = column(p1, p2, p3)

209

210

# Mixed arrangement

211

layout3 = column(

212

row(p1, p2), # Top row with two plots

213

p3 # Bottom plot spanning full width

214

)

215

216

show(layout3)

217

```

218

219

### Grid Layout

220

221

```python

222

from bokeh.layouts import gridplot

223

from bokeh.plotting import figure, show

224

import numpy as np

225

226

# Create 2x2 grid of plots

227

plots = []

228

for i in range(4):

229

p = figure(width=250, height=250, title=f"Plot {i+1}")

230

x = np.linspace(0, 4*np.pi, 50)

231

y = np.sin(x + i*np.pi/4)

232

p.line(x, y, line_width=2)

233

plots.append(p)

234

235

# Arrange in 2x2 grid

236

grid = gridplot([

237

[plots[0], plots[1]],

238

[plots[2], plots[3]]

239

], sizing_mode='stretch_width')

240

241

show(grid)

242

```

243

244

### Flexible Layout with Spacers

245

246

```python

247

from bokeh.layouts import column, row

248

from bokeh.models import Spacer

249

from bokeh.plotting import figure, show

250

251

p1 = figure(width=200, height=200)

252

p1.circle([1, 2, 3], [1, 2, 3])

253

254

p2 = figure(width=200, height=200)

255

p2.square([1, 2, 3], [3, 2, 1])

256

257

# Create layout with flexible spacing

258

layout = column(

259

p1,

260

Spacer(height=50), # Fixed 50px spacing

261

row(

262

Spacer(width_policy='max'), # Flexible left space

263

p2,

264

Spacer(width_policy='max') # Flexible right space (centers p2)

265

)

266

)

267

268

show(layout)

269

```

270

271

### Tabbed Interface

272

273

```python

274

from bokeh.models import Panel, Tabs

275

from bokeh.plotting import figure, show

276

import numpy as np

277

278

# Create plots for different tabs

279

tab1_plot = figure(width=400, height=400, title="Line Plot")

280

x = np.linspace(0, 4*np.pi, 100)

281

tab1_plot.line(x, np.sin(x))

282

283

tab2_plot = figure(width=400, height=400, title="Scatter Plot")

284

tab2_plot.scatter(np.random.random(50), np.random.random(50), size=10)

285

286

tab3_plot = figure(width=400, height=400, title="Bar Chart")

287

categories = ['A', 'B', 'C', 'D']

288

values = [1, 3, 2, 4]

289

tab3_plot.vbar(x=categories, top=values, width=0.5)

290

291

# Create tabs

292

tab1 = Panel(child=tab1_plot, title="Sine Wave")

293

tab2 = Panel(child=tab2_plot, title="Random Data")

294

tab3 = Panel(child=tab3_plot, title="Categories")

295

296

tabs = Tabs(tabs=[tab1, tab2, tab3])

297

298

show(tabs)

299

```

300

301

### Responsive Dashboard Layout

302

303

```python

304

from bokeh.layouts import column, row

305

from bokeh.plotting import figure, show

306

from bokeh.models import Div

307

import numpy as np

308

309

# Create title

310

title = Div(text="<h1>Sales Dashboard</h1>",

311

sizing_mode='stretch_width')

312

313

# Create plots with responsive sizing

314

p1 = figure(height=300, title="Revenue Trend",

315

sizing_mode='stretch_width')

316

months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']

317

revenue = [100, 120, 140, 110, 160, 180]

318

p1.line(range(len(months)), revenue, line_width=3)

319

p1.xaxis.ticker = list(range(len(months)))

320

p1.xaxis.major_label_overrides = dict(zip(range(len(months)), months))

321

322

p2 = figure(width=300, height=300, title="Regional Sales")

323

regions = ['North', 'South', 'East', 'West']

324

sales = [45, 30, 35, 25]

325

p2.vbar(x=regions, top=sales, width=0.5, color='navy')

326

327

p3 = figure(width=300, height=300, title="Customer Satisfaction")

328

satisfaction = np.random.normal(8.5, 1.2, 1000)

329

hist, edges = np.histogram(satisfaction, bins=20)

330

p3.quad(top=hist, bottom=0, left=edges[:-1], right=edges[1:],

331

fill_color='lightblue', line_color='black')

332

333

# Create responsive layout

334

dashboard = column(

335

title,

336

p1, # Full width trend chart

337

row(p2, p3, sizing_mode='stretch_width'), # Side-by-side bottom charts

338

sizing_mode='stretch_width'

339

)

340

341

show(dashboard)

342

```

343

344

### Programmatic Layout Construction

345

346

```python

347

from bokeh.models import Column, Row, GridBox

348

from bokeh.plotting import figure, show

349

350

# Create plots

351

plots = []

352

for i in range(6):

353

p = figure(width=200, height=200, title=f"Plot {i+1}")

354

p.circle([1, 2, 3], [i, i+1, i+2])

355

plots.append(p)

356

357

# Programmatically create complex layout

358

main_row = Row(children=[

359

Column(children=plots[0:3], spacing=10),

360

Column(children=plots[3:6], spacing=10)

361

], spacing=20)

362

363

# Alternative: Using GridBox for precise control

364

grid = GridBox(children=[

365

(plots[0], 0, 0), (plots[1], 0, 1), (plots[2], 0, 2),

366

(plots[3], 1, 0), (plots[4], 1, 1), (plots[5], 1, 2)

367

], nrows=2, ncols=3, spacing=15)

368

369

show(grid)

370

```