0
# Visualization System
1
2
DOT language generation with customizable themes, color schemes, and graph styling for creating publication-quality profiler visualizations. The visualization system converts parsed profile data into GraphViz DOT format with intelligent color-coding to highlight performance hotspots.
3
4
## Capabilities
5
6
### DOT Graph Generation
7
8
Main class responsible for converting profile data into GraphViz DOT language format with customizable styling and theming.
9
10
```python { .api }
11
class DotWriter:
12
def __init__(self, fp):
13
"""
14
Initialize DOT writer.
15
16
Args:
17
fp: File-like object to write DOT output
18
"""
19
20
def graph(self, profile, theme):
21
"""
22
Generate complete DOT graph from profile data.
23
24
Args:
25
profile (Profile): Parsed profile data
26
theme (Theme): Color theme for visualization
27
"""
28
29
def node(self, node, **attrs):
30
"""
31
Generate DOT node definition.
32
33
Args:
34
node: Node identifier
35
**attrs: DOT attributes for the node
36
"""
37
38
def edge(self, src, dst, **attrs):
39
"""
40
Generate DOT edge definition.
41
42
Args:
43
src: Source node identifier
44
dst: Destination node identifier
45
**attrs: DOT attributes for the edge
46
"""
47
48
def begin_graph(self):
49
"""Begin DOT graph definition."""
50
51
def end_graph(self):
52
"""End DOT graph definition."""
53
```
54
55
### Theme System
56
57
Customizable color themes that map performance metrics to visual properties like colors, line weights, and node sizes.
58
59
```python { .api }
60
class Theme:
61
def __init__(self, bgcolor=(0.0, 0.0, 1.0), mincolor=(0.0, 0.0, 0.0), maxcolor=(0.0, 0.0, 1.0),
62
fontname="Arial", fontcolor="white", nodestyle="filled",
63
minfontsize=10.0, maxfontsize=10.0, minpenwidth=0.5, maxpenwidth=4.0,
64
gamma=2.2, skew=1.0):
65
"""
66
Initialize visualization theme.
67
68
Args:
69
bgcolor (tuple): Background color HSL values (0.0-1.0)
70
mincolor (tuple): Color for minimum values HSL (0.0-1.0)
71
maxcolor (tuple): Color for maximum values HSL (0.0-1.0)
72
fontname (str): Font family name
73
fontcolor (str): Font color
74
nodestyle (str): Node styling options
75
minfontsize (float): Minimum font size in points
76
maxfontsize (float): Maximum font size in points
77
minpenwidth (float): Minimum pen width for edges
78
maxpenwidth (float): Maximum pen width for edges
79
gamma (float): Gamma correction for color mapping
80
skew (float): Skew factor for color distribution
81
"""
82
83
def graph_bgcolor(self):
84
"""
85
Get background color for the graph.
86
87
Returns:
88
str: DOT color specification
89
"""
90
91
def node_bgcolor(self, weight):
92
"""
93
Get background color for a node based on its weight.
94
95
Args:
96
weight (float): Node weight/importance (0.0-1.0)
97
98
Returns:
99
str: DOT color specification
100
"""
101
102
def node_fgcolor(self, weight):
103
"""
104
Get foreground color for a node.
105
106
Args:
107
weight (float): Node weight/importance (0.0-1.0)
108
109
Returns:
110
str: DOT color specification
111
"""
112
113
def node_fontsize(self, weight):
114
"""
115
Get font size for node text based on weight.
116
117
Args:
118
weight (float): Node weight/importance (0.0-1.0)
119
120
Returns:
121
float: Font size in points
122
"""
123
124
def node_style(self):
125
"""
126
Get node styling attributes.
127
128
Returns:
129
str: DOT style specification
130
"""
131
132
def edge_color(self, weight):
133
"""
134
Get color for an edge based on its weight.
135
136
Args:
137
weight (float): Edge weight/importance (0.0-1.0)
138
139
Returns:
140
str: DOT color specification
141
"""
142
143
def edge_fontsize(self, weight):
144
"""
145
Get font size for edge labels based on weight.
146
147
Args:
148
weight (float): Edge weight/importance (0.0-1.0)
149
150
Returns:
151
float: Font size in points
152
"""
153
154
def edge_penwidth(self, weight):
155
"""
156
Get pen width for edges based on weight.
157
158
Args:
159
weight (float): Edge weight/importance (0.0-1.0)
160
161
Returns:
162
float: Pen width
163
"""
164
165
def edge_arrowsize(self, weight):
166
"""
167
Get arrow size for edges based on weight.
168
169
Args:
170
weight (float): Edge weight/importance (0.0-1.0)
171
172
Returns:
173
float: Arrow size
174
"""
175
```
176
177
### Predefined Color Schemes
178
179
Ready-to-use color themes optimized for different visualization needs and output formats.
180
181
```python { .api }
182
TEMPERATURE_COLORMAP: Theme
183
"""Blue to red temperature-style color scheme (default)."""
184
185
PINK_COLORMAP: Theme
186
"""Pink to red color scheme for alternative styling."""
187
188
GRAY_COLORMAP: Theme
189
"""Grayscale color scheme for monochrome output."""
190
191
BW_COLORMAP: Theme
192
"""Black and white color scheme for high contrast."""
193
194
PRINT_COLORMAP: Theme
195
"""Print-friendly color scheme optimized for paper output."""
196
```
197
198
### Theme Registry
199
200
Dictionary mapping theme names to Theme objects for easy selection.
201
202
```python { .api }
203
themes = {
204
'color': TEMPERATURE_COLORMAP,
205
'pink': PINK_COLORMAP,
206
'gray': GRAY_COLORMAP,
207
'bw': BW_COLORMAP,
208
'print': PRINT_COLORMAP
209
}
210
```
211
212
### Utility Functions
213
214
Helper functions for consistent formatting and color processing.
215
216
```python { .api }
217
def sorted_iteritems(d):
218
"""
219
Iterate dictionary items in sorted order for reproducible output.
220
221
Args:
222
d (dict): Dictionary to iterate
223
224
Yields:
225
tuple: (key, value) pairs in sorted order
226
"""
227
228
def times(x):
229
"""
230
Format multiplication count with Unicode symbol.
231
232
Args:
233
x (int): Count value
234
235
Returns:
236
str: Formatted count (e.g., "5×")
237
"""
238
239
def percentage(p):
240
"""
241
Format percentage value.
242
243
Args:
244
p (float): Percentage as decimal (0.0-1.0)
245
246
Returns:
247
str: Formatted percentage (e.g., "25.50%")
248
"""
249
```
250
251
## Usage Examples
252
253
### Basic Graph Generation
254
255
```python
256
import gprof2dot
257
import sys
258
259
# Parse profile data
260
parser = gprof2dot.PstatsParser()
261
with open('profile.stats', 'rb') as f:
262
profile = parser.parse(f)
263
264
# Generate DOT output with default theme
265
theme = gprof2dot.TEMPERATURE_COLORMAP
266
dot_writer = gprof2dot.DotWriter(sys.stdout)
267
dot_writer.graph(profile, theme)
268
```
269
270
### Custom Theme Usage
271
272
```python
273
import gprof2dot
274
275
# Use different predefined themes
276
themes_to_try = ['color', 'pink', 'gray', 'bw', 'print']
277
278
for theme_name in themes_to_try:
279
theme = gprof2dot.themes[theme_name]
280
281
with open(f'profile_{theme_name}.dot', 'w') as f:
282
dot_writer = gprof2dot.DotWriter(f)
283
dot_writer.graph(profile, theme)
284
```
285
286
### Creating Custom Themes
287
288
```python
289
import gprof2dot
290
291
# Create custom theme with specific colors
292
custom_theme = gprof2dot.Theme(
293
bgcolor=(1.0, 1.0, 1.0), # White background
294
mincolor=(0.0, 1.0, 0.0), # Green for low values
295
maxcolor=(1.0, 0.0, 0.0), # Red for high values
296
fontname="Helvetica",
297
fontsize="12",
298
fontcolor="black",
299
nodestyle="filled,rounded",
300
edgestyle="bold"
301
)
302
303
# Use custom theme
304
dot_writer = gprof2dot.DotWriter(sys.stdout)
305
dot_writer.graph(profile, custom_theme)
306
```
307
308
### Generating Different Output Formats
309
310
```python
311
import gprof2dot
312
import subprocess
313
import sys
314
315
# Generate DOT and convert to various formats
316
def generate_visualization(profile, theme, output_file, format='png'):
317
"""Generate visualization in specified format."""
318
319
# Generate DOT
320
dot_process = subprocess.Popen(
321
['dot', f'-T{format}', '-o', output_file],
322
stdin=subprocess.PIPE,
323
text=True
324
)
325
326
dot_writer = gprof2dot.DotWriter(dot_process.stdin)
327
dot_writer.graph(profile, theme)
328
dot_process.stdin.close()
329
dot_process.wait()
330
331
# Usage
332
theme = gprof2dot.TEMPERATURE_COLORMAP
333
generate_visualization(profile, theme, 'profile.png', 'png')
334
generate_visualization(profile, theme, 'profile.svg', 'svg')
335
generate_visualization(profile, theme, 'profile.pdf', 'pdf')
336
```
337
338
### Fine-Grained Graph Control
339
340
```python
341
import gprof2dot
342
343
class CustomDotWriter(gprof2dot.DotWriter):
344
"""Custom DOT writer with additional formatting."""
345
346
def begin_graph(self):
347
super().begin_graph()
348
# Add custom graph attributes
349
self.fp.write(' rankdir=TB;\n') # Top-to-bottom layout
350
self.fp.write(' concentrate=true;\n') # Merge similar edges
351
352
def node(self, node, theme):
353
# Add custom node processing
354
if hasattr(node, 'is_main') and node.is_main:
355
# Highlight main function differently
356
self.fp.write(f' "{node.id}" [shape=doublecircle];\n')
357
else:
358
super().node(node, theme)
359
360
# Use custom writer
361
custom_writer = CustomDotWriter(sys.stdout)
362
custom_writer.graph(profile, theme)
363
```
364
365
### Color Weight Calculations
366
367
```python
368
import gprof2dot
369
370
def analyze_color_mapping(profile, theme):
371
"""Analyze how colors map to performance metrics."""
372
373
for function in profile.functions.values():
374
if gprof2dot.TOTAL_TIME_RATIO in function:
375
weight = function[gprof2dot.TOTAL_TIME_RATIO]
376
bgcolor = theme.node_bgcolor(weight)
377
fgcolor = theme.node_fgcolor(weight)
378
379
print(f"Function {function.name}:")
380
print(f" Weight: {weight:.3f}")
381
print(f" Background: {bgcolor}")
382
print(f" Foreground: {fgcolor}")
383
```