XYZ Plot (Artify)
XYZ Plot (Artify)
- images
- xyz_plot
XYZ plots are how you answer "does Euler vs. Heun actually matter at this CFG?" without guessing. In Automatic1111 and Forge they're a built-in script; in ComfyUI you have to bring your own, and the classics are the Efficiency Nodes XY Plot and the core X/Y/Z Plot. This one's pitch is different: no converting widgets to inputs, no typing a target node's ID. XYZ Plot (Artify) gives you dropdowns populated live from the widgets already sitting in your graph - you pick what to sweep, drop in the values, and it queues the whole grid for you.
It's a young pack (basically zero community footprint as of this writing), so expect a couple of rough edges, but the core idea is sound and it saves real time on sampler/CFG/LoRA-strength comparisons.
How it works
The trick is a two-stage run. First, a bit of frontend JS scans every node on the canvas and builds a reference for each widget that looks like #12::KSampler::cfg. That reference is what lands in input_x/input_y/input_z - which is why the dropdowns only show widgets, not node IDs you have to look up.
On the first run, the node:
- Splits
value_x/value_y/value_zon semicolons. - Writes
result.jsonplus aworkflow.jsonintoComfyUI/output/<folder_name>. - Deep-copies the prompt for every combination, overwrites the chosen widget with the next value, and re-queues each cell as a separate partial-execution job via the local
/promptendpoint - one queue entry per grid cell.
Each queued cell re-executes the plot node in "cell mode," sees the x/y/z index tucked into its inputs, and saves that single image as something like x2_y4_1.jpeg. If a folder with the same name already exists, it gets moved to _old_<timestamp> first rather than merged - archiving is always-on and you can't turn it off.
The inputs that matter
input_x/input_y(required): dropdowns of every widget on your other nodes. Pick e.g. a KSampler'ssampler_nameandcfg.value_x/value_y/value_z: multiline strings, semicolon-separated.6.5; 7.0; 7.5for CFG,Euler; Heunfor samplers.input_z/value_z(optional): leaveinput_zatnoneandvalue_zempty if you don't want a Z axis - you'll get an error if you fill values but don't pick a target.output_folder_name: supports tokens like%date:yyMMdd%,%inputx_node_title%,%inputx_widget_name%. The default is verbose but genuinely useful.images: wire this from your VAE decode so the node has something to save.
The one output, xyz_plot (type ARTIFY_XYZ_PLOT), plugs into XYZ Viewer (Artify).
Install
The pack is tiny and dependency-free - requirements.txt is effectively empty, no models to download.
cd ComfyUI/custom_nodes
git clone https://github.com/ArtifyGames/comfyui-testing.git
Restart ComfyUI and refresh the browser tab. Or use ComfyUI Manager and search for comfyui-testing (pack title "ComfyUI-Testing").
Where people get burned
- Empty dropdowns: they're populated from the live graph, and the node excludes itself - the node you want to sweep has to exist on the canvas first.
- Z error out of nowhere: if you leave
input_zonnone, clearvalue_z. The node throwsvalue_z was provided, but input_z is not selectedotherwise. - Combo widgets: if you sweep a sampler or scheduler combo, the values have to be real option names. Free-text and number widgets are the safest targets.
- Queue spam: a 3×3 sweep is 9 queue entries plus the initial run. Bigger grids bury your queue - that's by design, since each cell is a separate render with its own seed handling.
If the wrong cells keep coming out, double-check that the node title or widget you selected still exists - the reference is re-resolved on every run, so renaming a target node can break the ref and raise Widget '...' was not found on node #....
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| output_folder_name | STRING | %date:yyMMdd%_X_%inputx_node_title%_%inputx_widget_name%_Y_%inputy_node_title%_%inputy_widget_name%_Z_%inputz_node_title%_%inputz_widget_name% | — |
| input_x | COMBO | none | 1 options: none |
| value_x | STRING | 6.5; 7.0; 7.5 | — |
| input_y | COMBO | none | 1 options: none |
| value_y | STRING | 20; 30; 40 | — |
| input_zopt | COMBO | none | 1 options: none |
| value_zopt | STRING | Euler; Heun | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| xyz_plot | ARTIFY_XYZ_PLOT | — |