CV Chart Matrix
A similarity matrix rendered as a five-pixel image is useless — CV Chart Matrix fixes that
- matrix
- spec
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 torow 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.manualpins the scale so colours mean the same thing across runs - 0 to 1 for similarities.symmetric around zerocentres a diverging ramp on 0, which is what signed differences and correlations want.min_value/max_valueonly apply withmanual.
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 sharedsite-packages/cv2and every contrib-backed node in the pack goes missing. The repo shipstools/repair_opencv_contrib.py- run--checkto diagnose,--applyto 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 tomanual.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| matrix | NPARRAY | 2-D array (rows x columns). Size-1 axes are squeezed away, so an (N, 1, M) block charts as N x M. | |
| title | STRING | Heading drawn above the chart. Empty draws none. | |
| row_labelsopt | STRING | Name per row, as a JSON list or ';' / newline / ',' separated text. Missing names fall back to 'row 0', 'row 1', ... | |
| col_labelsopt | STRING | Name per column, same formats. Missing names fall back to 'col 0', 'col 1', ... | |
| show_valuesopt | BOOLEAN | true | Print each cell's value inside it, so the table reads without hovering. Turn off for large matrices where the text would not fit. |
| decimalsopt | INT | 30–8 | Significant decimals for the printed cell values and the tooltip. |
| value_rangeopt | COMBO | auto (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_valueopt | FLOAT | 0.00-1000000000–1000000000 | Color scale minimum ('manual' range only). |
| max_valueopt | FLOAT | 1.00-1000000000–1000000000 | Color scale maximum ('manual' range only). |
| paletteopt | COMBO | viridis | Color ramp. 'viridis' matches 'Preview CV Array''s heatmap render; 'coolwarm (diverging)' belongs with 'symmetric around zero'. |
| themeopt | COMBO | dark | Chart colors. 'light' is for a PNG that will be pasted into a document. |
| chart_heightopt | INT | 340160–2048 | Height of the chart area inside the node, in pixels. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| spec | STRING | The chart definition as JSON - the exact option the frontend renders. Wire into 'Preview as Text' to read the charted cells. |