T is primarily an orchestration engine and does not currently provide
its own native low-level plotting library. Instead, T’s
show_plot() function supports a wide range of visualization
libraries across R, Python, and Julia:
ggplot2matplotlib,
seaborn, plotly, altair,
plotnineTidierPlots.jl,
Plots.jl, and Makie.jl /
CairoMakieOne of T’s unique features is Automated Visual Metadata Capture. When you generate a plot in an R, Python, or Julia node, T “sees” the plot object and automatically extracts its structural metadata during the build process.
Generating a plot in T is as simple as returning a plot object from a foreign-language node.
p = pipeline {
p_ggplot = rn(
command = <{
library(ggplot2)
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
labs(title = "Fuel Economy")
}>
)
}
p = pipeline {
p_matplotlib = pyn(
command = <{
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.scatter([2.6, 3.2, 3.4], [21.0, 19.2, 18.1])
ax.set_title("Fuel Economy")
fig
}>
)
}
In each case, T recognizes that the node result is a visualization.
p = pipeline {
p_plotsjl = jln(command = <{
using Plots
plot([1, 2, 3], [3, 4, 5], title = "Fuel Economy")
}>)
}
When you build a pipeline containing these nodes, T creates two
artifacts for each plotting node in the Nix store: 1. The
Artifact: The serialized plot object (e.g., an RDS file for
ggplot2). 2. The Metadata
(viz): A JSON representation of the plot’s
contents.
T automatically extracts: - Title: The main title of
the plot. - Backend: The runtime used to produce the
plot ("R", "Python", or "Julia").
- Class: The stable plot class tag (for example
"ggplot", "plotnine",
"tidierplots", "plotsjl", or
"makie"). - Labels: Axis labels and
legends. - Layers: The types of geometries present
(e.g., “point”, “line”). - Mappings: For
grammar-of-graphics style backends such as ggplot2,
plotnine, and TidierPlots.jl.
read_node()Because T captures this metadata, you can inspect the “contents” of a plot directly from your T scripts or the REPL without needing to render it to an image.
When you call read_node() on a plotting node, T returns
the metadata dictionary instead of the binary
artifact.
> g = read_node(p.p_ggplot)
> print(g.title)
"Fuel Economy"
> print(g.layers)
["point"]
> print(g.labels)
{ x: "wt", y: "mpg", title: "Fuel Economy" }
This “Transparent Plotting” enables programmatic verification of visualizations—for example, a test script could assert that a generated plot has the correct title and includes a regression line layer.
Plot metadata is pretty-printed in the REPL instead of dumping raw runtime-specific structures.
For example, a ggplot node read through
read_node() displays as a structured object with fields
such as:
classbackendtitlemappinglabelslayersThis makes plotting nodes inspectable even when the underlying
artifact is binary (.rds, Python pickle, or Julia
serialization output).
When using Quarto with
T pipelines, it is important to understand how read_node()
behaves depending on the language of the code chunk.
Within a {t} code block, read_node()
follows the same behavior as the REPL: it returns the JSON
metadata dictionary.
```{t}
#| echo: false
g = read_node(p.p_ggplot)
print(g.title)
```
Output: “Fuel Economy”
This is useful for including summary information about your visualizations directly in the text of your report.
To actually render the plot in your report, you must
use an {r} or {python} chunk. However, in
these environments, read_node() is a preprocessor token
that T replaces with the absolute path string to the
artifact in the Nix store.
Because read_node() returns a path, you must manually
load the artifact using the specialized reader for that language.
```{r}
#| echo: false
# read_node("p_ggplot") becomes '/nix/store/.../artifact'
p <- readRDS(read_node("p_ggplot"))
p
```
```{python}
#| echo: false
try:
import cloudpickle as pickle
except ImportError:
import pickle
# read_node("p_matplotlib") becomes '/nix/store/.../artifact'
with open(read_node("p_matplotlib"), "rb") as f:
fig = pickle.load(f)
fig
```
This dual behavior ensures that you can use T for programmatic inspection and R/Python/Julia for high-fidelity visual rendering, all while maintaining strict Nix-based reproducibility.
show_plot()show_plot() renders a plotting artifact in a fresh Nix
sandbox, writes the rendered image to _pipeline/, and then
opens the image locally.
It accepts:
rn() / pyn() nodejln() nodeComputedNoderead_node() result that still points back to a built
plot nodeThe rendered output is currently written as a PNG file under
_pipeline/.
Add an opener in tproject.toml if you want to override
the default viewer:
[visualization-tool]
command = "xdg-open"The value must be a single executable name or an absolute path to an executable. When no custom tool is configured, T falls back to:
open on systems where it is availablexdg-open otherwisep = rn(command = <{
library(ggplot2)
ggplot(mtcars, aes(wt, mpg)) + geom_point()
}>)
show_plot(p)
show_plot(p) returns the local path of the rendered PNG
after launching the viewer.
show_plot() renders the plot by reloading the stored
artifact inside a Nix sandbox:
ggplot2 to
be present in [r-dependencies].packages.matplotlib and cloudpickle in
[py-dependencies].packages.seaborn, matplotlib, and
cloudpickle in
[py-dependencies].packages.plotly,
kaleido (for static image export), and
cloudpickle in
[py-dependencies].packages.altair,
vl-convert-python (preferred), and cloudpickle
in [py-dependencies].packages.plotnine,
pandas, and cloudpickle in
[py-dependencies].packages.TidierPlots in
[jl-dependencies].packages.Plots and
any backend package you explicitly use in
[jl-dependencies].packages.CairoMakie for headless reproducibility;
CairoMakie is mandatory in
[jl-dependencies].packages to use show_plot()
with Makie objects. T automatically activates the CairoMakie backend
during the render process.When you use these libraries in a pyn() or Julia
plotting node, T’s static analyzer will automatically detect the imports
and prompt you to add the required rendering dependencies to your
tproject.toml if they are missing.
| Detected Import | Automatically Suggested Packages |
|---|---|
import matplotlib |
matplotlib,
cloudpickle |
import seaborn |
seaborn,
matplotlib, cloudpickle |
import plotnine |
plotnine,
pandas, cloudpickle |
import plotly |
plotly, kaleido,
cloudpickle |
import altair |
altair,
vl-convert-python, cloudpickle |
using TidierPlots /
import TidierPlots |
TidierPlots |
using Plots /
import Plots |
Plots |
using Makie /
import Makie |
Makie |
using CairoMakie /
import CairoMakie |
CairoMakie |
Example project configuration:
[r-dependencies]
packages = ["ggplot2"]
[py-dependencies]
version = "python314"
packages = ["matplotlib", "plotnine", "seaborn", "plotly", "kaleido"]
[jl-dependencies]
version = "lts"
packages = ["TidierPlots", "Plots", "Makie", "CairoMakie"]
[visualization-tool]
command = "xdg-open"_pipeline/When you call show_plot(), T creates local helper files
in _pipeline/, including:
This keeps the visualization workflow aligned with T’s existing pipeline artifact conventions.
See the T Pipeline Demos for real-world examples of pipelines generating interactive and static reports.