0
# Configuration & Theming
1
2
Theme system and configuration options for customizing chart appearance, including axis styling, color schemes, and layout properties. Altair provides comprehensive theming capabilities for consistent visual styling across visualizations.
3
4
## Capabilities
5
6
### Theme Registry
7
8
Central registry system for managing and applying themes to customize default chart appearance.
9
10
```python { .api }
11
class ThemeRegistry:
12
def enable(self, name, **kwargs):
13
"""
14
Enable a theme by name.
15
16
Parameters:
17
- name: Theme name ('default', 'dark', 'excel', 'ggplot2', 'quartz', 'vox', 'fivethirtyeight', 'latimes', 'urbaninstitute', 'googlecharts')
18
- **kwargs: Theme-specific options
19
"""
20
21
def register(self, name, theme_func, enable=False):
22
"""
23
Register a new theme function.
24
25
Parameters:
26
- name: Theme name
27
- theme_func: Function returning theme configuration
28
- enable: Whether to enable immediately
29
"""
30
31
def get(self):
32
"""Get current active theme configuration."""
33
34
@property
35
def active(self):
36
"""Get name of active theme."""
37
38
def names(self):
39
"""Get list of available theme names."""
40
41
# Global theme registry
42
theme = ThemeRegistry()
43
```
44
45
### Top-Level Configuration
46
47
Main configuration class that controls overall chart appearance and behavior.
48
49
```python { .api }
50
class Config:
51
def __init__(
52
self,
53
arc=None,
54
area=None,
55
axis=None,
56
axisBand=None,
57
axisBottom=None,
58
axisDiscrete=None,
59
axisLeft=None,
60
axisPoint=None,
61
axisQuantitative=None,
62
axisRight=None,
63
axisTemporal=None,
64
axisTop=None,
65
axisX=None,
66
axisXBand=None,
67
axisXDiscrete=None,
68
axisXPoint=None,
69
axisXQuantitative=None,
70
axisXTemporal=None,
71
axisY=None,
72
axisYBand=None,
73
axisYDiscrete=None,
74
axisYPoint=None,
75
axisYQuantitative=None,
76
axisYTemporal=None,
77
background=None,
78
bar=None,
79
boxplot=None,
80
circle=None,
81
concat=None,
82
countTitle=None,
83
customFormatTypes=None,
84
errorband=None,
85
errorbar=None,
86
facet=None,
87
fieldTitle=None,
88
font=None,
89
fontSize=None,
90
geoshape=None,
91
header=None,
92
image=None,
93
legend=None,
94
line=None,
95
lineBreak=None,
96
mark=None,
97
numberFormat=None,
98
padding=None,
99
params=None,
100
point=None,
101
projection=None,
102
range=None,
103
rect=None,
104
rule=None,
105
scale=None,
106
selection=None,
107
square=None,
108
style=None,
109
text=None,
110
tick=None,
111
timeFormat=None,
112
title=None,
113
trail=None,
114
view=None,
115
**kwargs
116
):
117
"""
118
Top-level configuration for chart appearance and behavior.
119
120
Parameters include configuration objects for all chart components.
121
"""
122
```
123
124
### Axis Configuration
125
126
Configuration classes for customizing axis appearance and behavior.
127
128
```python { .api }
129
class AxisConfig:
130
def __init__(
131
self,
132
aria=None,
133
bandPosition=None,
134
description=None,
135
domain=None,
136
domainCap=None,
137
domainColor=None,
138
domainDash=None,
139
domainDashOffset=None,
140
domainOpacity=None,
141
domainWidth=None,
142
format=None,
143
formatType=None,
144
grid=None,
145
gridCap=None,
146
gridColor=None,
147
gridDash=None,
148
gridDashOffset=None,
149
gridOpacity=None,
150
gridWidth=None,
151
labelAlign=None,
152
labelAngle=None,
153
labelBaseline=None,
154
labelBound=None,
155
labelColor=None,
156
labelExpr=None,
157
labelFlush=None,
158
labelFlushOffset=None,
159
labelFont=None,
160
labelFontSize=None,
161
labelFontStyle=None,
162
labelFontWeight=None,
163
labelLimit=None,
164
labelLineHeight=None,
165
labelOffset=None,
166
labelOpacity=None,
167
labelOverlap=None,
168
labelPadding=None,
169
labelSeparation=None,
170
labels=None,
171
maxExtent=None,
172
minExtent=None,
173
offset=None,
174
orient=None,
175
style=None,
176
tickBand=None,
177
tickCap=None,
178
tickColor=None,
179
tickCount=None,
180
tickDash=None,
181
tickDashOffset=None,
182
tickExtra=None,
183
tickMinStep=None,
184
tickOffset=None,
185
tickOpacity=None,
186
tickRound=None,
187
tickSize=None,
188
tickWidth=None,
189
ticks=None,
190
title=None,
191
titleAlign=None,
192
titleAnchor=None,
193
titleAngle=None,
194
titleBaseline=None,
195
titleColor=None,
196
titleFont=None,
197
titleFontSize=None,
198
titleFontStyle=None,
199
titleFontWeight=None,
200
titleLimit=None,
201
titleLineHeight=None,
202
titleOpacity=None,
203
titlePadding=None,
204
titleX=None,
205
titleY=None,
206
translate=None,
207
values=None,
208
zindex=None,
209
**kwargs
210
):
211
"""Axis styling and behavior configuration."""
212
```
213
214
### Legend Configuration
215
216
Configuration for legend appearance and layout.
217
218
```python { .api }
219
class LegendConfig:
220
def __init__(
221
self,
222
aria=None,
223
clipHeight=None,
224
columnPadding=None,
225
columns=None,
226
cornerRadius=None,
227
description=None,
228
direction=None,
229
disable=None,
230
fillColor=None,
231
gradientDirection=None,
232
gradientHorizontalMaxLength=None,
233
gradientHorizontalMinLength=None,
234
gradientLength=None,
235
gradientOpacity=None,
236
gradientStrokeColor=None,
237
gradientStrokeWidth=None,
238
gradientThickness=None,
239
gradientVerticalMaxLength=None,
240
gradientVerticalMinLength=None,
241
gridAlign=None,
242
labelAlign=None,
243
labelBaseline=None,
244
labelColor=None,
245
labelFont=None,
246
labelFontSize=None,
247
labelFontStyle=None,
248
labelFontWeight=None,
249
labelLimit=None,
250
labelOffset=None,
251
labelOpacity=None,
252
labelOverlap=None,
253
labelPadding=None,
254
labelSeparation=None,
255
layout=None,
256
legendX=None,
257
legendY=None,
258
offset=None,
259
orient=None,
260
padding=None,
261
rowPadding=None,
262
strokeColor=None,
263
strokeDash=None,
264
strokeWidth=None,
265
symbolBaseFillColor=None,
266
symbolBaseStrokeColor=None,
267
symbolDash=None,
268
symbolDashOffset=None,
269
symbolDirection=None,
270
symbolFillColor=None,
271
symbolLimit=None,
272
symbolOffset=None,
273
symbolOpacity=None,
274
symbolSize=None,
275
symbolStrokeColor=None,
276
symbolStrokeWidth=None,
277
symbolType=None,
278
title=None,
279
titleAlign=None,
280
titleAnchor=None,
281
titleBaseline=None,
282
titleColor=None,
283
titleFont=None,
284
titleFontSize=None,
285
titleFontStyle=None,
286
titleFontWeight=None,
287
titleLimit=None,
288
titleLineHeight=None,
289
titleOpacity=None,
290
titleOrient=None,
291
titlePadding=None,
292
unselectedOpacity=None,
293
zindex=None,
294
**kwargs
295
):
296
"""Legend styling and layout configuration."""
297
```
298
299
### Scale Configuration
300
301
Default configuration for scales across different data types.
302
303
```python { .api }
304
class ScaleConfig:
305
def __init__(
306
self,
307
bandPaddingInner=None,
308
bandPaddingOuter=None,
309
bandWithNestedOffsetPaddingInner=None,
310
bandWithNestedOffsetPaddingOuter=None,
311
barBandPaddingInner=None,
312
clamp=None,
313
continuousPadding=None,
314
discretePadding=None,
315
invalid=None,
316
maxBandSize=None,
317
maxFontSize=None,
318
maxOpacity=None,
319
maxSize=None,
320
maxStrokeWidth=None,
321
minBandSize=None,
322
minFontSize=None,
323
minOpacity=None,
324
minSize=None,
325
minStrokeWidth=None,
326
pointPadding=None,
327
rectBandPaddingInner=None,
328
round=None,
329
textXRangeStep=None,
330
useUnaggregatedDomain=None,
331
xReversed=None,
332
**kwargs
333
):
334
"""Default scale configuration for different data types."""
335
```
336
337
### View Configuration
338
339
Configuration for chart view properties like dimensions and styling.
340
341
```python { .api }
342
class ViewConfig:
343
def __init__(
344
self,
345
continuousHeight=None,
346
continuousWidth=None,
347
cornerRadius=None,
348
cursor=None,
349
discreteHeight=None,
350
discreteWidth=None,
351
fill=None,
352
fillOpacity=None,
353
opacity=None,
354
step=None,
355
stroke=None,
356
strokeCap=None,
357
strokeDash=None,
358
strokeDashOffset=None,
359
strokeJoin=None,
360
strokeMiterLimit=None,
361
strokeOpacity=None,
362
strokeWidth=None,
363
**kwargs
364
):
365
"""Chart view styling and dimensions configuration."""
366
```
367
368
### Title Configuration
369
370
Configuration for chart titles and text elements.
371
372
```python { .api }
373
class TitleConfig:
374
def __init__(
375
self,
376
align=None,
377
anchor=None,
378
angle=None,
379
aria=None,
380
baseline=None,
381
color=None,
382
dx=None,
383
dy=None,
384
font=None,
385
fontSize=None,
386
fontStyle=None,
387
fontWeight=None,
388
frame=None,
389
limit=None,
390
lineHeight=None,
391
offset=None,
392
opacity=None,
393
orient=None,
394
style=None,
395
subtitleColor=None,
396
subtitleFont=None,
397
subtitleFontSize=None,
398
subtitleFontStyle=None,
399
subtitleFontWeight=None,
400
subtitleLineHeight=None,
401
subtitlePadding=None,
402
zindex=None,
403
**kwargs
404
):
405
"""Title and subtitle styling configuration."""
406
```
407
408
### Mark Configuration
409
410
Configuration classes for different mark types.
411
412
```python { .api }
413
class MarkConfig:
414
def __init__(
415
self,
416
align=None,
417
angle=None,
418
aria=None,
419
ariaRole=None,
420
ariaRoleDescription=None,
421
aspect=None,
422
baseline=None,
423
binSpacing=None,
424
blend=None,
425
color=None,
426
continuousBandSize=None,
427
cornerRadius=None,
428
cornerRadiusBottomLeft=None,
429
cornerRadiusBottomRight=None,
430
cornerRadiusEnd=None,
431
cornerRadiusTopLeft=None,
432
cornerRadiusTopRight=None,
433
cursor=None,
434
description=None,
435
dir=None,
436
discreteBandSize=None,
437
dx=None,
438
dy=None,
439
ellipsis=None,
440
fill=None,
441
fillOpacity=None,
442
filled=None,
443
font=None,
444
fontSize=None,
445
fontStyle=None,
446
fontWeight=None,
447
height=None,
448
href=None,
449
innerRadius=None,
450
interpolate=None,
451
invalid=None,
452
limit=None,
453
lineBreak=None,
454
lineHeight=None,
455
opacity=None,
456
order=None,
457
orient=None,
458
outerRadius=None,
459
padAngle=None,
460
radius=None,
461
radius2=None,
462
shape=None,
463
size=None,
464
smooth=None,
465
stroke=None,
466
strokeCap=None,
467
strokeDash=None,
468
strokeDashOffset=None,
469
strokeJoin=None,
470
strokeMiterLimit=None,
471
strokeOffset=None,
472
strokeOpacity=None,
473
strokeWidth=None,
474
style=None,
475
tension=None,
476
text=None,
477
theta=None,
478
theta2=None,
479
thickness=None,
480
timeUnitBandPosition=None,
481
timeUnitBandSize=None,
482
tooltip=None,
483
url=None,
484
width=None,
485
x=None,
486
x2=None,
487
xOffset=None,
488
y=None,
489
y2=None,
490
yOffset=None,
491
**kwargs
492
):
493
"""General mark styling configuration."""
494
495
# Specific mark configurations
496
class AreaConfig(MarkConfig): ...
497
class BarConfig(MarkConfig): ...
498
class LineConfig(MarkConfig): ...
499
class PointConfig(MarkConfig): ...
500
class RectConfig(MarkConfig): ...
501
class TextConfig(MarkConfig): ...
502
class TickConfig(MarkConfig): ...
503
class CircleConfig(MarkConfig): ...
504
class SquareConfig(MarkConfig): ...
505
class RuleConfig(MarkConfig): ...
506
class TrailConfig(MarkConfig): ...
507
class ArcConfig(MarkConfig): ...
508
class ImageConfig(MarkConfig): ...
509
class GeoshapeConfig(MarkConfig): ...
510
511
# Composite mark configurations
512
class BoxPlotConfig(MarkConfig): ...
513
class ErrorBarConfig(MarkConfig): ...
514
class ErrorBandConfig(MarkConfig): ...
515
```
516
517
## Usage Examples
518
519
### Theme Usage
520
521
```python
522
import altair as alt
523
524
# Enable built-in themes
525
alt.theme.enable('dark')
526
alt.theme.enable('ggplot2')
527
alt.theme.enable('quartz')
528
alt.theme.enable('vox')
529
alt.theme.enable('fivethirtyeight')
530
531
# Check available themes
532
print(alt.theme.names())
533
534
# Get current theme
535
print(alt.theme.active)
536
```
537
538
### Custom Theme Creation
539
540
```python
541
# Define custom theme function
542
def custom_theme():
543
return {
544
'config': {
545
'view': {'continuousWidth': 600, 'continuousHeight': 400},
546
'axis': {
547
'labelFontSize': 12,
548
'titleFontSize': 14,
549
'gridColor': '#E0E0E0'
550
},
551
'legend': {
552
'labelFontSize': 11,
553
'titleFontSize': 12
554
},
555
'mark': {'color': '#1f77b4'},
556
'title': {'fontSize': 16, 'color': '#333333'}
557
}
558
}
559
560
# Register and enable custom theme
561
alt.theme.register('custom', custom_theme)
562
alt.theme.enable('custom')
563
```
564
565
### Chart-Specific Configuration
566
567
```python
568
# Configure individual chart
569
chart = alt.Chart(data).mark_circle().encode(
570
x='x:Q',
571
y='y:Q'
572
).configure_axis(
573
gridColor='lightgray',
574
labelFontSize=12
575
).configure_legend(
576
orient='bottom',
577
titleFontSize=14
578
).configure_mark(
579
opacity=0.7
580
).configure_title(
581
fontSize=18,
582
color='darkblue'
583
)
584
```
585
586
### Axis Customization
587
588
```python
589
# Custom axis styling
590
chart = alt.Chart(data).mark_point().encode(
591
x=alt.X('x:Q', axis=alt.Axis(
592
title='X Axis Title',
593
titleFontSize=14,
594
titleColor='blue',
595
labelAngle=-45,
596
labelColor='gray',
597
grid=True,
598
gridColor='lightgray',
599
gridOpacity=0.5
600
)),
601
y=alt.Y('y:Q', axis=alt.Axis(
602
title='Y Axis Title',
603
titleFontSize=14,
604
format='.2f',
605
tickCount=5
606
))
607
)
608
```
609
610
### Legend Customization
611
612
```python
613
# Custom legend styling
614
chart = alt.Chart(data).mark_circle().encode(
615
x='x:Q',
616
y='y:Q',
617
color=alt.Color('category:N', legend=alt.Legend(
618
title='Categories',
619
titleFontSize=14,
620
labelFontSize=12,
621
orient='right',
622
offset=10,
623
symbolSize=100,
624
symbolStrokeWidth=2
625
))
626
)
627
```
628
629
### Scale Configuration
630
631
```python
632
# Custom scale defaults
633
chart = alt.Chart(data).mark_bar().encode(
634
x='category:N',
635
y='value:Q'
636
).configure_scale(
637
bandPaddingInner=0.2,
638
continuousPadding=10
639
).configure_axisX(
640
labelAngle=0,
641
labelPadding=5
642
)
643
```
644
645
### Mark Styling
646
647
```python
648
# Global mark configuration
649
chart = alt.Chart(data).mark_circle().encode(
650
x='x:Q',
651
y='y:Q',
652
color='category:N'
653
).configure_mark(
654
opacity=0.8,
655
stroke='white',
656
strokeWidth=1
657
).configure_circle(
658
size=60
659
)
660
```
661
662
### View Configuration
663
664
```python
665
# Chart view styling
666
chart = alt.Chart(data).mark_point().encode(
667
x='x:Q',
668
y='y:Q'
669
).configure_view(
670
stroke='black',
671
strokeWidth=2,
672
fill='lightgray',
673
continuousWidth=500,
674
continuousHeight=400
675
)
676
```
677
678
### Complete Theme Configuration
679
680
```python
681
# Comprehensive theme setup
682
def publication_theme():
683
return {
684
'config': {
685
'background': 'white',
686
'view': {
687
'continuousWidth': 500,
688
'continuousHeight': 400,
689
'stroke': 'transparent'
690
},
691
'axis': {
692
'domain': False,
693
'grid': True,
694
'gridColor': '#EEEEEE',
695
'gridWidth': 1,
696
'labelColor': '#666666',
697
'labelFontSize': 10,
698
'labelFont': 'Arial',
699
'titleColor': '#333333',
700
'titleFontSize': 12,
701
'titleFont': 'Arial',
702
'titleFontWeight': 'bold'
703
},
704
'legend': {
705
'labelColor': '#666666',
706
'labelFontSize': 10,
707
'titleColor': '#333333',
708
'titleFontSize': 11,
709
'titleFontWeight': 'bold',
710
'symbolStrokeWidth': 0,
711
'symbolSize': 80
712
},
713
'mark': {
714
'color': '#2E86AB',
715
'stroke': '#2E86AB',
716
'strokeWidth': 1.5
717
},
718
'title': {
719
'color': '#333333',
720
'fontSize': 14,
721
'fontWeight': 'bold',
722
'font': 'Arial'
723
}
724
}
725
}
726
727
alt.theme.register('publication', publication_theme, enable=True)
728
```
729
730
## Types
731
732
```python { .api }
733
from typing import Union, Dict, Any, Optional, List
734
735
# Theme function type
736
ThemeFunction = Callable[[], Dict[str, Any]]
737
738
# Configuration types
739
ConfigDict = Dict[str, Any]
740
741
# Font specifications
742
FontSpec = Union[str, Dict[str, Any]]
743
FontWeight = Union['normal', 'bold', 'lighter', 'bolder', int]
744
FontStyle = Union['normal', 'italic', 'oblique']
745
746
# Color specifications
747
ColorSpec = Union[str, Dict[str, Any]]
748
749
# Size and spacing
750
SizeSpec = Union[int, float]
751
SpacingSpec = Union[int, float, Dict[str, Union[int, float]]]
752
753
# Alignment specifications
754
TextAlign = Union['left', 'center', 'right']
755
TextBaseline = Union['alphabetic', 'top', 'middle', 'bottom', 'line-top', 'line-bottom']
756
757
# Orientation specifications
758
Orient = Union['left', 'right', 'top', 'bottom']
759
LegendOrient = Union['left', 'right', 'top', 'bottom', 'top-left', 'top-right', 'bottom-left', 'bottom-right', 'none']
760
761
# Title anchor
762
TitleAnchor = Union['start', 'middle', 'end']
763
```