Nodes/ComfyUI CV/CV Plot 2D (cv2.plot)
ComfyUI Node

CV Plot 2D (cv2.plot)

Turn a column of numbers into an image you can actually save

By bmad4ever·Created 4 months ago·Updated 14 days ago· 1
CV Plot 2D (cv2.plot)
  • values
  • x_values
  • plot
◄width640►
◄height400►
◄drawline►
◄line_width1►
◄show_gridtrue►
◄grid_lines10►
◄show_texttrue►
◄value_rangeauto (data range)►
◄min_x0.00►
◄max_x1.00►
◄min_y0.00►
◄max_y1.00►
◄line_color(0, 255, 0)►
◄background_color(30, 30, 30)►
◄axis_color(200, 200, 200)►
◄grid_color(70, 70, 70)►
◄text_color(230, 230, 230)►
◄print_point_index-1►
◄y_downfalse►

Charts inside ComfyUI are usually either interactive widgets (great for reading, useless for output) or a bunch of drawing nodes. CV Plot 2D takes the third path: it renders a plot as an ordinary IMAGE using cv2.plot.Plot2d, OpenCV's own plotting module. Because it's just an image, it composites, diffs, saves and stacks like anything else - which is exactly what you want when the plot is going into something: a report sheet, a video frame, a PNG that lands next to the data it describes.

It draws one series, with no legend and no labels. This is not the ECharts family - if you need several series, category names, tooltips or a threshold line, the pack's CV Chart Series / CV Chart Scatter / CV Chart Matrix nodes are the interactive, fancier option. Pick by destination: image out → this; inspect in the UI → those.

What goes in

values is the series. A 1-D array (or (N,1) / (1,N)) gets plotted against its sample index; an (N,2) array is read as x,y pairs. x_values (optional) overrides the x axis, ignored when values is already pairs. Larger values are drawn upward by default.

Then the layout: width (default 640) and height (default 400). Watch the clamps - cv2.plot itself clamps width up to 400 and height up to 300, so asking for a 200-wide plot gets you a 400-wide one. That's the module, not the node.

draw picks line (connects consecutive samples) or points only (marks them without segments). Points-only is the honest choice when the samples are independent measurements rather than a signal - joining them implies continuity you don't have.

Cosmetics are all optional widgets: line_width, show_grid, grid_lines, and the colors as BGR tuples (line_color (0, 255, 0), background_color (30, 30, 30), axis_color, grid_color, text_color). BGR, not RGB - the pack is consistent about this, but it's the kind of thing you'll get wrong once.

Two more that earn their place:

  • value_range - auto (data range) lets Plot2d fit the axes, which is convenient and hides how big the values actually are; manual pins the axes with min_x / max_x / min_y / max_y. Manual is how you compare two runs side by side, and it's the reason those four inputs exist.
  • print_point_index - annotates ONE sample's value onto the plot. -1 is none. Perfect for calling out the winner in a comparison without a second annotation pass.
  • y_down (default false) flips the axis so larger values go down. Worth knowing: this is the opposite of raw cv2.plot, whose own default draws downward - the node corrects it, so the default here matches every other plot in the pack.

One output: plot, an IMAGE (BGR converted to ComfyUI RGB) ready for Save Image or compositing.

Install

Manager → search ComfyUI CV, or:

cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
cd comfyui_cv && pip install "opencv-contrib-python-headless~=5.0.0.93"

Restart. Python ≥ 3.12, V3 node API. Plot2d is a cv2 class that only accepts float64, which the node handles for you - feed it whatever dtype you have.

Common issues

  • Blank or empty plot - either the input was empty (which renders an empty plot rather than failing) or the values are all identical and the auto range collapsed. Use manual range to check.
  • Your requested size was ignored - the 400/300 clamps above.
  • The colors are wrong - BGR tuples. Swap the first and third numbers.
  • Multiple series came out only once - one series per node. Use CV Chart Series if you need more, or stack images.
  • Values went the wrong way up - y_down is off by default specifically so this node doesn't inherit cv2.plot's downward convention. If you turned it on for image-coordinate data, that's why.

Pack disclaimer as usual: LLM-assisted, personal, not production-grade, no promised updates. The nice thing about a plot is that a wrong one usually looks wrong.

Categoryimage/CV/plots

Inputs (21)

NameTypeDefaultDescription
valuesNPARRAYThe numbers to plot: 1-D (or (N, 1) / (1, N)) is plotted against the sample index; an (N, 2) array is read as x, y pairs. Converted to float64, which is the only dtype Plot2d accepts. Larger values are drawn UPWARDS (see y_down).
widthINT640400–4096Plot width in pixels. cv2.plot CLAMPS anything below 400 up to 400 - that is the module, not this node.
heightINT400300–4096Plot height in pixels; clamped up to 300 minimum by cv2.plot itself.
drawCOMBOline'line' connects consecutive samples; 'points only' marks them without the connecting segments - the honest choice when the samples are independent measurements rather than a signal.
x_valuesoptNPARRAYOptional x coordinate per sample (same length as values). Without it samples are plotted against their index. Ignored when values is (N, 2).
line_widthoptINT11–16Stroke width of the plotted line in pixels.
show_gridoptBOOLEANtrueDraw the background grid.
grid_linesoptINT101–100Number of grid divisions when the grid is shown.
show_textoptBOOLEANtrueDraw the axis value texts (the min/max readouts cv2.plot prints along the axes).
value_rangeoptCOMBOauto (data range)'auto' lets Plot2d fit the axes to the data - which hides how big the values are in absolute terms. 'manual' pins the axes so two plots of different runs are comparable.
min_xoptFLOAT0.00-1000000000–1000000000Left edge of the x axis ('manual' range only).
max_xoptFLOAT1.00-1000000000–1000000000Right edge of the x axis ('manual' range only).
min_yoptFLOAT0.00-1000000000–1000000000Bottom of the y axis ('manual' range only).
max_yoptFLOAT1.00-1000000000–1000000000Top of the y axis ('manual' range only).
line_coloroptSTRING(0, 255, 0)Series color as a BGR tuple, e.g. '(0, 255, 0)'.
background_coloroptSTRING(30, 30, 30)Plot background color, BGR.
axis_coloroptSTRING(200, 200, 200)Axis line color, BGR.
grid_coloroptSTRING(70, 70, 70)Grid line color, BGR.
text_coloroptSTRING(230, 230, 230)Axis text color, BGR.
print_point_indexoptINT-1-1–1000000Prints the value of ONE sample onto the plot: the index to annotate, or -1 for none. Useful to call out the winner of a comparison.
y_downoptBOOLEANfalseFlips the y axis so larger values go DOWN, matching image coordinates (or a cost/error where lower is better). Off - the default - draws larger values UP, like 'CV Chart Series' and every other plot. Note this is the OPPOSITE of raw cv2.plot, whose own default draws downward; the node corrects it.

Outputs (1)

NameTypeDescription
plotIMAGEThe rendered plot as a normal IMAGE (BGR converted to ComfyUI RGB), ready for Save Image, compositing or stacking next to the data it describes.