Skip to main content

VisualMetrics

See the theory. Change the assumptions. Understand the model.

An interactive visual laboratory for statistics, statistical inference, econometrics, causal inference, machine learning and modern AI — in English, Arabic and French.

PyPI Python License Tests Labs Languages

Source code, issues and the full documentation live on GitHub: https://github.com/merwanroudane/visualmetrics · Documentation site · Changelog · Report a problem


See it in one minute

VisualMetrics walkthrough

A real recording: open the catalogue → search → open a lab → change the assumption → watch the animation explain itself frame by frame → read a proof → switch to Arabic.


Table of contents


What it is

A laboratory where a statistical idea is something you operate rather than read about. Each concept is a lab: you move the assumptions, watch what the estimator does, and read the consequence in words and in numbers at the same time.

It is a Python library, not a website. pip install visualmetrics gives you a package; visualmetrics gui starts a local application on your own machine, the same way Jupyter does. Nothing is hosted and nothing leaves your computer.

What it is not

  • Not a proof assistant. The 13 proofs are human-written arguments, checked for internal consistency, not machine-verified.
  • Not a substitute for a textbook. It is built to sit beside one.
  • Not a research output package. It uses real estimators and reports honest numbers, but its purpose is understanding. For publication tables use statsmodels, linearmodels or R.
  • Not an assessment system. The self-checks explain their answers and grade nothing.
  • Not a claim that a simulation proves anything. That distinction is enforced in code and in the test suite.

Install

pip install "visualmetrics[gui]"

That is the normal install: the application, the figures and all 47 labs.

Just the library, without the interface
pip install visualmetrics

Pulls only NumPy, SciPy and platformdirs. You get the catalogue, trilingual search, the glossary, the proofs, the teaching material and the whole numeric engine — every estimator, test and covariance matrix.

Drawing a figure needs the viz extra. Ask for one without it and the error tells you exactly what to install rather than crashing:

>>> vm.lab("inference.power")
MissingDependencyError: 'plotly' is required for interactive figures but is not
installed. Install the 'viz' extra:  pip install "visualmetrics[viz]"
Everything, or from source
pip install "visualmetrics[all]"     # every extra that installs from wheels

git clone https://github.com/merwanroudane/visualmetrics
cd visualmetrics
pip install -e ".[dev,gui]"
pytest -m "not slow"

all deliberately excludes the proofs extra: Manim needs cairo and ffmpeg on the system, and folding it in would make pip install visualmetrics[all] fail on a clean machine.

Run it

visualmetrics

Open http://localhost:8080. That is the whole setup.


How to use it, step by step

1. Start at the catalogue

The catalogue

Every concept the package knows about — 47 built and 16 planned. The planned ones are shown, marked, and refuse to open. Nothing is hidden to make the count look better.

Search works in any of the three languages at once, including Arabic typed without diacritics. Filter by domain or by level.

2. Open a lab

A lab

Three things to notice before you touch anything:

The evidence badge, above the tabs Says what kind of claim this figure makes — here # Numerical demonstration, with its caveat beside it. It is never decoration
The knowledge tabs Overview, Intuition, Visualize, Animate, Simulation, Compare, Assumptions, Mathematics, Interpretation, Common mistakes, Warnings, Code. A tab appears only when the lab has something to put in it
The scenarios panel, on the left Grouped by what they are for, not listed flat

3. Change the assumption

Scenario groups

This is the point of the whole package. Scenarios are grouped as the standard case, weak signal, strong signal, under the null, at the boundary, small sample, large sample, sensitivity, compare methods — and, in labs where a method can break, assumption violated and counterexample.

Every lab is required to offer at least one case where the method fails. A lab that only shows the happy path is rejected by the test suite.

After changing the scenario

Pick one and the figures, the numbers, the assumptions and the warnings all re-compute. Below the controls you can set a seed, copy a link that reproduces exactly this view, or export the whole thing.

4. Watch the animation explain itself

The animation player

This is the feature the package exists for. The figure is on the left; the commentary is beside it, not in a caption underneath, and it changes with every frame:

  • What you are seeing — what is on screen right now
  • What changed — what moved since the last frame
  • Why it changed — the mechanism, not a description of the picture
  • How to read it — what the movement means
  • What to conclude — what you may take away
  • Careful — what you may not take away

Plus the equation the frame illustrates and the numbers at that frame. Step with the arrows, scrub the slider, or press play.

An animation that arrives without that layer is refused, not played silently — in the application and in every exporter.

5. Read the proof behind the lab

A proof

Labs that rest on a theorem link to it. A proof gives you:

  • the idea in plain language before any symbol appears;
  • the claim, stated precisely;
  • the assumptions in force, each marked essential or relaxable, each saying what breaks if it fails;
  • the steps one at a time, each with why that move is legal — the justification is the part that teaches;
  • the conclusion, and then, always on screen, what this does NOT establish.

Where an identity can be checked numerically, a button runs the check and labels it as a test of the code — never as evidence for the theorem.

6. Switch language mid-sentence

The same lab in Arabic

The same lab, one click later. The layout mirrors, the tabs reverse, the scenario groups translate, and you keep your figure, your parameters and your scroll position. A teacher can switch language mid-explanation without losing the class's place.

The interface, catalogue, glossary, scenarios, errors and proof structure are fully translated. The lab narrative still falls back to English in Arabic and French — about 2,400 keys remain. That is the honest state, and contributions there are the most valuable thing anyone can add.


The Python API

Everything the interface does is available directly; the GUI has no privileged access.

import visualmetrics as vm

result = vm.lab("inference.power", effect_size=0.4, n=60, alpha=0.05)

result.figure                  # the primary figure
result.metric_dict()["power"]  # the numbers behind it
result.evidence                # EvidenceType.SIMULATION — stated, not implied
result.warnings                # what this run wants you to notice
print(result.code)             # the exact Python that reproduces this run

A LabResult carries the whole scientific layer:

Attribute What it holds
panels Figures, each with a title, caption and evidence type
metrics Numbers, with labels and reference values
explanations Prose blocks, each tagged with a knowledge tab
assumptions Each with its status and, when violated, the consequence
animations Each with its per-frame explanation layer
warnings What the run raised
evidence What kind of evidence this is
code / dgp How to reproduce it, and how the data were made
# browse
vm.list_concepts(domain="econometrics")
vm.search("hétéroscédasticité")         # any of the three languages
vm.explain("regression.fwl")
vm.concept("causal.did").scenarios

# proofs
print(vm.proof("regression.fwl.theorem").to_text())

# teaching material
vm.objectives("inference.power")        # what to take away, and how to check it
vm.misconceptions("inference.power")    # the plausible wrong beliefs
vm.quiz("inference.power", count=3)     # a self-check, never a grade

# settings
vm.configure(language="ar", theme="dark", level="advanced", seed=7)

Every lab is deterministic given a seed:

assert vm.lab("inference.bootstrap", seed=42).metric_dict() == \
       vm.lab("inference.bootstrap", seed=42).metric_dict()

Notebooks

import visualmetrics as vm
from visualmetrics import notebook

notebook.setup()
vm.lab("econometrics.heteroskedasticity", scenario="severe")

After setup() a result displays as a small report — badge, warnings, violated assumptions and numbers — rather than a bare figure. Notebook cells get pasted into drafts, and a figure without its context is exactly what this package exists to prevent.

notebook.interact("inference.power")    # live controls (needs the notebook extra)

Working in three languages

vm.configure(language="ar")             # for the session
vm.lab("inference.clt", language="fr")  # for one call

Technical vocabulary can be shown three ways, because a class that will go on to read English papers needs the English term even when working in Arabic:

Mode What you see
translated The translated term only
bilingual The translated term with the English one beside it
english_technical Prose in your language, technical terms in English

Arabic is right-to-left by architecture: document direction, layout mirroring, figure axes, a real Naskh font stack, and Unicode isolation so R-squared does not scramble the sentence around it. Search normalises diacritics, tatweel and the alef/yeh/teh-marbuta variants.


The three rules this package keeps

1. A simulation is never a proof

Every figure and animation declares its evidence type. Nine of them, from formal_proof through simulation to counterexample. Only three count as proof, and no amount of visual polish promotes the others.

This is enforced, not intended: a ProofSpec refuses a non-proof evidence kind, a lab may not wear a proof badge unless it points at a real proof, and the badge travels with the figure into every export.

2. Every animation explains itself

Every frame answers what you see, what changed, why, and how to read it. The exporter and the player both refuse an animation without that layer.

3. The catalogue never overstates itself

47 built, 16 planned. The planned ones appear with a badge, are not clickable, and refuse to open with an explanation. Concepts are named for the science — there is no "Statistics 3" anywhere in an id, a title or the interface, and a test enforces it.


The catalogue

15 canonical domains:

Mathematical foundations Probability and random variables
Descriptive statistics Inferential statistics
Regression and linear models Econometrics
Time series econometrics Panel data econometrics
Causal inference Multivariate statistics
Spatial econometrics Machine learning
Deep learning Modern AI
Explainable AI

The full list is generated from the registry, so it cannot drift from what is installed.

Scenarios

519 scenarios across the 47 built labs:

canonical · positive · negative · null · weak · strong · boundary · violation · counterexample · sensitivity · small_sample · large_sample · high_noise · low_noise · robustness · misspecification · compare_methods

vm.lab("econometrics.heteroskedasticity", scenario="severe")
vm.lab("causal.did", scenario="violated_trends")
vm.lab("timeseries.cointegration", scenario="spurious")

Proofs

13, each with named assumptions, per-step justifications and an explicit statement of its limits — Frisch-Waugh-Lovell, Gauss-Markov, Neyman-Pearson, Cramér-Rao, the CLT, IV consistency, OLS orthogonality, the projection theorem, PCA variance maximisation, lasso sparsity, backpropagation, omitted variable bias and restricted least squares.

Exporting

from visualmetrics.export import export_html_report, export_result, export_animation

export_html_report(result, "report.html")   # figures + the whole scientific layer
export_result(result, "figure.png")         # static images (needs kaleido)
export_result(result, "result.json")        # everything as data
export_animation(result.animations[0], "animation.html")

Every exporter carries the evidence badge, the assumptions, the warnings and the frame commentary. There is no exporter that strips them — exporting an animation to a static format is refused for exactly that reason, and export_animation_frames writes the commentary beside the images.

Configurations round-trip, so a result is shareable:

from visualmetrics.export import save_config, load_config

save_config(state, "lesson-1.json")
vm.run_state(load_config("lesson-1.json"))   # same figures, same numbers

Optional extras

Extra Enables
gui The application
viz Plotly and Matplotlib figures
symbolic SymPy derivations
econometrics statsmodels, linearmodels, arch cross-checks
causal networkx DAG tooling
ai scikit-learn, SHAP
proofs Manim, for exported proof animations
notebook ipywidgets controls
data pandas, openpyxl, pyarrow
export kaleido, for static images

Troubleshooting

visualmetrics doctor

Reports the Python version, every optional backend with its status and version, which extra provides it, the languages available, the catalogue counts and whether the config and cache directories are writable. A package that is installed but unusable — a NumPy ABI mismatch, say — is reported as unusable rather than as missing, because the two have different fixes.

Accessibility

  • Never colour alone. Every series carries a dash pattern or marker shape; an assumption's status is shown by icon, word and colour together.
  • All seven themes meet WCAG AA contrast for body text; high_contrast reaches 21:1. A colourblind-safe palette is included, and contrast is checked by the test suite rather than by eye.
  • Reduced motion is obeyed as a rule: transitions disabled, autoplay refused with an explanation, every frame still reachable by hand.
  • Every figure carries a text alternative; assumptions expose ARIA status.
  • Full keyboard navigation with a visible focus ring.

Supported Python versions

3.11, 3.12 and 3.13, on Linux, macOS and Windows.

Contributing

See CONTRIBUTING.md. The rules above are not negotiable and are enforced by tests. Where help is most useful:

  1. Translating a lab. ~2,400 labs.* keys are still English-only in Arabic and French. One lab is a complete contribution.
  2. Building a planned concept. Sixteen are catalogued and waiting.
  3. Reporting a wrong number. The most serious kind of bug here — worth reporting even when you are not certain.

Adding a concept

  1. Add a ConceptSpec stub to catalog/builtin.py (Status.PLANNED).
  2. Write concepts/<domain>/<name>.py exporting SPEC and LAB.
  3. Declare controls and at least five scenarios, one where the method fails.
  4. Produce panels, metrics, explanations, assumptions and one animation whose every frame explains itself.
  5. Add the text to i18n/{en,ar,fr}/concepts.json.
  6. Flip the status and run pytest.

The interface needs no changes at all — it renders whatever the spec declares.

Citation

@software{roudane_visualmetrics,
  author  = {Roudane, Merwan},
  title   = {VisualMetrics: an interactive visual laboratory for statistics,
             econometrics, causal inference and machine learning},
  year    = {2026},
  url     = {https://github.com/merwanroudane/visualmetrics},
  license = {MIT}
}

See CITATION.cff.

License

MIT — see LICENSE.

Contact

Dr Merwan Roudanemerwanroudane920@gmail.com Issues: https://github.com/merwanroudane/visualmetrics/issues

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

visualmetrics-0.1.1.tar.gz (1.6 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

visualmetrics-0.1.1-py3-none-any.whl (666.9 kB view details)

Uploaded Python 3

File details

Details for the file visualmetrics-0.1.1.tar.gz.

File metadata

  • Download URL: visualmetrics-0.1.1.tar.gz
  • Upload date:
  • Size: 1.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for visualmetrics-0.1.1.tar.gz
Algorithm Hash digest
SHA256 67dad85600b18557b92a15acba74ff3cc8449da7f1cefced4460ea12e92a6fe2
MD5 1e345a72e6015e0b58e97649f68232ec
BLAKE2b-256 1d8946e12c94649bc7bea8293c7e6c7a192c772234cc423f057e2530eb8f320d

See more details on using hashes here.

File details

Details for the file visualmetrics-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: visualmetrics-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 666.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for visualmetrics-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0a605eb68a5d71bac544a112a371a7a18b533b23a0adce663e197778a1e09541
MD5 293264a7e1910551bab4514f711a2ae6
BLAKE2b-256 40b1b0819600d7557a619f9a92644017ba02ee8147c4102e7e27e73bc8e02815

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.2

2 files

This release

0.1.1 This release

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page