Painter Sigmas Graph
Draw the denoise curve you actually want, then plug it into a sampler
- sigmas
Sampler choice is the loud half of sampler tuning; the sigma schedule is the quiet half, and on 2026's flow-matching models it's often the half that actually matters. The stock scheduler list is a fixed menu - Karras, beta, sgm_uniform and friends. Painter Sigmas Graph hands you a canvas instead. Drag the control points, get a SIGMAS tensor, feed it to a sampler.
One honest caveat before the sales pitch: on flow-matching models the trajectory is already nearly straight, so the more violently you reshape the curve, the more it usually costs you. A 60-sampler sweep on Z-Image Turbo landed on that conclusion - conservative schedules beat aggressively redistributed denoising effort, and Karras-style curves were the worst offenders. This node is for the cases where you know what shape you want, not for a magical curve that fixes everything.
The shape of the thing
The node outputs exactly one thing: sigmas. No latent input, no steps output - the author stripped an existing sigma-graph node (ComfyUI_Element_easy's curve node, itself derived from TWanSigmaGraph by Temult, MIT) down to the one job. Wire sigmas into a sampler that takes a sigma override and you're done; it won't work on the plain KSampler, which picks its own.
Three widgets:
steps- default 20. The curve's x axis gets divided into this many segments, producingsteps + 1sigma values. This is the total schedule length before trimming, so decide your step count here, not in the sampler.start_step- default 0. Discards that many sigmas off the front of the curve. Since sigmas descend from 1 toward 0, that means sampling starts further down the schedule - less noisy, never at pure noise. It's the trick for a resume or a partial second pass; what you give up is the structural work the early steps do.graph_data- the JSON the on-node editor writes:{"points": [{"x": 0.0, "y": 1.0}, {"x": 1.0, "y": 0.0}], "mode": "curve"}. You can hand-type it or paste a preset's JSON straight in, which is a nice trick for sharing curves in a chat thread.
x runs 0 → 1 across generation, y is the sigma value: 1 is pure noise, 0 is fully denoised, and the output range is locked to 0–1. In "curve" mode the points are joined with a natural cubic spline (solved with the Thomas algorithm); in "linear" mode they're joined with straight segments. Both are clamped, so you can't accidentally demand a sigma of 1.4.
Stuff that surprises people
You can't get a flat plateau. After sampling the curve, the node sorts the values descending and then forces each one to be strictly greater than the next by nudging it 1e-5. It's a safety rail against a sampler choking on a non-decreasing schedule, and it's why a deliberately horizontal stretch in your curve comes out as a very gentle ramp.
Bad JSON doesn't crash the run. If graph_data won't parse, the node tries to salvage bare numbers from the string, and failing that prints a warning and falls back to the default 1 → 0 line. Points with NaN or infinity are silently skipped, out-of-range y values are clamped, and missing endpoints at x = 0 or x = 1 get synthesised. The upside is resilience; the downside is that a malformed curve can look like "the node does nothing".
If fewer than two sigmas survive trimming - set start_step past the end and it's clamped to steps - 1, but a pathological curve can still get there - the output falls back to [1.0, 0.0], i.e. the dumbest possible schedule.
Presets live on the server, not in your workflow. The on-node combo box lists saved curves with S / D / R buttons (save, delete, reset), and saving writes to presets/PainterSigmasGraph_presets.json inside the pack folder via a small HTTP route the pack registers. The shipped file includes a few curves the author uses (an 8-step detail curve, LTX 2.5's parameters, a beta-style 6-step) - Chinese names, western maths. But the curve itself is just the graph_data widget, so it travels inside your workflow; only the named preset shortcuts are per-machine. Move the pack to another install and your saved presets go with the folder, not with the PNG.
Installing it
Nothing special - it's one file in a pack you probably already have:
cd ComfyUI/custom_nodes
git clone https://github.com/princepainter/ComfyUI-PainterNodes
Restart. The node imports torch, json, math and nothing exotic, and the requirements file is just soundfile and numpy for the rest of the pack. It appears under the Painter/Sigmas category, which is a long scroll away from the core scheduler nodes.
If your sampler ignores the sigmas you just fed it, check the sampler before the graph - some schedulers (and some custom sampler nodes) apply their own sigma shift and quietly discard what you handed them. That failure mode causes a lot of "my curve does nothing" posts, and it isn't this node's fault.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| steps | INT | 201–1000 | 总步数(曲线被均分成 steps 段,共产生 steps+1 个 sigma) |
| start_step | INT | 00–1000 | 起始步数:丢弃曲线前 start_step 个 sigma,输出从这一步开始的 sigma 序列 |
| graph_data | STRING | {"points": [{"x": 0.0, "y": 1.0}, {"x": 1.0, "y": 0.0}], "mode": "curve"} | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| sigmas | SIGMAS | — |