Open source
From a Table to a Map
Standpoint reads a comparison table and draws a positioning map, named axes included. One command does it.

Everyone has met this table. Options as rows, criteria as columns, ratings in the cells: eight programming languages compared on performance, ecosystem, tooling, job market. The table is honest, complete, verifiable. It is also unreadable: faced with eight columns of figures, the eye gives up and the choice falls back on gut feeling, the very thing the table was meant to prevent.
Standpoint turns that table into a map. Each option becomes a point on a plane; two nearby points are two similar profiles; the ends of the axes carry plain words, in the language of your columns. The question the map answers fits on one line: where do you stand?
A table of programming languages becomes a map: the leader at the top right, challengers along each axis, everyone else in the legend.
Motivation
Positioning maps are a staple of marketing and consulting: people sketch them on whiteboards to place brands, products, competitors. The method that builds them properly, Principal Component Analysis (PCA), is more than a century old: given many columns of numbers, it finds the few directions along which the options actually differ the most, so a whole row of ratings collapses into two numbers that still carry most of what distinguishes it from the rest.
The method is well known; what costs time is everything around it. Orienting the map so it reads the right way. Naming the axes with words a management committee understands. Coloring, labeling without overlaps, exporting at print quality. That workshop labor is what Standpoint automates: one command reads the table (CSV or Markdown) and writes the figure, as SVG and PNG, plus a YAML file with every coordinate and every coefficient.
One architectural choice matters to me: everything runs on your machine. The computation, the drawing, and even the axis naming, handled by a local language model running under Ollama, a program that runs open models on your own computer. Your table, which sometimes holds internal notes about your competitors, is never uploaded anywhere.
How it works
First step: put the criteria on an equal footing. A 5-point comfort rating and a price in thousands of euros cannot be compared as they are; without care, the column with the biggest numbers would crush all the others. Each column \(j\) is therefore centered on its mean \(\mu_j\) and scaled by its standard deviation \(\sigma_j\), the usual measure of spread:
After this rescaling, every criterion weighs the same: a difference of one means "one standard deviation above average" everywhere.
Second step, the mathematical core. Picture the options as a cloud of points in an eight-dimensional space, one dimension per criterion. PCA looks for the plane that, viewed head-on, spreads that cloud out as much as possible: the two directions \(v_1, v_2\) along which the options pull apart the most. They are the top two eigenvectors of the covariance matrix of the rescaled data, the ones tied to the largest eigenvalues \(\lambda_1 \ge \lambda_2\). An option's position on the map is then its projection:
A flat map remains a summary of a richer space. The share of information it keeps can be measured, and Standpoint prints it on the figure:
Around 80%, the map tells the table's story faithfully; below that, read it as a sketch.
Third step, orientation. A raw PCA map comes out facing an arbitrary way: nothing forces the "good" corner to sit at the top right. Standpoint rotates the plane to put your reference option there, the one whose position you want to tell. One edge case is handled: a reference rated top marks on everything would land far away from everyone; it is placed just past the best competitor instead, where the map stays legible.
Last step, the words. PCA axes remain weighted sums of your columns, so they stay readable: one axis may lean on performance and concurrency, the other on ease of learning and job market. A local model reads those weights and names the four poles as positive qualities, in the table's language (English, French or Spanish, detected from the column names). A column where lower is better, marked "(↓)" as in Price (↓), yields a pole that names the benefit, "Affordable", never the drawback. A guard filters out acronyms, negations and antonym pairs.
The tool judges itself: its map of the competing landscape (factoextra, FactoMineR, prince…) is produced by Standpoint.
The same engine comes in seven forms: a
Python library (import standpoint), two twin command-line tools, a
browser GUI, an HTTP API, an MCP server for agents, and a fully static build where the engine, compiled
to WebAssembly, runs in the visitor's browser with no server at all. The figure itself is hand-authored
SVG, with no charting library: every stroke is a decision, not an inheritance from a template.
Conclusion
An honest table deserves better than a gut reading. The map does not replace the table: it gives the overview, the one that decides which rows to reread closely. And because the axes remain combinations of your own criteria, the map holds up in a meeting: every position traces back to the original figures, kept in the output YAML.
Standpoint is open source under the BSD
license: pip install standpoint, then one command on your CSV. The
code, the examples and the documentation live at github.com/warith-harchaoui/standpoint. Bring a table; leave knowing where you
stand.