LZ XY Plot
The config node that sets up a sweep without sampling
- lz_pipe
- lz_pipe
- x_labels
- y_labels
- x_replace_key
- y_replace_key
- x_type
- y_type
- x_values
- y_values
- total_count
Systematic comparison - three checkpoints against two samplers - is the backbone of how people actually pick their defaults, and a grid of outputs is the format that makes the result legible. LZ XY Plot is the node that defines what you're comparing. It doesn't generate anything itself. It takes your axis definitions - x_type/y_type, the values for each, and the replace keys for prompt axes - and packages them into the lz_pipe, ready for a sampler downstream to consume.
It's the "declare your experiment" half of the system. LZXYPlotSampler folds config and sampling into one node; this one keeps the config separate so you can reuse it, inspect it, and share it with LZXYSampler, which is designed to read a pipe that LZXYPlot has already prepared.
The axis types
Both x_type and y_type offer the same seven options:
none- this axis doesn't vary; the sampler runs a single value.checkpoint- each line is a checkpoint filename; the sampler hot-swaps models.lora- each line isname:model_weight:clip_weight(weights optional, default 1.0).sampler/scheduler- each line is a sampler or scheduler name.positive/negative- each line is replacement text for a placeholder in the prompt.
x_values and y_values are multiline - one value per line - which is the detail beginners get wrong constantly. Comma-separated won't work; each candidate is a line. And at least one axis needs values, or the node raises an error when you try to run.
The replace keys and escape flag
For the positive/negative axes, x_replace_key/y_replace_key is the exact placeholder in your base prompt that gets swapped for each line. With replace_escape on (the default), the swap also converts underscores to spaces and escapes parentheses before matching. That's aimed at danbooru-style prompts where tags use spaces - but it means a placeholder written with underscores will be matched after underscores become spaces, which surprises people. If your replacement does nothing or inserts backslashes, check this flag and how your placeholder is written.
The outputs
It returns the enriched lz_pipe plus a pile of metadata: x_labels, y_labels (comma-joined), the replace keys, the axis types, the values as newline-joined strings, and - the one that matters - total_count, which is len(x_values) × len(y_values). That's your warning shot: if total_count says 600 and you're about to run a 20-step sampler, that's 600 generations. Math before commitment.
Installing it
Same pack as the whole XY family:
cd ComfyUI/custom_nodes
git clone https://github.com/liz-ils/ComfyUI-LZNodes
Restart ComfyUI, or ComfyUI Manager → search "ComfyUI-LZNodes". No dependencies beyond stock ComfyUI.
If you don't need to separate config from sampling, skip straight to LZXYPlotSampler - it combines everything this node does with the sampler itself, which for most first sweeps is the simpler starting point.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| x_type | COMBO | none | 8 options: none, checkpoint, diffusion_model, lora, sampler, scheduler, +2 |
| x_values | STRING | — | |
| y_type | COMBO | none | 8 options: none, checkpoint, diffusion_model, lora, sampler, scheduler, +2 |
| y_values | STRING | — | |
| x_replace_key | STRING | — | |
| y_replace_key | STRING | — | |
| replace_escape | BOOLEAN | true | — |
| lz_pipeopt | LZ_PIPE | — |
Outputs (10)
| Name | Type | Description |
|---|---|---|
| lz_pipe | LZ_PIPE | — |
| x_labels | STRING | — |
| y_labels | STRING | — |
| x_replace_key | STRING | — |
| y_replace_key | STRING | — |
| x_type | STRING | — |
| y_type | STRING | — |
| x_values | STRING | — |
| y_values | STRING | — |
| total_count | INT | — |