| Title: | Metro-Style Diagrams of 'targets' Pipeline Dependency Graphs |
|---|---|
| Description: | Create metro-style diagrams of targets pipelines dependency graph and other directed acyclic graphs using ggplot2. |
| Authors: | Roy Francis [aut, cre] (ORCID: <https://orcid.org/0000-0001-8654-3580>) |
| Maintainer: | Roy Francis <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.0.0.9001 |
| Built: | 2026-10-16 17:39:11 UTC |
| Source: | https://github.com/royfrancis/ggtargets |
as_dag() is the entry point for any DAG that isn't read from a
targets pipeline (see tar_dag()). It normalizes the input into a
dag: a classed list with nodes and edges data frames, keeping
insertion order throughout, the way networkx does.
as_dag(x, ...) ## S3 method for class 'data.frame' as_dag(x, nodes = NULL, ...) ## S3 method for class 'list' as_dag(x, ...) ## Default S3 method: as_dag(x, ...)as_dag(x, ...) ## S3 method for class 'data.frame' as_dag(x, nodes = NULL, ...) ## S3 method for class 'list' as_dag(x, ...) ## Default S3 method: as_dag(x, ...)
x |
An edge-list data frame with |
... |
Passed on to methods. |
nodes |
Optional data frame of nodes, with at least a |
as_dag.list() deliberately narrows the return value described above.
It is the tar_dag() path, so it keeps only the vertices columns a
metro plot can use - type, status, description, seconds,
bytes and branches - and no extra edges columns. To color by
other node attributes, pass an edge-list data frame and a nodes
table to as_dag.data.frame() instead.
Node names are identities, and the package matches edge colors on them
downstream, so every method rejects a name that is NA, empty
or contains "|" or a carriage return.
A dag: a classed list with nodes (columns name, label,
plus any extra attributes, which node_color, node_shape and, for a
numeric one, node_size can name) and edges (columns from, to,
plus any extra columns of x, which only edge_width uses for
drawing) data frames, in insertion order.
edges <- data.frame(from = c("a", "a", "b"), to = c("b", "c", "c")) dag <- as_dag(edges) print(dag) ggplot_dag(dag) # a node table, with extra attributes for coloring nodes <- data.frame(name = c("a", "b", "c"), type = c("x", "y", "x")) dag2 <- as_dag(edges, nodes = nodes) ggplot_dag(dag2, node_color = "type")edges <- data.frame(from = c("a", "a", "b"), to = c("b", "c", "c")) dag <- as_dag(edges) print(dag) ggplot_dag(dag) # a node table, with extra attributes for coloring nodes <- data.frame(name = c("a", "b", "c"), type = c("x", "y", "x")) dag2 <- as_dag(edges, nodes = nodes) ggplot_dag(dag2, node_color = "type")
Collapses a dag: the nodes that share a value of the by column are
merged into one node, named after that value, and the edges are projected
onto these new nodes. A pipeline of fifty targets in four stages becomes a
graph of four nodes, drawn by the same functions (ggplot_dag(),
tar_ggplot()) as any other dag.
dag_collapse(dag, by, label_n = TRUE)dag_collapse(dag, by, label_n = TRUE)
dag |
|
by |
The name of a node column (a single string). Its values are used as text. |
label_n |
If |
Any node column works as by, so there is nothing special about its name:
a column of your own (passed to as_dag() as nodes), or one that
tar_dag() returns - description, type or status. targets has no
tag or category field of its own, and description is its one free-form
text, so a pipeline's stages go there: see "Collapsing a pipeline by
stage" in tar_ggplot(). For any other metadata, add a column to
dag$nodes yourself first (not named row, col, x, y or
color_index).
A node with no value in by (NA or an empty string) stays on its own,
and a value that is also the name of such a node is an error, since the
two would be merged.
Nodes. name is the value of by, and label is that value with
the member count, "model (7)". A node with no by value is not
merged: it stays as it is, in its own place. The order is the
order of first appearance, so each merged node sits where its first
member was. n counts the members (replacing any n column you
already have, so n itself is not a useful by).
Other node columns. seconds, bytes and branches are summed
(NA if every member is NA). Any other column keeps its value when
all the members share it, and is NA otherwise; in particular the by
column itself keeps its value (even if it is one of the columns that
are otherwise summed), so node_color = by colors the collapsed
graph.
Edges. An edge between two members of one group disappears. The
others are drawn between the groups, once per pair of groups, with an
n column that counts the edges it stands for. Any other edge column is
dropped.
Merging nodes can create a cycle, which a DAG can't have: with a -> b -> c, a and c in group X and b in group Y, the collapsed graph has X -> Y -> X. That is an error, naming the groups and the edges behind it. Group
by a different column, or move the node that closes the loop.
A dag, with the columns described above: nodes name, label,
n and the rolled-up columns, and edges from, to and n.
nodes <- data.frame( name = c("raw", "clean", "fit", "eval", "report"), stage = c("data", "data", "model", "model", "report") ) edges <- data.frame( from = c("raw", "clean", "fit", "eval"), to = c("clean", "fit", "eval", "report") ) dag <- as_dag(edges, nodes = nodes) small <- dag_collapse(dag, "stage") small$nodes small$edges ggplot_dag(small, node_color = "stage") # a grouping that closes a loop is an error bad <- as_dag( data.frame(from = c("a", "b"), to = c("b", "c")), nodes = data.frame(name = c("a", "b", "c"), group = c("X", "Y", "X")) ) try(dag_collapse(bad, "group")) # the targets' own `description` as the key targets::tar_dir({ targets::tar_script(list( targets::tar_target(x, 1, description = "input"), targets::tar_target(y, x + 1, description = "input"), targets::tar_target(z, y * 2, description = "output") )) ggplot_dag(dag_collapse(tar_dag(), "description")) })nodes <- data.frame( name = c("raw", "clean", "fit", "eval", "report"), stage = c("data", "data", "model", "model", "report") ) edges <- data.frame( from = c("raw", "clean", "fit", "eval"), to = c("clean", "fit", "eval", "report") ) dag <- as_dag(edges, nodes = nodes) small <- dag_collapse(dag, "stage") small$nodes small$edges ggplot_dag(small, node_color = "stage") # a grouping that closes a loop is an error bad <- as_dag( data.frame(from = c("a", "b"), to = c("b", "c")), nodes = data.frame(name = c("a", "b", "c"), group = c("X", "Y", "X")) ) try(dag_collapse(bad, "group")) # the targets' own `description` as the key targets::tar_dir({ targets::tar_script(list( targets::tar_target(x, 1, description = "input"), targets::tar_target(y, x + 1, description = "input"), targets::tar_target(z, y * 2, description = "output") )) ggplot_dag(dag_collapse(tar_dag(), "description")) })
Returns a list of ggplot2 layers in draw order, ready to add to a
ggplot() call (or combined with dag_theme() by ggplot_dag()).
dag_layers( layout, node_color = NULL, edge_color = "source", palette = metro_palette, node_shape = NULL, shapes = targets_node_shapes(), node_size = NULL, edge_width = NULL, zoom = 1 )dag_layers( layout, node_color = NULL, edge_color = "source", palette = metro_palette, node_shape = NULL, shapes = targets_node_shapes(), node_size = NULL, edge_width = NULL, zoom = 1 )
layout |
A |
node_color, palette, edge_color
|
Color resolution arguments: see
the pkgdown site's Colors article for the full set of rules and
examples. |
node_shape |
The shape of a node: |
shapes |
Which shape each value of the |
node_size |
The size of a node: |
edge_width |
The width of an edge: |
zoom |
Multiplier for node size, line widths and text size, to match
a panel sized at |
A list of ggplot2 layers.
dag <- as_dag(data.frame(from = c("a", "a", "b"), to = c("b", "c", "c"))) lay <- dag_layout(dag, style_metro()) ggplot2::ggplot() + dag_layers(lay) + dag_theme()dag <- as_dag(data.frame(from = c("a", "a", "b"), to = c("b", "c", "c"))) lay <- dag_layout(dag, style_metro()) ggplot2::ggplot() + dag_layers(lay) + dag_theme()
Turns an as_dag() dag into a dag_layout, the plain data that
dag_layers() and ggplot_dag() draw from. Coordinates are in
dagviz's SVG pixel space, with y growing downward (dag_theme()
reverses the y scale to match).
dag_layout(dag, style = style_metro())dag_layout(dag, style = style_metro())
dag |
|
style |
A |
A dag_layout: a classed list of
nodes: one row per node, in row order - name, label, row,
col, x, y, color_index, plus the dag's extra node columns.
Those can't be named row, col, x, y or color_index: the
layout needs these, so such a column is an error.
segments: straight lines, layer ("leader", "vline",
"bridge" or "hline"), x, y, xend, yend, from, to
and order (dagviz's draw order, shared with arcs).
arcs: one point path per arc (id), with x, y, from, to
and order.
labels: name, label, x, y.
edge_paths: one full point path per graph edge - from, to,
piece ("vline", "arc" or "hline"), x, y, and order
(point order along the path) - used for edge_color other than
"source", for any edge_width, and for highlighting paths.
edges: the dag's edges as they are - from, to, plus any
extra edge columns, such as the n of dag_collapse(), which
edge_width of dag_layers() can name. (They are kept apart from
edge_paths, so that no column of yours can overwrite a coordinate
there.)
viewbox: a list of left, top, bottom, right, width and
height.
style: the style_metro() object.
dag <- as_dag(data.frame(from = c("a", "a", "b"), to = c("b", "c", "c"))) lay <- dag_layout(dag, style_metro()) print(lay) lay$nodesdag <- as_dag(data.frame(from = c("a", "a", "b"), to = c("b", "c", "c"))) lay <- dag_layout(dag, style_metro()) print(lay) lay$nodes
For a plot drawn with a fixed panel size (the ggplot_dag() default),
returns the full plot's size, including any legend or title added with
ggplot2::labs(); a legend taller than the graph makes the plot taller,
so it isn't cut off (with a few percent to spare, as devices measure text
slightly differently). Otherwise, returns the view box size at 1 px per data
unit (96 dpi), read from the coord_fixed() limits that dag_layers()
sets. Useful for sizing figures, e.g. knitr's fig.width/fig.height.
dag_size(plot)dag_size(plot)
plot |
A plot from |
A named numeric vector, c(width =, height =), in inches.
dag <- as_dag(data.frame(from = c("a", "a", "b"), to = c("b", "c", "c"))) dag_size(ggplot_dag(dag)) dag_size(ggplot_dag(dag, node_color = "name")) # wider: includes the legenddag <- as_dag(data.frame(from = c("a", "a", "b"), to = c("b", "c", "c"))) dag_size(ggplot_dag(dag)) dag_size(ggplot_dag(dag, node_color = "name")) # wider: includes the legend
theme_void() with zero plot margins and a white background, plus
scale_y_reverse(): layout coordinates have y growing downward, as in
dagviz's SVG. The theme is an ordinary ggplot2 theme, so any of its
elements can be overridden by adding theme() settings afterwards.
dag_theme()dag_theme()
A legend gets a small margin on its right (legend.box.margin, 5.5 pt),
so that it doesn't touch the edge of the image. A plot without a legend
has no such margin.
A list of ggplot2 theme/scale components.
dag <- as_dag(data.frame(from = c("a", "a", "b"), to = c("b", "c", "c"))) lay <- dag_layout(dag, style_metro()) ggplot2::ggplot() + dag_layers(lay) + dag_theme()dag <- as_dag(data.frame(from = c("a", "a", "b"), to = c("b", "c", "c"))) lay <- dag_layout(dag, style_metro()) ggplot2::ggplot() + dag_layers(lay) + dag_theme()
ggplot_dag() is ggplot() + dag_layers(lay, ...) + dag_theme().
Given a dag instead of a dag_layout, it first lays it out with
dag_layout(), in the style you give it (style_metro() by default).
ggplot_dag( x, node_color = NULL, edge_color = "source", palette = metro_palette, node_shape = NULL, shapes = targets_node_shapes(), node_size = NULL, edge_width = NULL, style = style_metro(), fixed_size = TRUE, zoom = 1 )ggplot_dag( x, node_color = NULL, edge_color = "source", palette = metro_palette, node_shape = NULL, shapes = targets_node_shapes(), node_size = NULL, edge_width = NULL, style = style_metro(), fixed_size = TRUE, zoom = 1 )
x |
A |
node_color, palette, edge_color, node_shape, shapes, node_size, edge_width
|
Passed to |
style |
A |
fixed_size |
If |
zoom |
Uniform size multiplier for nodes, lines and text (with
|
By default (fixed_size = TRUE) the panel gets an absolute size of
zoom px (at 96 dpi) per data unit, via theme(panel.widths, panel.heights). Nodes, lines and text then keep the same size whatever
the pipeline's length: a bigger graph gives a bigger plot, not smaller
nodes. Use dag_size() (or ggsave_dag()) to get or save the plot at
that size. On a device smaller than the plot, such as a small RStudio
Plots pane, a large graph is clipped: lower zoom, or save it with
ggsave_dag().
With fixed_size = FALSE the panel stretches to fill the device, as
any ggplot does. Nodes, line widths and text are set in absolute units,
so they keep their size while the spacing between nodes stretches, and
their proportions to it vary with the graph's size.
Adding a complete theme afterwards (e.g. + ggplot2::theme_void())
replaces the panel size and so turns fixed sizing off. Add individual
theme() settings instead.
A ggplot object.
dag <- as_dag(data.frame(from = c("a", "a", "b"), to = c("b", "c", "c"))) ggplot_dag(dag) ggplot_dag(dag, edge_color = "target") ggplot_dag(dag, style = style_metro(node_radius = 9, scale = 12)) ggplot_dag(dag, zoom = 0.5) # nodes shaped (and colored) by a column nodes <- data.frame(name = c("a", "b", "c"), role = c("in", "mid", "out")) ggplot_dag( as_dag(data.frame(from = c("a", "b"), to = c("b", "c")), nodes = nodes), node_color = "role", node_shape = "role", shapes = c("diamond", "circle", "triangle") ) dag_size(ggplot_dag(dag)) # a collapsed graph, with node size and edge width showing the counts nodes <- data.frame( name = c("raw", "clean", "tidy", "fit", "eval", "report"), stage = c("data", "data", "data", "model", "model", "report") ) edges <- data.frame( from = c("raw", "clean", "tidy", "tidy", "fit", "eval"), to = c("clean", "tidy", "fit", "eval", "eval", "report") ) small <- dag_collapse(as_dag(edges, nodes = nodes), "stage") ggplot_dag(small, node_color = "stage", node_size = "n", edge_width = "n")dag <- as_dag(data.frame(from = c("a", "a", "b"), to = c("b", "c", "c"))) ggplot_dag(dag) ggplot_dag(dag, edge_color = "target") ggplot_dag(dag, style = style_metro(node_radius = 9, scale = 12)) ggplot_dag(dag, zoom = 0.5) # nodes shaped (and colored) by a column nodes <- data.frame(name = c("a", "b", "c"), role = c("in", "mid", "out")) ggplot_dag( as_dag(data.frame(from = c("a", "b"), to = c("b", "c")), nodes = nodes), node_color = "role", node_shape = "role", shapes = c("diamond", "circle", "triangle") ) dag_size(ggplot_dag(dag)) # a collapsed graph, with node size and edge width showing the counts nodes <- data.frame( name = c("raw", "clean", "tidy", "fit", "eval", "report"), stage = c("data", "data", "data", "model", "model", "report") ) edges <- data.frame( from = c("raw", "clean", "tidy", "tidy", "fit", "eval"), to = c("clean", "tidy", "fit", "eval", "eval", "report") ) small <- dag_collapse(as_dag(edges, nodes = nodes), "stage") ggplot_dag(small, node_color = "stage", node_size = "n", edge_width = "n")
Sizes the output with dag_size(), so that one data unit equals one SVG
pixel (times ggplot_dag(zoom =)) at scale 1, at 96 dpi.
ggsave_dag(filename, plot = ggplot2::last_plot(), scale = 1, ...)ggsave_dag(filename, plot = ggplot2::last_plot(), scale = 1, ...)
filename |
File to write to, passed to |
plot |
A plot from |
scale |
Resolution multiplier (applied to |
... |
Passed on to |
scale raises resolution (dpi = 96 * scale) rather than the physical
width/height: line widths and text are set in absolute units (points),
so scaling the canvas size at a fixed dpi would make them relatively
thinner/smaller against the (now larger) node spacing. Scaling dpi
instead keeps every element's proportions exactly as dagviz draws them,
just at higher resolution.
For a fixed-size plot (the ggplot_dag() default) the output also
makes room for any legend or title. For a plot with
fixed_size = FALSE (or manual assembly), the size is the view box's
alone, so a legend or title shrinks the panel to fit.
The result of ggplot2::ggsave(), invisibly.
dag <- as_dag(data.frame(from = c("a", "a", "b"), to = c("b", "c", "c"))) p <- ggplot_dag(dag) ggsave_dag(tempfile(fileext = ".png"), p)dag <- as_dag(data.frame(from = c("a", "a", "b"), to = c("b", "c", "c"))) p <- ggplot_dag(dag) ggsave_dag(tempfile(fileext = ".png"), p)
n distinct colors, never recycled. The first 18 are
dagviz.style.colors.palette()'s colors (6 hues at 3 lightness levels,
in dagviz's order, minus the 3 duplicates that its 7th hue step produces
by wrapping around to the 1st). Further colors are generated
deterministically in HCL space, each kept only if it is perceptibly
different from all earlier ones. metro_palette(k) is always the first
k colors of metro_palette(n) for k <= n. Colors get harder to tell
apart as n grows large (beyond roughly 100).
metro_palette(n)metro_palette(n)
n |
Number of colors to generate. |
A character vector of n distinct hex colors.
metro_palette(5) # as a row of color swatches swatches <- data.frame(x = 1:24, color = metro_palette(24)) ggplot2::ggplot(swatches, ggplot2::aes(x, 1, fill = I(color))) + ggplot2::geom_tile() + ggplot2::theme_void()metro_palette(5) # as a row of color swatches swatches <- data.frame(x = 1:24, color = metro_palette(24)) ggplot2::ggplot(swatches, ggplot2::aes(x, 1, fill = I(color))) + ggplot2::geom_tile() + ggplot2::theme_void()
Reproduces dagviz's StyleConfig defaults (style/metro.py) as a
dag_style_metro object: round nodes (the default shape; see node_shape
of dag_layers()), thick colored edges with rounded bends, and labels to
the right.
style_metro( scale = 10, node_radius = 6, node_fill = NULL, node_stroke = "white", node_stroke_width = 2, edge_stroke_width = 2, label_font_family = "sans-serif", label_font_size = "inherit", label_font_color = "currentColor", label_arrow_stroke = "lightgrey", label_arrow_dash_array = "2", arc_radius = 15, bridge_color = "white", minimal_width = NULL, node_size_range = NULL, edge_width_range = NULL )style_metro( scale = 10, node_radius = 6, node_fill = NULL, node_stroke = "white", node_stroke_width = 2, edge_stroke_width = 2, label_font_family = "sans-serif", label_font_size = "inherit", label_font_color = "currentColor", label_arrow_stroke = "lightgrey", label_arrow_dash_array = "2", arc_radius = 15, bridge_color = "white", minimal_width = NULL, node_size_range = NULL, edge_width_range = NULL )
scale |
Half the distance, in pixels, between neighboring rows and
between neighboring lanes (columns): both are |
node_radius |
The radius of a node, in pixels: of a circle, and the
size that other shapes (see |
node_fill |
Optional single fill color for every node, used only
when |
node_stroke, node_stroke_width
|
The color and width of a node's border. |
edge_stroke_width |
The line width of an edge. |
label_font_family, label_font_size, label_font_color
|
The font
family, size (in pixels) and color of a node's label. Accept either
dagviz's own |
label_arrow_stroke, label_arrow_dash_array
|
The color and linetype
of the leader line from a node to its label. |
arc_radius |
The radius of an input arc. |
bridge_color |
The color of the white "bridge" drawn under a horizontal line where it crosses other edges. |
minimal_width |
How far the plot extends to the right of its
labels. |
node_size_range, edge_width_range
|
The smallest and largest node
radius and edge width, in pixels, when |
A dag_style_metro object.
style_metro() dag <- as_dag(data.frame(from = c("a", "a", "b"), to = c("b", "c", "c"))) ggplot_dag(dag, style = style_metro(node_radius = 9, arc_radius = 12, scale = 12))style_metro() dag <- as_dag(data.frame(from = c("a", "a", "b"), to = c("b", "c", "c"))) ggplot_dag(dag, style = style_metro(node_radius = 9, arc_radius = 12, scale = 12))
A thin wrapper around targets::tar_network(): runs it, then converts
its vertices/edges result with as_dag(), keeping type (which
ggplot_dag() draws as the node shape, see targets_node_shapes()),
status, description, seconds, bytes and branches.
tar_dag(targets_only = TRUE, envir = parent.frame(), ...)tar_dag(targets_only = TRUE, envir = parent.frame(), ...)
targets_only |
Passed to |
envir |
Environment to run the target script in. Forwarded
explicitly (rather than left to |
... |
Passed to |
description is the one free-form field targets has for a target, and
can hold the stage it belongs to, for dag_collapse() to collapse the
pipeline by: see "Collapsing a pipeline by stage" in tar_ggplot().
A dag (see as_dag()).
targets::tar_dir({ # doesn't pollute the working directory targets::tar_script(list( targets::tar_target(x, 1), targets::tar_target(y, x + 1) )) ggplot_dag(tar_dag()) })targets::tar_dir({ # doesn't pollute the working directory targets::tar_script(list( targets::tar_target(x, 1), targets::tar_target(y, x + 1) )) ggplot_dag(tar_dag()) })
The headline one-call function: tar_dag(), then dag_collapse() if you
give a collapse_by, then dag_layout() and ggplot_dag(). Mirrors
targets::tar_visnetwork()'s filtering arguments.
tar_ggplot( style = style_metro(), node_color = NULL, edge_color = "source", palette = metro_palette, node_shape = NULL, shapes = targets_node_shapes(), node_size = NULL, edge_width = NULL, collapse_by = NULL, fixed_size = TRUE, zoom = 1, targets_only = TRUE, envir = parent.frame(), ... )tar_ggplot( style = style_metro(), node_color = NULL, edge_color = "source", palette = metro_palette, node_shape = NULL, shapes = targets_node_shapes(), node_size = NULL, edge_width = NULL, collapse_by = NULL, fixed_size = TRUE, zoom = 1, targets_only = TRUE, envir = parent.frame(), ... )
style, node_color, edge_color, palette, node_shape, shapes, node_size, edge_width
|
Passed to |
collapse_by |
|
fixed_size, zoom
|
Passed to |
targets_only, envir, ...
|
Passed to |
To plot a pipeline in another folder: script and store locate the
pipeline's files, but tar_network() runs _targets.R from the current
working directory, and most pipelines use relative paths (e.g.
tar_source("R")). Use withr::with_dir("path/to/project", tar_ggplot()).
As in tar_visnetwork(), the node shape shows its type: a circle for a
regular target, a square for a dynamic-branching one, and triangles for
imported functions and objects (only in the graph with targets_only = FALSE). A legend names the shapes when more than one is drawn. See
targets_node_shapes().
A ggplot object.
targets has no tag or category field for a target, but it has one free-form
text field, description, and collapse_by = "description" collapses the
pipeline by it: the targets that share a description become one node,
labeled with how many they are (ingest (4)), and the dependencies between
stages become one edge each (see dag_collapse()). With node_size = "n"
and edge_width = "n", the size of a node and the width of an edge show
those counts.
A description can be set for each target, tar_target(raw, read_data(), description = "ingest"), or for a block of them with tar_option_set(),
which applies to every target defined after it:
# _targets.R library(targets) tar_option_set(description = "ingest") ingest <- list(tar_target(raw, read_data()), tar_target(clean, tidy(raw))) tar_option_set(description = "model") model <- list(tar_target(fit, fit_model(clean))) tar_option_set(description = character(0)) # back to no description c(ingest, model)
tar_ggplot(collapse_by = "description", node_size = "n", edge_width = "n")
Things to know:
End a block with tar_option_set(description = character(0)). The option
stays set for every target defined after it, including those in files
loaded later with tar_source().
tarchetypes::tar_map() appends the mapped values to each description by
default (descriptions = tidyselect::everything()), so the targets it
makes would be stages of their own. Pass descriptions = NULL to keep the
stage's description.
The descriptions must match exactly: "ingest" and "Ingest " are two
stages.
A target with no description is a node of its own. A stage can't be named like such a target (an error: the two would be merged).
Stages that depend on each other both ways (A -> B -> A) are an error that names the edges behind it.
description is also the label of a target in targets::tar_manifest()
and targets::tar_visnetwork(), so a short stage name is a good one, and
a sentence is not.
node_color = "status" colors a stage by its status when all its targets
share one. A stage whose targets differ has no status, and is drawn gray
with no legend entry, as is any node with a missing value in the
node_color column.
For metadata of your own, add a column to the nodes of tar_dag()'s result
(its names can't be row, col, x, y or color_index), then call
dag_collapse() and ggplot_dag() yourself.
# each call is its own tar_dir(), so each plot actually prints - inside # one tar_dir({ ... }) block, only the last expression auto-prints targets::tar_dir({ targets::tar_script(list( targets::tar_target(x, 1), targets::tar_target(y, x + 1) )) tar_ggplot() }) targets::tar_dir({ targets::tar_script(list( targets::tar_target(x, 1), targets::tar_target(y, x + 1) )) tar_ggplot(node_color = "status", palette = targets_status_colors()) }) # the pipeline in stages, kept in the descriptions of its targets targets::tar_dir({ targets::tar_script(list( targets::tar_target(raw, 1, description = "ingest"), targets::tar_target(clean, raw + 1, description = "ingest"), targets::tar_target(fit, clean * 2, description = "model"), targets::tar_target(out, fit, description = "report") )) tar_ggplot(collapse_by = "description", node_size = "n", edge_width = "n") })# each call is its own tar_dir(), so each plot actually prints - inside # one tar_dir({ ... }) block, only the last expression auto-prints targets::tar_dir({ targets::tar_script(list( targets::tar_target(x, 1), targets::tar_target(y, x + 1) )) tar_ggplot() }) targets::tar_dir({ targets::tar_script(list( targets::tar_target(x, 1), targets::tar_target(y, x + 1) )) tar_ggplot(node_color = "status", palette = targets_status_colors()) }) # the pipeline in stages, kept in the descriptions of its targets targets::tar_dir({ targets::tar_script(list( targets::tar_target(raw, 1, description = "ingest"), targets::tar_target(clean, raw + 1, description = "ingest"), targets::tar_target(fit, clean * 2, description = "model"), targets::tar_target(out, fit, description = "report") )) tar_ggplot(collapse_by = "description", node_size = "n", edge_width = "n") })
The shape targets::tar_visnetwork() draws for each vertex type, as a
hard-coded copy - they belong to targets, not ggtargets, and are
checked against the installed targets version in the package's own
tests. It is the default shapes of tar_ggplot()/ggplot_dag()/
dag_layers(), so a pipeline's nodes are drawn by type: a regular target
(stem) is a circle, a dynamic-branching target (pattern) a square, and
an imported function and object an up and a down triangle. Imports are
only in the graph with tar_ggplot(targets_only = FALSE).
targets_node_shapes()targets_node_shapes()
A named character vector of shape names, one per type. The shapes
a node can take are "circle", "square", "diamond", "triangle"
and "triangle_down".
targets_node_shapes() dag <- as_dag( data.frame(from = c("a", "a", "b"), to = c("b", "c", "c")), nodes = data.frame( name = c("a", "b", "c"), type = c("stem", "stem", "pattern") ) ) ggplot_dag(dag)targets_node_shapes() dag <- as_dag( data.frame(from = c("a", "a", "b"), to = c("b", "c", "c")), nodes = data.frame( name = c("a", "b", "c"), type = c("stem", "stem", "pattern") ) ) ggplot_dag(dag)
The colors targets::tar_visnetwork() uses for target status, as a
hard-coded copy - they belong to targets, not ggtargets, and are
checked against the installed targets version in the package's own
tests, so a drift is caught rather than silently shipped. Fits the
palette argument of tar_ggplot()/ggplot_dag()/dag_layers()
directly, e.g.
tar_ggplot(node_color = "status", palette = targets_status_colors()).
targets_status_colors()targets_status_colors()
A named character vector of hex colors, one per status.
targets_status_colors() dag <- as_dag( data.frame(from = c("a", "a", "b"), to = c("b", "c", "c")), nodes = data.frame(name = c("a", "b", "c"), status = c("uptodate", "outdated", "errored")) ) ggplot_dag(dag, node_color = "status", palette = targets_status_colors())targets_status_colors() dag <- as_dag( data.frame(from = c("a", "a", "b"), to = c("b", "c", "c")), nodes = data.frame(name = c("a", "b", "c"), status = c("uptodate", "outdated", "errored")) ) ggplot_dag(dag, node_color = "status", palette = targets_status_colors())