shift_node_marks() prepares node markers for inferred regime shifts on an
already plotted tree. For bifrost_search inputs, transitions are computed
from the final multi-regime BMM mapped tree. Generic workflows can supply a
shift_transitions() table, or a SIMMAP-style tree plus a named
state_values vector.
Usage
shift_node_marks(
x = NULL,
tree = NULL,
state_values = NULL,
transitions = NULL,
ic_weights = NULL,
support_threshold = 0.9,
letter_order = c("child_state", "node", "age"),
marker_base_cex = 1.5,
marker_scale_factor = 0.08,
marker_transform = c("square_root", "log1p"),
marker_max_cex = Inf
)
# S3 method for class 'shift_node_marks'
plot(
x,
rate_changes = c("increase", "decrease"),
show_letters = TRUE,
show_low_support = TRUE,
show_legend = TRUE,
marker_alpha = 0.75,
letter_cex = 0.75,
increase_fill = "white",
decrease_fill = "#2b6cb0",
marker_col = "#111827",
low_support_cex = 0.7,
low_support_col = grDevices::adjustcolor("black", alpha.f = 0.58),
legend_position = "topleft",
legend_cex = 0.72,
...
)
# S3 method for class 'shift_node_marks'
as.data.frame(
x,
row.names = NULL,
optional = FALSE,
component = c("marks", "increase_key", "summary"),
...
)Arguments
- x
A
bifrost_searchobject, ashift_transitions()table, a SIMMAP-stylephylotree whenstate_valuesis supplied, or an object previously returned byshift_node_marks().- tree
Optional SIMMAP-style
phylotree for generic input mode.- state_values
Named numeric vector mapping SIMMAP state labels to state-associated values for generic input mode.
- transitions
Optional precomputed transition table. When supplied,
xis used only as a possible source ofic_weights.- ic_weights
Optional data frame with
nodeandic_weight_withshiftcolumns. When omitted for a compatiblebifrost_searchobject,x$ic_weightsis used when available.- support_threshold
Numeric threshold used to flag low-support shifts from
ic_weight_withshift.- letter_order
Ordering used when assigning letters to increase nodes. The default,
"child_state", matches the Berv et al. (2026) manuscript convention by ordering increases by the destination regime state, with node number as a stable tie-breaker. Use"node"for node-number order or"age"for chronological order.- marker_base_cex, marker_scale_factor
Controls for marker size. Size is
marker_base_cex + transformed(abs(percentage_change)) * marker_scale_factor.- marker_transform
Transformation applied to absolute percent change before scaling marker size.
- marker_max_cex
Maximum marker size.
- rate_changes
Which directional shifts to draw.
- show_letters
Logical; draw letter labels for increase nodes.
- show_low_support
Logical; draw an additional dot on shifts with
ic_weight_withshift < support_threshold.- show_legend
Logical; draw a compact legend for the node marks.
- marker_alpha
Alpha used for filled node markers.
- letter_cex
Character expansion for letter labels.
- increase_fill, decrease_fill
Fill colors for increase and decrease markers.
- marker_col
Outline color for filled node markers.
- low_support_cex, low_support_col
Size and color for low-support dots.
- legend_position
Position passed to
graphics::legend().- legend_cex
Character expansion passed to
graphics::legend().- ...
Reserved for future extensions. Supplying unused arguments to
plot()oras.data.frame()methods is an error.- row.names, optional
Included for compatibility with
base::as.data.frame(); ignored.- component
Component to extract with
base::as.data.frame(). Use"marks","increase_key", or"summary".
Value
shift_node_marks() returns an object of class "shift_node_marks"
with marks, increase_key, low_support_nodes, summary, and
settings. Plotting returns the same object invisibly. The
as.data.frame() method returns the requested component as a plain
data.frame.
Details
The workflow is intentionally plot-agnostic: first draw the tree with
plot.rateMap() or another tree plotting function, then call plot() on the
returned shift_node_marks object to add the node layer.
Examples
toy_tree <- ape::read.tree(text = "(((a:1,b:1):1,c:2):1,d:3);")
toy_tree <- phytools::paintSubTree(
tree = toy_tree,
node = ape::Ntip(toy_tree) + 1L,
state = "0"
)
toy_tree <- phytools::paintSubTree(
tree = toy_tree,
node = ape::Ntip(toy_tree) + 2L,
state = "1"
)
toy_tree <- phytools::paintSubTree(
tree = toy_tree,
node = ape::Ntip(toy_tree) + 3L,
state = "2"
)
marks <- shift_node_marks(
tree = toy_tree,
state_values = c("0" = 1, "1" = 4, "2" = 2)
)
marks$increase_key
#> letter child_state node age percentage_change ic_weight_withshift
#> 1 A 1 6 2 300 NA
