Prompt Matrix
The X/Y Plot ComfyUI never shipped — PromptMatrix does it in one node
- model
- clip
- vae
- latent_image
- composite
- cells
If you came over from AUTOMATIC1111, you know the drill: drop in a base prompt, list a few variations, and get back a labeled grid that shows exactly what changed. That's X/Y Plot, and it's one of the few things people routinely say ComfyUI does worse. This node is that feature, folded into a single node that runs the whole sampling pipeline - encode, sample, decode - so you never have to hand-wire a grid of KSamplers.
What it actually does
Wire in your model, clip, and vae like you would for any normal generation, type a base prompt, and give it two axis strings. Each axis is comma-separated, where the first value is the search key and everything after it are the replacements. So with positive_prompt of a beautiful photo of a SUBJECT SETTING, an X-axis of SUBJECT, dog, cat, duck and a Y-axis of SETTING, in a forest, in a restaurant, you get a 3×3 grid from dog in a forest onward.
Under the hood it's the boring-but-correct approach: for every cell it substitutes the keys in both prompts with str.replace() (case-sensitive, so subject will not match SUBJECT), tokenizes, encodes, samples with the node's steps/cfg/sampler_name/scheduler/denoise, and decodes with the VAE. All of that happens inside the node - no separate KSampler, CLIP Text Encode, or VAE Decode needed. It then pastes the cells into a white-labeled composite, A1111 style.
You get two outputs. composite is the labeled grid image, ready for the Save Image node - that's the one you'll actually look at. cells is the flat batch of individual images if you want to save or process each variation separately. A nice touch: if you pass a latent_image in, its dimensions override width/height.
The inputs that matter
- positive_prompt / negative_prompt - your base prompts, with placeholder words the axes will swap in.
- x_axis / y_axis - the variations. Remember: first entry is the search key, not a value.
- seed - this is where it gets clever. The widget has ComfyUI's native "control after generate" dropdown, so you can set it to increment or randomize and just queue runs. No manual seed node juggling.
- batch_in_node / seed_count - flip this on to generate several grids in one execution with incrementing seeds, instead of queueing runs.
Quoting is worth knowing: only double quotes group a value containing commas ("on a long, winding road" works), single quotes are always literal, and \, escapes a comma. An empty axis or one starting with a comma gets skipped entirely.
The magic keys
Instead of substituting text, you can vary a sampling parameter by using <seed>, <steps>, <cfg>, or <denoise> as the first axis entry. X-axis: <cfg>, 5.0, 7.5, 10.0 gives you three columns at different CFG scales - a genuinely fast way to find the sweet spot. <seed> has two modes: list explicit seeds, or give the bare key with batch_in_node on and it auto-generates seed_count seeds. Values are validated before sampling, so you get a clear error instead of a silent fail.
Installing it
Either use ComfyUI Manager (search for comfyui-prompt-matrix) or:
cd ComfyUI/custom_nodes
git clone https://github.com/ColKernel0x8E/comfyui-prompt-matrix.git
Then restart ComfyUI. That's the whole install - there's no requirements.txt, no model downloads, nothing but ComfyUI core. Refreshingly lightweight compared to most custom nodes.
Gotchas
The single-threaded sampling loop means big grids take a while - a 5×5 is 25 full generations, so budget accordingly. The pipeline is hardcoded, so no per-cell tricks like VAE tiling or per-cell LoRA toggles. And the most common beginner stumble is assuming the first axis value gets used as a variation; it's the search key, so dog, cat on an axis with no dog in the prompt substitutes nothing. Long labels can also get truncated on the composite. None of these are dealbreakers - for iterating on prompt wording or CFG with a consistent seed, this is the node to reach for.
Inputs (19)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| clip | CLIP | — | |
| vae | VAE | — | |
| positive_prompt | STRING | — | |
| negative_prompt | STRING | — | |
| x_axis | STRING | — | |
| y_axis | STRING | — | |
| seed | INT | 00–18446744073709550000 | — |
| batch_in_node | BOOLEAN | false | — |
| seed_count | INT | 11–256 | — |
| steps | INT | 201–200 | — |
| cfg | FLOAT | 7.00–30 | — |
| sampler_name | COMBO | 44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38 | |
| scheduler | COMBO | 9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3 | |
| width | INT | 51264–8192 | — |
| height | INT | 51264–8192 | — |
| denoise | FLOAT | 1.000–1 | — |
| max_composite_width | INT | 2048512–16384 | — |
| latent_imageopt | LATENT | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| composite | IMAGE | — |
| cells | IMAGE | — |