Plots a TNA model with nodes arranged in multiple groups using geometric layouts:
2 groups: Bipartite (two vertical columns or horizontal rows)
3+ groups: Polygon (nodes along edges of a regular polygon)
Supports triangle (3), rectangle (4), pentagon (5), hexagon (6), and beyond.
Usage
plot_htna(
x,
node_list,
layout = "auto",
use_list_order = TRUE,
jitter = TRUE,
jitter_amount = 0.8,
jitter_side = "first",
orientation = "vertical",
group1_pos = -1.2,
group2_pos = 1.2,
curvature = 0.4,
group1_color = "#ffd89d",
group2_color = "#a68ba5",
group1_shape = "circle",
group2_shape = "square",
group_colors = NULL,
group_shapes = NULL,
angle_spacing = 0.15,
edge_colors = NULL,
legend = TRUE,
legend_position = "topright",
extend_lines = FALSE,
scale = 1,
...
)Arguments
- x
A tna object or weight matrix.
- node_list
List of 2+ character vectors defining node groups.
- layout
Layout type: "auto" (default), "bipartite", "polygon", or "circular". When "auto", uses bipartite for 2 groups and polygon for 3+ groups. "circular" places groups along arcs of a circle. Legacy values "triangle" and "rectangle" are supported as aliases for "polygon".
- use_list_order
Logical. Use node_list order (TRUE) or weight-based order (FALSE). Only applies to bipartite layout.
- jitter
Controls horizontal spread of nodes. Options:
TRUE (default): Auto-compute jitter based on edge connectivity
FALSE or 0: No jitter (nodes aligned in columns)
Numeric (0-1): Amount of jitter (0.3 = spread nodes 30\
Named list: Manual per-node offsets by label (e.g., list(Wrong = -0.2))
Numeric vector of length n: Direct x-offsets for each node
Only applies to bipartite layout.
- jitter_amount
Base jitter amount when jitter=TRUE. Default 0.5. Higher values spread nodes more toward the center. Only applies to bipartite layout.
- jitter_side
Which side(s) to apply jitter: "first", "second", "both", or "none". Default "first" (only first group nodes are jittered toward center). Only applies to bipartite layout.
- orientation
Layout orientation for bipartite: "vertical" (two columns, default) or "horizontal" (two rows). Ignored for triangle/rectangle layouts.
- group1_pos
Position for first group in bipartite layout. Default -1.2.
- group2_pos
Position for second group in bipartite layout. Default 1.2.
- curvature
Edge curvature amount. Default 0.4 for visible curves.
- group1_color
Color for first group nodes. Default "#ffd89d".
- group2_color
Color for second group nodes. Default "#a68ba5".
- group1_shape
Shape for first group nodes. Default "circle".
- group2_shape
Shape for second group nodes. Default "square".
- group_colors
Vector of colors for each group. Overrides group1_color/group2_color. Required for 3+ groups if not using defaults.
- group_shapes
Vector of shapes for each group. Overrides group1_shape/group2_shape. Required for 3+ groups if not using defaults.
- angle_spacing
Controls empty space at corners (0-1). Default 0.15. Higher values create larger empty angles at vertices. Only applies to triangle/rectangle layouts.
- edge_colors
Vector of colors for edges by source group. If NULL (default), uses darker versions of group_colors. Set to FALSE to use default edge color.
- legend
Logical. Whether to show a legend. Default TRUE for polygon layouts.
- legend_position
Position for legend: "topright", "topleft", "bottomright", "bottomleft", "right", "left", "top", "bottom". Default "topright".
- extend_lines
Logical or numeric. Draw extension lines from nodes. Only applies to bipartite layout.
FALSE (default): No extension lines
TRUE: Draw lines extending toward the other group (default length 0.1)
Numeric: Length of extension lines
- scale
Scaling factor for high resolution plotting.
- ...
Additional parameters passed to tplot().
Examples
# --- 2-group bipartite example ---
nodes_2 <- c("Wrong", "Retry", "Right", "Attempt", "Instruction", "Skip",
"Order", "Correct", "Hint", "Quit", "Clarify", "Question", "Praise")
set.seed(1)
m2 <- matrix(runif(length(nodes_2)^2, 0, 0.3), length(nodes_2), length(nodes_2))
diag(m2) <- 0
dimnames(m2) <- list(nodes_2, nodes_2)
node_types <- list(
Student = c("Wrong", "Retry", "Right", "Attempt", "Instruction", "Skip"),
AI = c("Order", "Correct", "Hint", "Quit", "Clarify", "Question", "Praise")
)
plot_htna(m2, node_types)
plot_htna(m2, node_types, jitter_amount = 0.5)
# --- Triangle layout (3 groups) ---
nodes_3 <- c("Explain", "Question", "Feedback",
"Answer", "Ask", "Attempt",
"Hint", "Score", "Progress")
m3 <- matrix(runif(81, 0, 0.3), 9, 9)
diag(m3) <- 0
dimnames(m3) <- list(nodes_3, nodes_3)
node_types_3 <- list(
Teacher = c("Explain", "Question", "Feedback"),
Student = c("Answer", "Ask", "Attempt"),
System = c("Hint", "Score", "Progress")
)
plot_htna(m3, node_types_3)
plot_htna(m3, node_types_3, layout = "triangle")
# --- Rectangle layout (4 groups) ---
nodes_4 <- c("Click", "Type", "Scroll",
"Validate", "Transform",
"Display", "Alert",
"Save", "Load", "Cache")
m4 <- matrix(runif(100, 0, 0.3), 10, 10)
diag(m4) <- 0
dimnames(m4) <- list(nodes_4, nodes_4)
node_types_4 <- list(
Input = c("Click", "Type", "Scroll"),
Process = c("Validate", "Transform"),
Output = c("Display", "Alert"),
Storage = c("Save", "Load", "Cache")
)
plot_htna(m4, node_types_4)