Skip to content
Projects

TikZ tokens

Download notebookView on GitHubRun when the site was built.

Arrow tips, fill patterns, plot marks, node shapes, path decorations and styles are short TikZ strings such as -stealth or crosshatch. tikzfigure gives each kind a small type, all built on TikzToken: named constants for the common values, a function for any other, and the same behavior for all of them. Plain strings keep working everywhere a token is accepted.

from tikzfigure import TikzFigure, arrows, decorations, marks, patterns, shapes, styles
from tikzfigure.core.tikz_token import TikzToken
ModuleTypeExamplesUsed as
arrowsTikzArrowforward, stealth, latex_botharrows=
patternsTikzPatterncrosshatch, dots, north_east_linespattern=
marksTikzMarkcircle, square_filled, xmark= of a plot
shapesTikzShapediamond, ellipse, starshape= of a node
decorationsTikzDecorationsnake, zigzag, bracedecoration=
stylesTikzStyledashed, decorate, line_width(1.2)options=[...]
for token in (
arrows.stealth,
patterns.crosshatch,
marks.square_filled,
shapes.diamond,
decorations.snake,
styles.dashed,
):
print(
f"{type(token).__name__:15} {token.spec!r:18} a TikzToken: {isinstance(token, TikzToken)}"
)
TikzArrow '-stealth' a TikzToken: True
TikzPattern 'crosshatch' a TikzToken: True
TikzMark 'square*' a TikzToken: True
TikzShape 'diamond' a TikzToken: True
TikzDecoration 'snake' a TikzToken: True
TikzStyle 'dashed' a TikzToken: True

Some tokens need a TikZ library: shape= beyond circles and rectangles needs shapes.geometric, patterns patterns, and decorations the matching decorations.* library.

fig = TikzFigure()
fig.usetikzlibrary("shapes.geometric", "patterns", "decorations.pathmorphing")
a = fig.add_node(
0, 0, label="a", content="A", shape=shapes.diamond, draw="black", fill="blue!20"
)
b = fig.add_node(4, 0, label="b", content="B", shape=shapes.ellipse, draw="black")
edge = fig.draw([a, b], arrows=arrows.stealth, options=[styles.line_width(1.2)])
box = fig.filldraw(
[(0, -1), (4, -1), (4, -2), (0, -2)], cycle=True, pattern=patterns.crosshatch
)
wave = fig.draw(
[(0, -3), (4, -3)], options=[styles.decorate], decoration=decorations.snake
)
corner = fig.draw(
[(0, -4), (2, -4), (2, -5)], options=[styles.dashed, styles.rounded_corners(4)]
)
fig.show()
/home/runner/work/tikzfigure/tikzfigure/.venv/lib/python3.12/site-packages/fitz/__init__.py:17: FutureWarning: The `fitz` API is deprecated and will be removed in future. Use `import pymupdf` instead.
warnings.warn(
Notebook output
print(fig)
% --------------------------------------------- %
% Tikzfigure generated by tikzfigure v0.5.0 %
% https://github.com/max-models/tikzfigure %
% --------------------------------------------- %
\begin{tikzpicture}
\node[shape=diamond, fill=blue!20, draw=black] (a) at ({0}, {0}) {A};
\node[shape=ellipse, draw=black] (b) at ({4}, {0}) {B};
\draw[line width=1.2pt, -stealth] (a) to (b);
\filldraw[pattern=crosshatch] (0, -1)
to
(4, -1)
to
(4, -2)
to
(0, -2) -- cycle;
\draw[decorate, decoration=snake] (0, -3) to (4, -3);
\draw[dashed, rounded corners=4pt] (0, -4) to (2, -4) to (2, -5);
\end{tikzpicture}

Each module has a function for any other value: arrows.tip, patterns.pattern, marks.mark, shapes.shape, decorations.decoration and styles.style. The styles module also builds measured options: line_width, rounded_corners, dash_pattern, bend_left and bend_right.

big_tip = arrows.tip("-{Latex[length=3mm]}")
print(big_tip)
print(styles.line_width(0.8), styles.dash_pattern(on=3, off=2), styles.bend_left(30))
-{Latex[length=3mm]}
line width=0.8pt dash pattern=on 3pt off 2pt bend left=30

Two tokens of the same kind are equal when their specs are, and they hash the same, so they work as dictionary keys or in sets, for a palette of styles shared between figures. str(token) and token.to_tikz() give the raw string.

print(arrows.forward == arrows.tip("->"))
print(styles.dashed == styles.style("dashed"))
print(arrows.forward == styles.style("->")) # different kinds are never equal
line_styles = {"measured": styles.solid, "fit": styles.dashed, "theory": styles.dotted}
print({name: str(style) for name, style in line_styles.items()})
True
True
False
{'measured': 'solid', 'fit': 'dashed', 'theory': 'dotted'}