Generates LaTeX TikZ code from a Disco, Knowledge, or
caugi::caugi object, preserving node positions, labels, and visual styles.
Edges are rendered with arrows, line widths, and colors.
The output is readable LaTeX code that can be
directly compiled or modified.
Usage
make_tikz(
x,
...,
scale = 10,
full_doc = TRUE,
bend_edges = FALSE,
bend_angle = 25,
tier_label_pos = c("above", "below", "left", "right")
)Arguments
- x
A
Disco,Knowledge, orcaugi::caugiobject.- ...
Additional arguments passed to
plot()andcaugi::plot().- scale
Numeric scalar. Scaling factor for node coordinates. Default is
10.- full_doc
Logical. If
TRUE(default), generates a full standalone LaTeX document. IfFALSE, returns only thetikzpictureenvironment.- bend_edges
Logical. If
TRUE, edges are drawn with bent edges. Default isFALSE. Edges connecting the same pair of nodes in both directions (A %-->% BandB %-->% A) are automatically bent left and right to avoid overlap. Bend direction is automatically chosen to reduce overlap.- bend_angle
Numeric scalar. Angle in degrees for bending arrows when
bend_edges = TRUE. Default is25.- tier_label_pos
Character string specifying the position of tier labels relative to the tier rectangles. Must be one of
"above","below","left", or"right". Default is"above".
Value
A character string containing LaTeX TikZ code. Depending on
full_doc, this is either:
a complete LaTeX document (
full_doc = TRUE), oronly the
tikzpictureenvironment (full_doc = FALSE).
Details
The function calls plot() to generate a caugi::caugi_plot object, then
traverses the plot object's grob structure to extract nodes and
edges. Supported features include:
Nodes
Fill color and draw color (supports both named colors and custom RGB values)
Font size
Coordinates are scaled by the
scaleparameter
Edges
Line color and width
Arrow scale
Optional bending to reduce overlapping arrows
The generated TikZ code uses global style settings, and edges are connected to nodes by name (as opposed to hard-coded coordinates), making it easy to modify the output further if needed.
Examples
################# Convert Knowledge to Tikz ################
data(num_data)
kn <- knowledge(
num_data,
X1 %-->% X2,
X2 %!-->% c(X3, Y),
Y %!-->% Z
)
# Full standalone document
tikz_kn <- make_tikz(kn, scale = 10, full_doc = TRUE)
cat(tikz_kn)
#> %%% Generated by causalDisco (version 1.0.1.9000)
#> \documentclass[tikz,border=2mm]{standalone}
#> \usetikzlibrary{arrows.meta, positioning, shapes.geometric, fit, backgrounds, calc}
#>
#> \begin{document}
#> \tikzset{every node/.style={fill=lightgray}, every path/.style={draw=red}}
#> \tikzset{arrows={[scale=3]}, arrow/.style={-{Stealth}, thick}}
#> \begin{tikzpicture}
#> \node[draw, circle] (X1) at (1.667,0) {X1};
#> \node[draw, circle] (X2) at (1.667,3.333) {X2};
#> \node[draw, circle] (X3) at (3.333,6.667) {X3};
#> \node[draw, circle] (Y) at (0,6.667) {Y};
#> \node[draw, circle] (Z) at (0,10) {Z};
#> \path (X1) edge[draw=blue, -Latex] (X2)
#> (X2) edge[, -Latex] (X3)
#> (X2) edge[, -Latex] (Y)
#> (Y) edge[, -Latex] (Z);
#> \end{tikzpicture}
#> \end{document}
# Only the tikzpicture environment
tikz_kn_snippet <- make_tikz(kn, full_doc = FALSE)
cat(tikz_kn_snippet)
#> %%% Generated by causalDisco (version 1.0.1.9000)
#> \tikzset{every node/.style={fill=lightgray}, every path/.style={draw=red}}
#> \tikzset{arrows={[scale=3]}, arrow/.style={-{Stealth}, thick}}
#> \begin{tikzpicture}
#> \node[draw, circle] (X1) at (1.667,0) {X1};
#> \node[draw, circle] (X2) at (1.667,3.333) {X2};
#> \node[draw, circle] (X3) at (3.333,6.667) {X3};
#> \node[draw, circle] (Y) at (0,6.667) {Y};
#> \node[draw, circle] (Z) at (0,10) {Z};
#> \path (X1) edge[draw=blue, -Latex] (X2)
#> (X2) edge[, -Latex] (X3)
#> (X2) edge[, -Latex] (Y)
#> (Y) edge[, -Latex] (Z);
#> \end{tikzpicture}
# With bent edges
tikz_bent <- make_tikz(
kn,
full_doc = FALSE,
bend_edges = TRUE
)
cat(tikz_bent)
#> %%% Generated by causalDisco (version 1.0.1.9000)
#> \tikzset{every node/.style={fill=lightgray}, every path/.style={draw=red}}
#> \tikzset{arrows={[scale=3]}, arrow/.style={-{Stealth}, thick}}
#> \begin{tikzpicture}
#> \node[draw, circle] (X1) at (1.667,0) {X1};
#> \node[draw, circle] (X2) at (1.667,3.333) {X2};
#> \node[draw, circle] (X3) at (3.333,6.667) {X3};
#> \node[draw, circle] (Y) at (0,6.667) {Y};
#> \node[draw, circle] (Z) at (0,10) {Z};
#> \path (X1) edge[draw=blue, bend left=25, -Latex] (X2)
#> (X2) edge[bend left=25, -Latex] (X3)
#> (X2) edge[bend right=25, -Latex] (Y)
#> (Y) edge[bend left=25, -Latex] (Z);
#> \end{tikzpicture}
# With a color not supported by default TikZ colors; will fall back to RGB
tikz_darkblue <- make_tikz(
kn,
node_style = list(fill = "darkblue"),
full_doc = FALSE
)
cat(tikz_darkblue)
#> %%% Generated by causalDisco (version 1.0.1.9000)
#> \tikzset{every node/.style={fill={rgb:red,0.000;green,0.000;blue,0.545}}, every path/.style={draw=red}}
#> \tikzset{arrows={[scale=3]}, arrow/.style={-{Stealth}, thick}}
#> \begin{tikzpicture}
#> \node[draw, circle] (X1) at (1.667,0) {X1};
#> \node[draw, circle] (X2) at (1.667,3.333) {X2};
#> \node[draw, circle] (X3) at (3.333,6.667) {X3};
#> \node[draw, circle] (Y) at (0,6.667) {Y};
#> \node[draw, circle] (Z) at (0,10) {Z};
#> \path (X1) edge[draw=blue, -Latex] (X2)
#> (X2) edge[, -Latex] (X3)
#> (X2) edge[, -Latex] (Y)
#> (Y) edge[, -Latex] (Z);
#> \end{tikzpicture}
# With tiered knowledge
data(tpc_example)
kn_tiered <- knowledge(
tpc_example,
tier(
child ~ starts_with("child"),
youth ~ starts_with("youth"),
old ~ starts_with("old")
)
)
tikz_tiered_kn <- make_tikz(
kn_tiered,
full_doc = FALSE
)
cat(tikz_tiered_kn)
#> %%% Generated by causalDisco (version 1.0.1.9000)
#> \tikzset{every node/.style={fill=lightgray}}
#> \tikzset{arrows={[scale=1]}, arrow/.style={-{Stealth}, thick}}
#> \begin{tikzpicture}
#> \node[draw, circle] (child_x1) at (0,0) {child\_x1};
#> \node[draw, circle] (child_x2) at (0,10) {child\_x2};
#> \node[draw, circle] (youth_x3) at (5,0) {youth\_x3};
#> \node[draw, circle] (youth_x4) at (5,10) {youth\_x4};
#> \node[draw, circle] (oldage_x5) at (10,0) {oldage\_x5};
#> \node[draw, circle] (oldage_x6) at (10,10) {oldage\_x6};
#> \begin{scope}[on background layer]
#> \node[draw, rectangle, fill=blue!20, rounded corners, inner sep=0.5cm, fit=(child_x1)(child_x2)] (child) {};
#> \node[draw, rectangle, fill=blue!20, rounded corners, inner sep=0.5cm, fit=(oldage_x5)(oldage_x6)] (old) {};
#> \node[draw, rectangle, fill=blue!20, rounded corners, inner sep=0.5cm, fit=(youth_x3)(youth_x4)] (youth) {};
#> \end{scope}
#> \node[anchor=south, draw=none, fill=none] at ($(child.north)+(0cm,0.2cm)$) {child};
#> \node[anchor=south, draw=none, fill=none] at ($(old.north)+(0cm,0.2cm)$) {old};
#> \node[anchor=south, draw=none, fill=none] at ($(youth.north)+(0cm,0.2cm)$) {youth};
#> \path ;
#> \end{tikzpicture}
################# Convert disco to Tikz ################
data(num_data)
kn <- knowledge(
num_data,
X1 %-->% X2,
X2 %!-->% c(X3, Y),
Y %!-->% Z
)
pc_bnlearn <- pc(engine = "bnlearn", test = "fisher_z", alpha = 0.05)
disco_kn <- disco(data = num_data, method = pc_bnlearn, knowledge = kn)
tikz_snippet <- make_tikz(disco_kn, scale = 10, full_doc = FALSE)
cat(tikz_snippet)
#> %%% Generated by causalDisco (version 1.0.1.9000)
#> \tikzset{every node/.style={fill=lightgray}, every path/.style={draw=blue}}
#> \tikzset{arrows={[scale=3]}, arrow/.style={-{Stealth}, thick}}
#> \begin{tikzpicture}
#> \node[draw, circle] (X1) at (2.609,3.549) {X1};
#> \node[draw, circle] (X2) at (7.431,3.545) {X2};
#> \node[draw, circle] (X3) at (10,0) {X3};
#> \node[draw, circle] (Z) at (0,0.013) {Z};
#> \node[draw, circle] (Y) at (5.007,0.226) {Y};
#> \path (X1) edge[, -Latex] (X2)
#> (X1) edge[, -Latex] (Y)
#> (X1) edge[, -] (Z)
#> (X3) edge[, -Latex] (X2)
#> (X3) edge[, -Latex] (Y)
#> (Y) edge[, -Latex] (X2)
#> (Z) edge[, -Latex] (Y);
#> \end{tikzpicture}
################# Convert caugi objects to Tikz ################
cg <- caugi::caugi(A %-->% B + C)
tikz_snippet <- make_tikz(
cg,
node_style = list(fill = "red"),
scale = 10,
full_doc = FALSE
)
cat(tikz_snippet)
#> %%% Generated by causalDisco (version 1.0.1.9000)
#> \tikzset{every node/.style={fill=red}}
#> \tikzset{arrows={[scale=3]}, arrow/.style={-{Stealth}, thick}}
#> \begin{tikzpicture}
#> \node[draw, circle] (A) at (5,0) {A};
#> \node[draw, circle] (B) at (10,10) {B};
#> \node[draw, circle] (C) at (0,10) {C};
#> \path (A) edge[, -Latex] (B)
#> (A) edge[, -Latex] (C);
#> \end{tikzpicture}
