Nodes/ComfyUI CV/CV Chart Matrix
ComfyUI Node

CV Chart Matrix

A similarity matrix rendered as a five-pixel image is useless — CV Chart Matrix fixes that

By bmad4ever·Created 3 months ago·Updated 14 days ago· 1
CV Chart Matrix
  • matrix
  • spec
◄title►
◄row_labels►
◄col_labels►
◄show_valuestrue►
◄decimals3►
◄value_rangeauto (data range)►
◄min_value0.00►
◄max_value1.00►
◄paletteviridis►
◄themedark►
◄chart_height340►

What this is for

You have a 5×1 block of cosine similarities, or a 4×4 table of per-pair scores, or a method-by-metric comparison. In ComfyUI that lands as an NPARRAY, and the usual way to look at an array is Preview CV Array, which turns it into pixels - one anonymous pixel per cell, min-max normalized so the absolute numbers vanish. A 5×1 matrix becomes a five-pixel-wide image. Technically a picture of your data. Practically useless.

CV Chart Matrix draws the thing as an actual labelled heatmap, using the Apache ECharts library vendored in the pack. Every cell shows its value if you want, hovering gives you the row name, column name and full-precision number, and the colour scale is labelled in the array's own units. It's the node you reach for when the numbers matter more than the shape.

How it works

The node builds the whole ECharts option object in Python - palettes, labels, colour scale, decimals, theme - and hands that JSON to web/cv_charts.js, which does nothing but instantiate the chart. That split is the nice bit: all the decisions about what the picture says are server-side and inspectable. The option comes back out of the node as the spec STRING, so you can wire it into Preview as Text and read the charted cells without taking a screenshot.

Size-1 axes get squeezed first, so an (N, 1, M) block - the shape a lot of the pack's point nodes emit - charts as N × M rather than erroring on a 3-D array. There are also hard caps (40,000 cells) and it says so instead of trying to freeze your browser tab with a megapixel option object.

The inputs that matter

matrix is the required array, rows by columns. title is optional and empty draws none.

Then the two you'll actually spend time on:

  • row_labels / col_labels - one name per row/column, as a JSON list or ; / newline / comma separated text. Missing names fall back to row 0, row 1, … and a short list never breaks the chart. Handy trick: feed the same ;-separated label string you use to label a tile sheet of images, so row i of the matrix provably refers to the figure labelled i.
  • value_range - auto (data range) uses the array's own min/max, and this is the trap: on similarities clustered between 0.42 and 0.45, auto stretches those three hundredths across the full ramp and makes nothing look like a huge difference. manual pins the scale so colours mean the same thing across runs - 0 to 1 for similarities. symmetric around zero centres a diverging ramp on 0, which is what signed differences and correlations want. min_value/max_value only apply with manual.

The rest is presentation: show_values (on by default - turn it off when the cells get too small for text), decimals, palette (viridis matches Preview CV Array's heatmap render; coolwarm (diverging) belongs with the symmetric range), theme (light when the PNG is going into a document) and chart_height.

One output: spec. Since the node is an output node, the chart renders in the graph when you hit Queue - you don't have to wire anything for it to appear. Wire spec into Preview as Text if you want the numbers as text.

Install

It's one pack, so the same steps as every other CV node:

cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
# restart ComfyUI

Or in ComfyUI Manager, search ComfyUI CV (registry publisher bmad4ever). Either way the pack needs Python ≥ 3.12, a recent ComfyUI built on the V3 node API, and opencv-contrib-python-headless~=5.0.0.93 - which the requirements file installs for you. No models to download for this node; the chart library is vendored in the repo.

Common issues

  • Nothing renders / blank node area. Reload the page after installing. The chart is a frontend widget, and a stale browser tab won't have the JS.
  • Contrib nodes all disappeared at once. If another pack pulled in plain opencv-python (or -headless, non-contrib), it overwrote the shared site-packages/cv2 and every contrib-backed node in the pack goes missing. The repo ships tools/repair_opencv_contrib.py - run --check to diagnose, --apply to fix. There is no install-time guard against this, and it's the single most likely way this pack breaks on you.
  • Colours look dramatic and meaningless. That's the auto (data range) default doing its job. Switch to manual.
Categoryimage/CV/plots

Inputs (12)

NameTypeDefaultDescription
matrixNPARRAY2-D array (rows x columns). Size-1 axes are squeezed away, so an (N, 1, M) block charts as N x M.
titleSTRINGHeading drawn above the chart. Empty draws none.
row_labelsoptSTRINGName per row, as a JSON list or ';' / newline / ',' separated text. Missing names fall back to 'row 0', 'row 1', ...
col_labelsoptSTRINGName per column, same formats. Missing names fall back to 'col 0', 'col 1', ...
show_valuesoptBOOLEANtruePrint each cell's value inside it, so the table reads without hovering. Turn off for large matrices where the text would not fit.
decimalsoptINT30–8Significant decimals for the printed cell values and the tooltip.
value_rangeoptCOMBOauto (data range)What the color scale spans. 'auto' uses the array's own min/max - which makes tiny differences look dramatic; 'manual' pins it to the meaningful range (0-1 for similarities) so the colors mean the same thing across runs; 'symmetric around zero' centers a diverging ramp on 0 for signed data (differences, correlations).
min_valueoptFLOAT0.00-1000000000–1000000000Color scale minimum ('manual' range only).
max_valueoptFLOAT1.00-1000000000–1000000000Color scale maximum ('manual' range only).
paletteoptCOMBOviridisColor ramp. 'viridis' matches 'Preview CV Array''s heatmap render; 'coolwarm (diverging)' belongs with 'symmetric around zero'.
themeoptCOMBOdarkChart colors. 'light' is for a PNG that will be pasted into a document.
chart_heightoptINT340160–2048Height of the chart area inside the node, in pixels.

Outputs (1)

NameTypeDescription
specSTRINGThe chart definition as JSON - the exact option the frontend renders. Wire into 'Preview as Text' to read the charted cells.