Advanced Styling Reference#
Complete reference for all advanced styling and configuration options in visualkeras.
This page documents the powerful but less-commonly-used customization features available across all visualization modes.
Overview#
The options system in visualkeras supports:
Grouped highlights: Visually group related layers with backgrounds and labels
Logos and brand elements: Add logos and create legend entries
Per-layer styling: Customize individual layers with fine-grained control
Image embedding: Embed custom images or textures in visualizations
Text callables: Control what text appears in visualizations
Dimension configuration: Fine-tune how tensor shapes are displayed
All features are accessed through options objects and the styles parameter.
Grouped Highlights (layered_groups)#
Group related layers with colored backgrounds and labels.
Purpose#
Use grouped highlights to:
Visually separate architectural components (e.g., “Feature Extraction”, “Classification”)
Highlight specific stages of processing
Create visual hierarchy in complex models
Make diagrams easier to understand at a glance
Basic Syntax#
Groups are defined via the layered_groups parameter in LayeredOptions:
from visualkeras.options import LayeredOptions
import visualkeras
options = LayeredOptions(
layered_groups=[
{
'name': 'Feature Extraction',
'type': 'block',
'indices': [0, 1, 2, 3], # Layer indices to group
'fill': '#e8f4f8', # Background color
'outline': '#4a90e2', # Border color
},
{
'name': 'Classification',
'type': 'block',
'indices': [4, 5, 6],
'fill': '#f8e8e8', # Different color
'outline': '#e24a4a',
}
]
)
image = visualkeras.show(model, mode='layered', options=options)
image.show()
Parameter Details#
Each group definition is a dictionary with:
Parameter |
Type |
Description |
|---|---|---|
|
str |
Label for the group (displayed above the block) |
|
str |
Must be |
|
list/tuple |
Layer indices to include in the group (0-indexed from model.layers) |
|
color |
Background fill color (hex string like |
|
color |
Border color around the group |
Practical Example: ResNet-style Model#
model = keras.Sequential([
# Input/preprocessing layers
keras.layers.Input(shape=(224, 224, 3)),
keras.layers.Conv2D(64, (7, 7), padding='same'),
keras.layers.BatchNormalization(),
keras.layers.ReLU(),
keras.layers.MaxPooling2D((3, 3)),
# Feature extraction block
keras.layers.Conv2D(128, (3, 3), padding='same'),
keras.layers.BatchNormalization(),
keras.layers.ReLU(),
keras.layers.Conv2D(128, (3, 3), padding='same'),
# Classification block
keras.layers.GlobalAveragePooling2D(),
keras.layers.Dense(256),
keras.layers.ReLU(),
keras.layers.Dense(10, activation='softmax'),
])
options = LayeredOptions(
layered_groups=[
{
'name': 'Input & Preprocessing',
'type': 'block',
'indices': [0, 1, 2, 3, 4],
'fill': '#e3f2fd', # Blue
'outline': '#1976d2',
},
{
'name': 'Feature Extraction',
'type': 'block',
'indices': [5, 6, 7, 8],
'fill': '#f3e5f5', # Purple
'outline': '#7b1fa2',
},
{
'name': 'Classification Head',
'type': 'block',
'indices': [9, 10, 11, 12],
'fill': '#e8f5e9', # Green
'outline': '#388e3c',
}
]
)
image = visualkeras.show(model, mode='layered', options=options, preset='presentation')
image.show()
Logos and Branding (logo_groups, logos_legend)#
Add logos and create visual legends for your diagrams.
Purpose#
Use logos to:
Add company or institutional branding
Create visual legends explaining color coding
Add informational graphics
Improve publication figures
Basic Logo Syntax#
Define logos via the logo_groups and logos_legend parameters:
from visualkeras.options import LayeredOptions
options = LayeredOptions(
logo_groups=[
{
'indices': [0, 1, 2], # Layers to label
'fill': '#3498db', # Color
'outline': '#2980b9', # Border
'text': 'Conv Block 1', # Logo/label text
}
],
logos_legend=True # Show legend explaining logos
)
image = visualkeras.show(model, mode='layered', options=options)
image.show()
Logo Parameter Details#
Parameter |
Type |
Description |
|---|---|---|
|
str |
Text label for the logo |
|
list/tuple |
Layer indices to apply this logo to |
|
color |
Background color for logo |
|
color |
Border color for logo |
|
str |
When to show: |
logos_legendcan be:True/Falseto enable/disable legendA dict with legend customization options
Per-Layer Styling (styles Parameter)#
Fine-grained control over individual layers.
Purpose#
Use per-layer styling to:
Customize specific layers differently from others
Embed images in particular layers
Apply layer-specific colors or effects
Create highly customized publication figures
Basic Syntax#
Styles are passed via the styles parameter in LayeredOptions:
from visualkeras.options import LayeredOptions
import visualkeras
styles = {
0: { # Layer 0 (by index)
'fill': '#1f77b4',
'outline': '#0d47a1',
},
'conv_1': { # Layer by name
'fill': '#ff7f0e',
'outline': '#d84315',
},
keras.layers.Dense: { # By layer type (applies to all Dense layers)
'fill': '#2ca02c',
'outline': '#1b5e20',
}
}
options = LayeredOptions(styles=styles)
image = visualkeras.show(model, mode='layered', options=options)
image.show()
Style Keys Reference#
Available style parameters per layer:
Key |
Type |
Description |
|---|---|---|
|
color |
Layer background/fill color |
|
color |
Layer border color |
|
int |
Border thickness in pixels |
|
str |
Custom text to display in or for the layer |
Image Embedding (face_image)#
Embed custom images or textures in layer visualizations (LeNet mode).
Purpose#
Use image embedding to:
Show kernel visualizations
Display activation maps
Add custom graphics to layers
Create distinctive, publication-quality diagrams
Basic Syntax (LeNet Mode)#
from visualkeras.options import LenetOptions
styles = {
0: { # Layer 0
'face_image': '/path/to/kernel_viz.png',
'face_image_fit': 'cover', # How to fit image
'face_image_alpha': 200, # Transparency (0-255)
'face_image_inset': 2, # Border inset in pixels
}
}
options = LenetOptions(styles=styles)
image = visualkeras.show(model, mode='lenet', options=options)
image.show()
Image Options Reference#
Key |
Type |
Description |
|---|---|---|
|
path/str |
Path to an image file or a |
|
str |
Fit mode: |
|
int |
Transparency from 0 (transparent) to 255 (opaque) |
|
int |
Border inset in pixels |
Fit Mode Behavior#
'cover': Fill entire space, crop image if necessary'contain': Fit entire image, may have empty space (letterboxing)'fill': Stretch to fill (may distort)'stretch': Same as'fill''scale-down': Use largest fitting size without upscaling
Image-Fitting Options (image_axis, image_fit)#
Control how images are displayed in layered visualizations.
Purpose#
These options control global image behavior in layered mode:
from visualkeras.options import LayeredOptions
options = LayeredOptions(
image_axis='z', # Which axis represents image depth (batch processing)
image_fit='fill', # How to fit images in layer blocks
)
ImageAxis Options#
Axis |
Description |
|---|---|
|
Image axis along width |
|
Image axis along height |
|
Image axis along depth/channels (default) |
ImageFit Options#
Same options as face_image_fit: 'cover', 'contain', 'fill', 'stretch', 'scale-down'
Text Callables and Labels#
Customize what text appears in visualizations.
Using Built-in Callables#
from visualkeras.options import LAYERED_TEXT_CALLABLES, LayeredOptions
import visualkeras
# Use a built-in text callable
options = LayeredOptions(
text_callable=LAYERED_TEXT_CALLABLES['name_shape']
)
image = visualkeras.show(model, mode='layered', options=options)
image.show()
- Available built-in callables:
'name'- Layer name only'type'- Layer type/class name'shape'- Output tensor shape'name_shape'- Both name and shape (recommended for presentation)
Custom Text Callables#
Define your own text function:
from visualkeras.options import LayeredOptions
def custom_label(layer_index, layer):
"""Return (text_string, is_above_layer)"""
name = layer.__class__.__name__
output_shape = layer.output_shape if hasattr(layer, 'output_shape') else 'unknown'
text = f"{name}\n{output_shape}"
above = False # Show below the layer
return (text, above)
options = LayeredOptions(
text_callable=custom_label
)
image = visualkeras.show(model, mode='layered', options=options)
image.show()
LeNet Label Callables#
LeNet mode has special label callables:
from visualkeras.options import LenetOptions
def top_info(layer, render_shape):
"""Text above each layer"""
return f"{render_shape.dH}×{render_shape.dW}×{render_shape.dZ}" # h x w x channels
def bottom_info(layer, render_shape):
"""Text below each layer"""
return layer.__class__.__name__
options = LenetOptions(
top_label_callable=top_info,
bottom_label_callable=bottom_info,
)
image = visualkeras.show(model, mode='lenet', options=options)
image.show()
RenderShape Properties (for LeNet)#
When using label callables in LeNet mode, the RenderShape object provides:
Attr |
Description |
|---|---|
|
Height of the feature-map visualization in pixels |
|
Width of the feature-map visualization in pixels |
|
Number of channels (depth) |
Dimension Display Options#
Control how tensor dimensions are shown.
ShowDimension#
Enable dimension display on layers:
from visualkeras.options import LayeredOptions
options = LayeredOptions(
show_dimension=True, # Show tensor shapes on layers
dimension_caps=None, # Custom dimension display
)
image = visualkeras.show(model, mode='layered', options=options)
image.show()
DimensionCaps#
Limit dimension display formatting:
options = LayeredOptions(
show_dimension=True,
dimension_caps={
'max_width': 100, # Max characters for width display
'max_height': 100, # Max characters for height display
'decimal_places': 2, # Decimal precision
}
)
SizingMode Strategies#
Control how layer sizes are calculated.
Available Modes#
Mode |
Description |
|---|---|
|
Use actual tensor dimensions (default and most precise) |
|
Balance readability with accuracy |
|
Use logarithmic scaling to handle a large range of sizes |
|
Scale relative to a base size controlled by |
Example#
from visualkeras.options import LayeredOptions
# Logarithmic scaling for models with extreme size variations
options = LayeredOptions(
sizing_mode='logarithmic',
relative_base_size=20, # Reference size for relative mode
)
image = visualkeras.show(model, mode='layered', options=options)
image.show()
Complete Advanced Example#
Combining multiple advanced features:
from visualkeras.options import LayeredOptions, LAYERED_TEXT_CALLABLES
import visualkeras
# Define advanced options
options = LayeredOptions(
# Layout
spacing=20,
padding=30,
# Styling
background_fill='white',
font_color='black',
# Groups
layered_groups=[
{
'name': 'Feature Extraction',
'type': 'block',
'indices': [0, 1, 2, 3],
'fill': '#e3f2fd',
'outline': '#1976d2',
},
{
'name': 'Dense Classifier',
'type': 'block',
'indices': [4, 5, 6],
'fill': '#e8f5e9',
'outline': '#388e3c',
}
],
# Per-layer styling
styles={
keras.layers.Conv2D: {'fill': '#1976d2'},
keras.layers.Dense: {'fill': '#388e3c'},
},
# Text
text_callable=LAYERED_TEXT_CALLABLES['name_shape'],
# Dimensions
show_dimension=True,
sizing_mode='balanced',
# Legends
legend=True,
logos_legend=True,
)
image = visualkeras.show(
model,
mode='layered',
options=options,
preset='presentation'
)
image.save('advanced_diagram.png')
Tips and Best Practices#
Start with presets: Begin with
preset='presentation'and customize from thereUse grouped highlights: Improve readability of complex models with visual grouping
Test fit modes: Try different
image_fitvalues to find what looks bestCombine overlays: Use colors + groups + text for clearest communication
Save high-DPI: For publication, save PNG with sufficient resolution
Limit complexity: Too many style customizations can make diagrams harder to parse