or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

chart-composition.mdchart-creation.mdconfiguration-theming.mddata-handling.mdencodings-channels.mdexpressions-conditions.mdindex.mdparameters-interactions.mdrendering-output.mdtransformations.md

chart-composition.mddocs/

0

# Chart Composition

1

2

Functions for combining multiple charts through layering, concatenation, faceting, and repetition to create complex multi-view visualizations. Chart composition enables building sophisticated dashboards and analytical displays from simpler chart components.

3

4

## Capabilities

5

6

### Layering

7

8

Functions for overlaying multiple charts with different marks or encodings on the same coordinate system.

9

10

```python { .api }

11

def layer(*charts, **kwargs):

12

"""

13

Layer multiple charts on top of each other.

14

15

Parameters:

16

- *charts: Variable number of Chart objects to layer

17

- **kwargs: Additional layer properties (resolve, etc.)

18

19

Returns:

20

LayerChart: Layered chart specification

21

"""

22

23

class LayerChart:

24

def __init__(self, layer=None, **kwargs):

25

"""

26

Chart with multiple layered mark specifications.

27

28

Parameters:

29

- layer: List of layer specifications

30

"""

31

32

def resolve_axis(self, **kwargs):

33

"""Resolve axis sharing across layers."""

34

35

def resolve_legend(self, **kwargs):

36

"""Resolve legend sharing across layers."""

37

38

def resolve_scale(self, **kwargs):

39

"""Resolve scale sharing across layers."""

40

```

41

42

### Concatenation

43

44

Functions for arranging charts side-by-side or in grids without sharing coordinate systems.

45

46

```python { .api }

47

def concat(*charts, columns=None, spacing=None, **kwargs):

48

"""

49

Concatenate charts in a flexible layout.

50

51

Parameters:

52

- *charts: Variable number of Chart objects

53

- columns: Number of columns for grid layout

54

- spacing: Spacing between charts

55

56

Returns:

57

ConcatChart: Concatenated chart specification

58

"""

59

60

def hconcat(*charts, spacing=None, **kwargs):

61

"""

62

Horizontally concatenate charts.

63

64

Parameters:

65

- *charts: Variable number of Chart objects

66

- spacing: Horizontal spacing between charts

67

68

Returns:

69

HConcatChart: Horizontally concatenated chart

70

"""

71

72

def vconcat(*charts, spacing=None, **kwargs):

73

"""

74

Vertically concatenate charts.

75

76

Parameters:

77

- *charts: Variable number of Chart objects

78

- spacing: Vertical spacing between charts

79

80

Returns:

81

VConcatChart: Vertically concatenated chart

82

"""

83

84

class ConcatChart:

85

def __init__(self, concat=None, columns=None, **kwargs):

86

"""General concatenated chart layout."""

87

88

class HConcatChart:

89

def __init__(self, hconcat=None, **kwargs):

90

"""Horizontally concatenated chart layout."""

91

92

class VConcatChart:

93

def __init__(self, vconcat=None, **kwargs):

94

"""Vertically concatenated chart layout."""

95

```

96

97

### Faceting

98

99

Functions for creating small multiples based on data dimensions.

100

101

```python { .api }

102

def facet(

103

chart,

104

facet=None,

105

columns=None,

106

spacing=None,

107

**kwargs

108

):

109

"""

110

Create faceted chart with small multiples.

111

112

Parameters:

113

- chart: Base chart specification

114

- facet: Faceting field specification

115

- columns: Number of columns in facet grid

116

- spacing: Spacing between facet panels

117

118

Returns:

119

FacetChart: Faceted chart specification

120

"""

121

122

class FacetChart:

123

def __init__(self, facet=None, spec=None, **kwargs):

124

"""

125

Chart with faceted small multiples.

126

127

Parameters:

128

- facet: Facet field specification

129

- spec: Base chart specification for each panel

130

"""

131

```

132

133

### Repetition

134

135

Functions for repeating chart specifications with different field mappings.

136

137

```python { .api }

138

def repeat(

139

chart=None,

140

repeat=None,

141

columns=None,

142

**kwargs

143

):

144

"""

145

Repeat chart specification with different field mappings.

146

147

Parameters:

148

- chart: Base chart template

149

- repeat: Repeat specification (row/column field lists)

150

- columns: Number of columns for repeat grid

151

152

Returns:

153

RepeatChart: Repeated chart specification

154

"""

155

156

class RepeatChart:

157

def __init__(self, repeat=None, spec=None, **kwargs):

158

"""

159

Chart with repeated specifications.

160

161

Parameters:

162

- repeat: Repeat field mappings

163

- spec: Template chart specification

164

"""

165

```

166

167

### Resolution Control

168

169

Classes and methods for controlling how scales, axes, and legends are shared across composed charts.

170

171

```python { .api }

172

class Resolve:

173

def __init__(self, axis=None, legend=None, scale=None):

174

"""

175

Resolution specification for composed charts.

176

177

Parameters:

178

- axis: Axis resolution configuration

179

- legend: Legend resolution configuration

180

- scale: Scale resolution configuration

181

"""

182

183

class AxisResolveMap:

184

def __init__(self, x=None, y=None, **kwargs):

185

"""Axis resolution for specific encodings."""

186

187

class LegendResolveMap:

188

def __init__(self, color=None, size=None, shape=None, **kwargs):

189

"""Legend resolution for specific encodings."""

190

191

class ScaleResolveMap:

192

def __init__(self, x=None, y=None, color=None, size=None, **kwargs):

193

"""Scale resolution for specific encodings."""

194

195

# Resolution modes

196

ResolveMode = Union['independent', 'shared']

197

```

198

199

## Usage Examples

200

201

### Basic Layering

202

203

```python

204

import altair as alt

205

206

# Layer line and points

207

line = alt.Chart(data).mark_line().encode(

208

x='x:Q',

209

y='mean(y):Q'

210

)

211

212

points = alt.Chart(data).mark_circle().encode(

213

x='x:Q',

214

y='y:Q',

215

color='category:N'

216

)

217

218

layered = alt.layer(line, points).resolve_scale(

219

color='independent'

220

)

221

```

222

223

### Horizontal Concatenation

224

225

```python

226

# Side-by-side charts

227

chart1 = alt.Chart(data).mark_bar().encode(

228

x='category:N',

229

y='count():Q'

230

)

231

232

chart2 = alt.Chart(data).mark_point().encode(

233

x='x:Q',

234

y='y:Q',

235

color='category:N'

236

)

237

238

combined = alt.hconcat(chart1, chart2, spacing=20)

239

```

240

241

### Vertical Concatenation

242

243

```python

244

# Stacked charts

245

top_chart = alt.Chart(data).mark_line().encode(

246

x='date:T',

247

y='value:Q'

248

).properties(height=200)

249

250

bottom_chart = alt.Chart(data).mark_bar().encode(

251

x='date:T',

252

y='volume:Q'

253

).properties(height=100)

254

255

stacked = alt.vconcat(top_chart, bottom_chart)

256

```

257

258

### Grid Layout with Concat

259

260

```python

261

# 2x2 grid of charts

262

chart1 = alt.Chart(data).mark_point().encode(x='a:Q', y='b:Q')

263

chart2 = alt.Chart(data).mark_point().encode(x='c:Q', y='d:Q')

264

chart3 = alt.Chart(data).mark_bar().encode(x='category:N', y='count():Q')

265

chart4 = alt.Chart(data).mark_line().encode(x='date:T', y='value:Q')

266

267

grid = alt.concat(

268

chart1, chart2, chart3, chart4,

269

columns=2,

270

spacing=10

271

)

272

```

273

274

### Faceted Small Multiples

275

276

```python

277

# Facet by category

278

base = alt.Chart(data).mark_point().encode(

279

x='x:Q',

280

y='y:Q'

281

)

282

283

faceted = base.facet(

284

column=alt.Column('category:N', header=alt.Header(title='Category')),

285

columns=3

286

)

287

288

# Facet with both row and column

289

faceted_2d = base.facet(

290

column=alt.Column('category:N'),

291

row=alt.Row('type:N'),

292

spacing=10

293

)

294

```

295

296

### Repeat Chart

297

298

```python

299

# Scatterplot matrix

300

scatter_matrix = alt.Chart(data).mark_circle().encode(

301

x=alt.X(alt.repeat('column'), type='quantitative'),

302

y=alt.Y(alt.repeat('row'), type='quantitative'),

303

color='species:N'

304

).properties(

305

width=150,

306

height=150

307

).repeat(

308

row=['petalLength', 'petalWidth'],

309

column=['sepalLength', 'sepalWidth']

310

)

311

```

312

313

### Complex Dashboard Layout

314

315

```python

316

# Multi-panel dashboard

317

base = alt.Chart(data)

318

319

# Time series

320

time_series = base.mark_line().encode(

321

x='date:T',

322

y='value:Q',

323

color='category:N'

324

).properties(width=400, height=200)

325

326

# Bar chart

327

bars = base.mark_bar().encode(

328

x='category:N',

329

y='mean(value):Q'

330

).properties(width=150, height=200)

331

332

# Scatter plot

333

scatter = base.mark_circle().encode(

334

x='x:Q',

335

y='y:Q',

336

size='value:Q',

337

color='category:N'

338

).properties(width=200, height=200)

339

340

# Histogram

341

hist = base.mark_bar().encode(

342

x=alt.X('value:Q', bin=True),

343

y='count()'

344

).properties(width=200, height=200)

345

346

# Compose dashboard

347

dashboard = alt.vconcat(

348

time_series,

349

alt.hconcat(bars, scatter, hist, spacing=10),

350

spacing=15

351

)

352

```

353

354

### Layered Chart with Brushing

355

356

```python

357

# Base chart with brush selection

358

brush = alt.selection_interval()

359

360

base = alt.Chart(data).add_selection(brush)

361

362

# Background points

363

background = base.mark_circle(

364

color='lightgray',

365

opacity=0.5

366

).encode(

367

x='x:Q',

368

y='y:Q'

369

)

370

371

# Highlighted points

372

highlighted = base.mark_circle().encode(

373

x='x:Q',

374

y='y:Q',

375

color=alt.condition(brush, 'category:N', alt.value('lightgray'))

376

)

377

378

# Regression line for selected data

379

regression = base.mark_line(

380

color='red',

381

size=3

382

).transform_filter(

383

brush

384

).transform_regression('y', 'x')

385

386

layered_interactive = alt.layer(

387

background, highlighted, regression

388

)

389

```

390

391

### Resolution Control

392

393

```python

394

# Independent scales for layered charts

395

chart1 = alt.Chart(data1).mark_bar().encode(

396

x='category:N',

397

y='value1:Q'

398

)

399

400

chart2 = alt.Chart(data2).mark_line().encode(

401

x='category:N',

402

y='value2:Q'

403

)

404

405

# Allow independent y-scales

406

layered = alt.layer(chart1, chart2).resolve_scale(

407

y='independent'

408

).resolve_axis(

409

y='independent'

410

)

411

412

# Shared color legend

413

multi_chart = alt.hconcat(

414

chart1, chart2

415

).resolve_legend(

416

color='shared'

417

)

418

```

419

420

## Types

421

422

```python { .api }

423

from typing import Union, List, Dict, Any, Optional

424

425

# Chart composition types

426

ComposedChart = Union[LayerChart, ConcatChart, HConcatChart, VConcatChart, FacetChart, RepeatChart]

427

428

# Layout specifications

429

LayoutAlign = Union['all', 'each', 'none']

430

Spacing = Union[int, Dict[str, int]]

431

432

# Repeat specifications

433

RepeatMapping = Dict[str, List[str]]

434

RepeatRef = Dict[str, str]

435

436

# Facet specifications

437

FacetMapping = Union[str, Dict[str, Any]]

438

FacetFieldDef = Dict[str, Any]

439

440

# Resolution specifications

441

ResolveMode = Union['independent', 'shared']

442

443

class ResolveConfig:

444

axis: Optional[Dict[str, ResolveMode]] = None

445

legend: Optional[Dict[str, ResolveMode]] = None

446

scale: Optional[Dict[str, ResolveMode]] = None

447

448

# Layout configuration

449

class CompositionConfig:

450

columns: Optional[int] = None

451

spacing: Optional[Spacing] = None

452

align: Optional[LayoutAlign] = None

453

bounds: Optional[Union['full', 'flush']] = None

454

center: Optional[bool] = None

455

```