0
# TikZ Graphics and Plotting
1
2
Advanced graphics creation with TikZ including geometric shapes, plots, coordinate systems, and complex diagrams. PyLaTeX provides comprehensive support for TikZ and PGFPlots, enabling programmatic generation of professional-quality vector graphics, technical diagrams, and data visualizations.
3
4
## Capabilities
5
6
### TikZ Environment
7
8
The TikZ class creates the basic environment for vector graphics with support for geometric shapes, paths, and annotations.
9
10
```python { .api }
11
class TikZ(Environment):
12
"""
13
Basic TikZ picture environment for vector graphics.
14
15
Requires:
16
- tikz package (automatically added)
17
"""
18
19
def __init__(self, options=None, *, data=None):
20
"""
21
Create a TikZ picture environment.
22
23
Parameters:
24
- options: str, list, or TikZOptions, TikZ picture options
25
- data: initial graphics content
26
"""
27
```
28
29
Usage example:
30
31
```python
32
from pylatex import Document, Section, NoEscape
33
from pylatex.tikz import TikZ
34
35
doc = Document()
36
37
with doc.create(Section('Basic Graphics')):
38
# Simple TikZ drawing
39
with doc.create(TikZ()) as tikz:
40
tikz.append(NoEscape(r'\draw (0,0) -- (2,0) -- (1,1) -- cycle;'))
41
tikz.append(NoEscape(r'\fill[red] (0.5,0.5) circle (0.1);'))
42
43
# TikZ with options
44
tikz_options = ['scale=2', 'transform shape']
45
with doc.create(TikZ(options=tikz_options)) as tikz:
46
tikz.append(NoEscape(r'\draw[blue, thick] (0,0) rectangle (2,1);'))
47
tikz.append(NoEscape(r'\node at (1,0.5) {Scaled Rectangle};'))
48
```
49
50
### Coordinate System
51
52
The TikZCoordinate class provides precise coordinate handling with support for relative and absolute positioning.
53
54
```python { .api }
55
class TikZCoordinate(LatexObject):
56
def __init__(self, x, y, relative=False):
57
"""
58
Create a TikZ coordinate.
59
60
Parameters:
61
- x: float or int, X coordinate
62
- y: float or int, Y coordinate
63
- relative: bool, whether coordinate is relative (++) or absolute
64
"""
65
66
@classmethod
67
def from_str(cls, coordinate):
68
"""
69
Create coordinate from string representation.
70
71
Parameters:
72
- coordinate: str, coordinate string like '(1,2)' or '++(1,2)'
73
"""
74
75
def distance_to(self, other):
76
"""
77
Calculate distance to another coordinate.
78
79
Parameters:
80
- other: TikZCoordinate, target coordinate
81
"""
82
```
83
84
Usage example:
85
86
```python
87
from pylatex import Document, Section, NoEscape
88
from pylatex.tikz import TikZ, TikZCoordinate
89
90
doc = Document()
91
92
with doc.create(Section('Coordinate Examples')):
93
with doc.create(TikZ()) as tikz:
94
# Define coordinates
95
start = TikZCoordinate(0, 0)
96
end = TikZCoordinate(3, 2)
97
relative_point = TikZCoordinate(1, 1, relative=True)
98
99
# Use coordinates in drawing commands
100
tikz.append(NoEscape(f r'\draw {start} -- {end};'))
101
tikz.append(NoEscape(f r'\draw {end} -- {relative_point};'))
102
103
# Calculate and use distances
104
distance = start.distance_to(end)
105
tikz.append(NoEscape(f r'\node at (1.5, 2.5) {{Distance: {distance:.2f}}};'))
106
107
# Coordinate arithmetic
108
with doc.create(Section('Coordinate Calculations')):
109
with doc.create(TikZ()) as tikz:
110
p1 = TikZCoordinate(1, 1)
111
p2 = TikZCoordinate(2, 1)
112
p3 = p1 + p2 # Addition
113
114
tikz.append(NoEscape(f r'\fill[red] {p1} circle (0.05);'))
115
tikz.append(NoEscape(f r'\fill[blue] {p2} circle (0.05);'))
116
tikz.append(NoEscape(f r'\fill[green] {p3} circle (0.05);'))
117
```
118
119
### TikZ Drawing Commands
120
121
Core TikZ drawing primitives for creating geometric shapes and paths.
122
123
```python { .api }
124
class TikZNode(Command):
125
def __init__(self, text=None, options=None, at=None):
126
"""
127
Create a TikZ node.
128
129
Parameters:
130
- text: str, node content
131
- options: str or TikZOptions, node formatting options
132
- at: TikZCoordinate or str, node position
133
"""
134
135
class TikZDraw(Command):
136
def __init__(self, path, options=None):
137
"""
138
Create a TikZ draw command.
139
140
Parameters:
141
- path: str, drawing path specification
142
- options: str or TikZOptions, drawing options (color, line style, etc.)
143
"""
144
145
class TikZPath(Command):
146
def __init__(self, path, options=None):
147
"""
148
Create a TikZ path command.
149
150
Parameters:
151
- path: str, path specification
152
- options: str or TikZOptions, path options
153
"""
154
```
155
156
Usage example:
157
158
```python
159
from pylatex import Document, Section, NoEscape
160
from pylatex.tikz import TikZ, TikZNode, TikZDraw, TikZCoordinate
161
162
doc = Document()
163
164
with doc.create(Section('TikZ Drawing Commands')):
165
with doc.create(TikZ()) as tikz:
166
# Draw geometric shapes
167
tikz.append(TikZDraw(r'(0,0) rectangle (3,2)', options='fill=lightblue'))
168
tikz.append(TikZDraw(r'(4,0) circle (1)', options='fill=red, opacity=0.5'))
169
tikz.append(TikZDraw(r'(0,3) -- (3,4) -- (2,5) -- cycle',
170
options='fill=green, draw=black, thick'))
171
172
# Add nodes with labels
173
tikz.append(TikZNode('Rectangle', at=TikZCoordinate(1.5, 1)))
174
tikz.append(TikZNode('Circle', at=TikZCoordinate(4, 0)))
175
tikz.append(TikZNode('Triangle', at=TikZCoordinate(1.5, 4)))
176
177
# Complex path example
178
with doc.create(Section('Complex Paths')):
179
with doc.create(TikZ()) as tikz:
180
# Bezier curves
181
tikz.append(NoEscape(
182
r'\draw[thick, blue] (0,0) .. controls (1,2) and (3,2) .. (4,0);'
183
))
184
185
# Decorative paths
186
tikz.append(NoEscape(
187
r'\draw[decorate, decoration={zigzag, amplitude=0.2cm}] '
188
r'(0,-1) -- (4,-1);'
189
))
190
```
191
192
### Axis and Plotting Environment
193
194
The Axis class provides sophisticated plotting capabilities through PGFPlots integration.
195
196
```python { .api }
197
class Axis(Environment):
198
def __init__(self, options=None, *, data=None):
199
"""
200
Create a PGFPlots axis environment for data plotting.
201
202
Parameters:
203
- options: str, list, or Options, axis configuration options
204
- data: initial plot content
205
206
Requires:
207
- pgfplots package (automatically added)
208
- pgfplotsset compatibility setting (automatically configured)
209
"""
210
211
class Plot(Command):
212
def __init__(self, name=None, func=None, coordinates=None,
213
error_bar=None, options=None):
214
"""
215
Create a plot within an axis environment.
216
217
Parameters:
218
- name: str, plot name for legend
219
- func: str, mathematical function to plot
220
- coordinates: list, data points as coordinate pairs
221
- error_bar: dict, error bar specifications
222
- options: str or Options, plot styling options
223
"""
224
```
225
226
Usage example:
227
228
```python
229
from pylatex import Document, Section, NoEscape
230
from pylatex.tikz import TikZ, Axis, Plot
231
import numpy as np
232
233
doc = Document()
234
235
with doc.create(Section('Data Plotting')):
236
# Basic function plot
237
with doc.create(TikZ()) as tikz:
238
with tikz.create(Axis(options='xlabel=x, ylabel=y, title=Function Plot')) as axis:
239
axis.append(Plot(name='sin(x)', func='sin(deg(x))'))
240
axis.append(Plot(name='cos(x)', func='cos(deg(x))'))
241
242
# Data point plotting
243
with doc.create(TikZ()) as tikz:
244
# Generate sample data
245
x_data = np.linspace(0, 10, 20)
246
y_data = np.sin(x_data) + 0.1 * np.random.randn(20)
247
coordinates = [(x, y) for x, y in zip(x_data, y_data)]
248
249
axis_options = [
250
'xlabel=Time (s)',
251
'ylabel=Amplitude',
252
'title=Experimental Data',
253
'grid=major',
254
'legend pos=north east'
255
]
256
257
with tikz.create(Axis(options=axis_options)) as axis:
258
axis.append(Plot(name='Measured', coordinates=coordinates,
259
options='only marks, mark=*'))
260
axis.append(Plot(name='Theory', func='sin(deg(x))',
261
options='thick, red'))
262
263
# Multiple axis types
264
with doc.create(Section('Specialized Plots')):
265
# Logarithmic scale
266
with doc.create(TikZ()) as tikz:
267
log_options = [
268
'xmode=log',
269
'ymode=log',
270
'xlabel=Frequency (Hz)',
271
'ylabel=Magnitude',
272
'title=Bode Plot'
273
]
274
275
with tikz.create(Axis(options=log_options)) as axis:
276
# Frequency response data
277
freq = np.logspace(0, 3, 50)
278
magnitude = 1 / np.sqrt(1 + (freq/100)**2)
279
coords = [(f, m) for f, m in zip(freq, magnitude)]
280
281
axis.append(Plot(coordinates=coords, options='thick, blue'))
282
```
283
284
### TikZ Scope and Styling
285
286
Advanced styling and localized transformations using scope environments.
287
288
```python { .api }
289
class TikZScope(Environment):
290
def __init__(self, options=None, *, data=None):
291
"""
292
Create a TikZ scope for localized styling and transformations.
293
294
Parameters:
295
- options: str or TikZOptions, scope-specific options
296
- data: initial scope content
297
"""
298
299
class TikZOptions(Options):
300
"""
301
Specialized options class for TikZ with no escaping.
302
"""
303
304
def append_positional(self, option):
305
"""
306
Add positional option to TikZ options.
307
308
Parameters:
309
- option: str, option to add
310
"""
311
```
312
313
Usage example:
314
315
```python
316
from pylatex import Document, Section, NoEscape
317
from pylatex.tikz import TikZ, TikZScope, TikZOptions
318
319
doc = Document()
320
321
with doc.create(Section('Scoped Styling')):
322
with doc.create(TikZ()) as tikz:
323
# Global elements
324
tikz.append(NoEscape(r'\draw (0,0) rectangle (6,4);'))
325
326
# Scoped transformations and styling
327
scope_options = TikZOptions(['red', 'thick', 'scale=0.5', 'shift={(1,1)}'])
328
with tikz.create(TikZScope(options=scope_options)) as scope:
329
scope.append(NoEscape(r'\draw (0,0) rectangle (4,2);'))
330
scope.append(NoEscape(r'\fill[blue] (2,1) circle (0.5);'))
331
332
# Different scope with rotation
333
rotate_options = TikZOptions(['rotate=45', 'shift={(4,2)}'])
334
with tikz.create(TikZScope(options=rotate_options)) as scope:
335
scope.append(NoEscape(r'\draw[green, thick] (0,0) -- (2,0) -- (1,1) -- cycle;'))
336
337
# Nested scopes
338
with doc.create(Section('Nested Scopes')):
339
with doc.create(TikZ()) as tikz:
340
with tikz.create(TikZScope(options='blue, thick')) as outer_scope:
341
outer_scope.append(NoEscape(r'\draw (0,0) rectangle (4,3);'))
342
343
with outer_scope.create(TikZScope(options='red, scale=0.5')) as inner_scope:
344
inner_scope.append(NoEscape(r'\draw (1,1) rectangle (3,2);'))
345
inner_scope.append(NoEscape(r'\node at (2,1.5) {Nested};'))
346
```
347
348
## Advanced TikZ Applications
349
350
### Technical Diagrams
351
352
```python
353
from pylatex import Document, Section, NoEscape
354
from pylatex.tikz import TikZ, TikZNode, TikZCoordinate
355
356
doc = Document()
357
358
with doc.create(Section('System Architecture')):
359
with doc.create(TikZ()) as tikz:
360
# Define diagram components
361
components = [
362
('User Interface', TikZCoordinate(0, 3), 'fill=lightblue'),
363
('API Layer', TikZCoordinate(0, 2), 'fill=lightgreen'),
364
('Business Logic', TikZCoordinate(0, 1), 'fill=yellow'),
365
('Database', TikZCoordinate(0, 0), 'fill=pink')
366
]
367
368
# Draw components
369
for name, pos, style in components:
370
tikz.append(NoEscape(f r'\node[draw, {style}, minimum width=3cm, minimum height=0.8cm] '
371
f'at {pos} {{{name}}};'))
372
373
# Draw connections
374
for i in range(len(components) - 1):
375
y1, y2 = 3 - i - 0.4, 3 - i - 1 + 0.4
376
tikz.append(NoEscape(f r'\draw[thick, ->] (0,{y1}) -- (0,{y2});'))
377
378
# Network diagram
379
with doc.create(Section('Network Topology')):
380
with doc.create(TikZ()) as tikz:
381
# Server nodes
382
servers = [
383
('Web Server', TikZCoordinate(0, 2)),
384
('App Server', TikZCoordinate(3, 2)),
385
('DB Server', TikZCoordinate(6, 2))
386
]
387
388
# Client nodes
389
clients = [
390
('Client 1', TikZCoordinate(1, 0)),
391
('Client 2', TikZCoordinate(2, 0)),
392
('Client 3', TikZCoordinate(4, 0)),
393
('Client 4', TikZCoordinate(5, 0))
394
]
395
396
# Draw servers
397
for name, pos in servers:
398
tikz.append(NoEscape(f r'\node[draw, rectangle, fill=lightblue] '
399
f'at {pos} {{{name}}};'))
400
401
# Draw clients
402
for name, pos in clients:
403
tikz.append(NoEscape(f r'\node[draw, circle, fill=lightgreen] '
404
f'at {pos} {{{name}}};'))
405
406
# Connect clients to web server
407
for _, pos in clients:
408
tikz.append(NoEscape(f r'\draw[->] {pos} -- (0,2);'))
409
410
# Connect servers
411
tikz.append(NoEscape(r'\draw[<->] (0,2) -- (3,2);'))
412
tikz.append(NoEscape(r'\draw[<->] (3,2) -- (6,2);'))
413
```
414
415
### Mathematical Visualizations
416
417
```python
418
from pylatex import Document, Section, NoEscape
419
from pylatex.tikz import TikZ, Axis
420
import numpy as np
421
422
doc = Document()
423
424
with doc.create(Section('Mathematical Functions')):
425
# 3D surface plot
426
with doc.create(TikZ()) as tikz:
427
axis_options = [
428
'view={60}{30}',
429
'xlabel=x',
430
'ylabel=y',
431
'zlabel=z',
432
'title=3D Surface'
433
]
434
435
with tikz.create(Axis(options=axis_options)) as axis:
436
# Generate 3D function data
437
axis.append(NoEscape(
438
r'\addplot3[surf, samples=20, domain=-2:2] {x*x + y*y};'
439
))
440
441
# Vector field visualization
442
with doc.create(Section('Vector Fields')):
443
with doc.create(TikZ()) as tikz:
444
axis_options = [
445
'axis equal',
446
'xlabel=x',
447
'ylabel=y',
448
'title=Vector Field',
449
'grid=major'
450
]
451
452
with tikz.create(Axis(options=axis_options)) as axis:
453
# Create vector field
454
for x in np.linspace(-2, 2, 10):
455
for y in np.linspace(-2, 2, 10):
456
# Vector components (simple example)
457
dx, dy = -y * 0.3, x * 0.3
458
459
tikz.append(NoEscape(
460
f r'\draw[->] ({x},{y}) -- ({x+dx},{y+dy});'
461
))
462
```
463
464
### Interactive Diagrams
465
466
```python
467
from pylatex import Document, Section, Package, NoEscape
468
from pylatex.tikz import TikZ
469
470
doc = Document()
471
472
# Enable TikZ libraries for advanced features
473
doc.packages.append(Package('tikz', options=[
474
'arrows', 'positioning', 'shapes', 'decorations.markings'
475
]))
476
477
with doc.create(Section('Flow Chart')):
478
with doc.create(TikZ()) as tikz:
479
# Define node styles
480
tikz.append(NoEscape(r'''
481
\tikzstyle{process} = [rectangle, minimum width=3cm, minimum height=1cm,
482
text centered, draw=black, fill=orange!30]
483
\tikzstyle{decision} = [diamond, minimum width=3cm, minimum height=1cm,
484
text centered, draw=black, fill=green!30]
485
\tikzstyle{arrow} = [thick,->,>=stealth]
486
'''))
487
488
# Create flowchart
489
tikz.append(NoEscape(r'''
490
\node (start) [process] {Start Process};
491
\node (check) [decision, below of=start, yshift=-1cm] {Check Condition};
492
\node (process1) [process, below of=check, yshift=-1cm] {Execute Action};
493
\node (end) [process, below of=process1, yshift=-1cm] {End Process};
494
495
\draw [arrow] (start) -- (check);
496
\draw [arrow] (check) -- node[anchor=west] {Yes} (process1);
497
\draw [arrow] (process1) -- (end);
498
\draw [arrow] (check) -| node[anchor=south] {No} (end);
499
'''))
500
```
501
502
## Styling and Customization
503
504
### Custom TikZ Styles
505
506
```python
507
from pylatex import Document, Section, NoEscape
508
from pylatex.tikz import TikZ, TikZOptions
509
510
doc = Document()
511
512
# Define custom styles in preamble
513
doc.preamble.append(NoEscape(r'''
514
\tikzset{
515
highlight/.style={draw=red, fill=red!20, thick},
516
note/.style={draw=blue, dashed, fill=blue!10},
517
arrow/.style={thick, ->, >=latex}
518
}
519
'''))
520
521
with doc.create(Section('Custom Styles')):
522
with doc.create(TikZ()) as tikz:
523
tikz.append(NoEscape(r'\draw[highlight] (0,0) rectangle (2,1);'))
524
tikz.append(NoEscape(r'\draw[note] (3,0) circle (0.5);'))
525
tikz.append(NoEscape(r'\draw[arrow] (2,0.5) -- (2.5,0);'))
526
```
527
528
### Color Schemes and Themes
529
530
```python
531
from pylatex import Document, Package, NoEscape
532
from pylatex.tikz import TikZ
533
534
doc = Document()
535
doc.packages.append(Package('xcolor'))
536
537
# Define color palette
538
doc.preamble.append(NoEscape(r'''
539
\definecolor{primary}{RGB}{65, 105, 225}
540
\definecolor{secondary}{RGB}{220, 20, 60}
541
\definecolor{accent}{RGB}{255, 165, 0}
542
'''))
543
544
with doc.create(TikZ()) as tikz:
545
tikz.append(NoEscape(r'\fill[primary] (0,0) rectangle (2,1);'))
546
tikz.append(NoEscape(r'\fill[secondary] (2.5,0) rectangle (4.5,1);'))
547
tikz.append(NoEscape(r'\fill[accent] (5,0) rectangle (7,1);'))
548
```
549
550
## Package Dependencies
551
552
TikZ functionality requires specific LaTeX packages:
553
554
- **Basic TikZ**: `tikz` package (automatically added)
555
- **PGFPlots**: `pgfplots` package (automatically added with Axis)
556
- **Advanced features**: Various TikZ libraries
557
- **3D plotting**: `pgfplots` with 3D capabilities
558
559
```python
560
from pylatex import Document, Package
561
562
doc = Document()
563
564
# TikZ packages and libraries
565
doc.packages.append(Package('tikz'))
566
doc.packages.append(Package('pgfplots'))
567
doc.packages.append(Package('tikz', options=[
568
'arrows', 'positioning', 'shapes', 'decorations',
569
'patterns', 'calc', 'through', 'intersections'
570
]))
571
572
# PGFPlots configuration
573
doc.preamble.append(NoEscape(r'\pgfplotsset{compat=newest}'))
574
```
575
576
The TikZ system in PyLaTeX provides powerful vector graphics capabilities with programmatic control over complex diagrams, technical illustrations, and data visualizations while maintaining the high quality and precision of LaTeX graphics.