MyXYZHelper
The index-to-grid-position engine behind DemonAlone's XYZ plots
- row_list
- column_list
- page_list
- row_value
- column_value
- page_value
- XYZ_GRID_CONTROL
If you've ever wanted a proper XYZ comparison grid in ComfyUI - same prompt, different seeds down the rows, different CFG across the columns, maybe a third axis of checkpoints split across separate pages - you'll have run into the two competing designs for building one. One is the "monolithic" style: a single node owns the whole sweep, re-samples every combination internally, and hands you back a finished grid (that's how the Efficiency Nodes XY plot or Fill-Nodes' FL_KSamplerXYZPlot work). The other is the DIY style, where the plotting logic gets split into small pieces you wire around your own sampling pipeline, so it works with any sampler, any conditioning, any node you can hand an index to. MyXYZHelper is the second camp - the piece that tracks "which cell of the grid am I currently on" and generates the labels for it. It's credited straight to kenjiqq's well-regarded qq-nodes-comfyui pack in the README, not original DemonAlone work.
That split-apart design has real fans in the wild - people who use the qq-nodes lineage specifically like that separating the sampling from the grid bookkeeping means you can plot anything, not just the handful of parameters a monolithic XYZ node happens to hardcode support for.
How it works
You give it three lists - row_list, column_list, page_list - the values you want to sweep on each axis. Something upstream (typically a loop node iterating the full cross-product) increments an index once per rendered cell. MyXYZHelper takes that index and works out which row/column/page it currently corresponds to, then hands back each axis's current value as plain text, plus a bundle called XYZ_GRID_CONTROL that carries layout settings (label prefixes, font size, spacing) downstream to whatever actually assembles the final image.
The inputs and outputs that matter
row_list/column_list/page_list- required LISTs, the sweep values for each axis. Doing a plain 2D grid? Leavepage_lista single-item list.index- which cell you're currently on. In practice this gets wired from a loop counter, not typed by hand. The schema's max is a faintly ridiculous ~1.8×10^19 - ComfyUI's default unbounded-int ceiling, not a hint you're meant to actually get there.row_prefix/column_prefix/page_prefix- optional text stuck in front of the value on the label, e.g. setcolumn_prefixto"CFG: "so the header reads "CFG: 7.5" instead of a bare "7.5".font_size(10–40, default 20) andgrid_gap(up to 100, default 20) - cosmetic controls for the finished grid, consumed downstream rather than by this node itself.
Outputs: row_value / column_value / page_value (STRING) - wire whichever ones you're actually sweeping into the node that needs the current value for that cell. XYZ_GRID_CONTROL - feed this to the next stage of the pipeline (the pack's accumulator, or MyXYZSuperStacker); it's a custom type specific to this node family.
How to install it
ComfyUI Manager: search "DemonAlone-nodes-ComfyUI", install, restart. Manual: cd ComfyUI/custom_nodes && git clone https://github.com/DemonAlone/DemonAlone-nodes-ComfyUI, then restart. No models, no heavy dependencies - it's a pure-Python utility pack. One small tell if you go digging in the installed files: the module backing this node is still internally named SimpeStringGenerator_ComfyUI - typo and all - a leftover from wherever it got assembled from. Harmless, just confirms what the README's own credits already tell you: this corner of the pack is a repackage, not original code.
Common issues & troubleshooting
XYZ_GRID_CONTROL won't connect. It's a custom type, not a generic pipe - ComfyUI refuses the wire if you try to plug it into anything outside this node family, even something that superficially looks like it should accept "grid settings."
Labels come out blank or wrong. Check that index is actually being driven by your loop and not stuck at a fixed value. If index never advances, every "cell" reports the same row/column/page no matter how many times you sample.
Index outruns your lists. Nothing in the schema stops you feeding an index larger than row_list × column_list × page_list actually contains. Keep your loop's iteration count tied to the real size of your sweep, not a guess.
This node does nothing by itself. It doesn't sample, doesn't touch images, doesn't build the grid - it only computes position and labels. If you wanted one node that hands you a finished comparison sheet, pair this with the pack's accumulator and MyXYZSuperStacker, or reach for a monolithic plot node from another pack instead.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| row_list | LIST | — | |
| column_list | LIST | — | |
| page_list | LIST | — | |
| index | INT | 00–18446744073709550000 | — |
| row_prefixopt | STRING | — | |
| column_prefixopt | STRING | — | |
| page_prefixopt | STRING | — | |
| font_sizeopt | INT | 2010–40 | — |
| grid_gapopt | INT | 20 | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| row_value | STRING | — |
| column_value | STRING | — |
| page_value | STRING | — |
| XYZ_GRID_CONTROL | XYZ_GRID_CONTROL | — |