VISTA — VISualization of relation Topologies of Alternatives
Project description
VISTA — VISualization of relation Topologies of Alternatives
Overview
VISTA is a visualization framework for Multi-Criteria Decision Analysis (MCDA) ranking methods. For a given ranking method it sweeps a test alternative across a 2-D criteria space and classifies every point by its pairwise relation to a fixed reference alternative:
| Symbol | Relation | Meaning |
|---|---|---|
| P+ | Better | The test alternative is preferred over the reference |
| I | Indifferent | The method cannot distinguish the two alternatives |
| P− | Worse | The reference alternative is preferred |
| R | Incomparable | The method cannot order the two alternatives |
The resulting colour-coded map reveals decision boundaries and structural differences between MCDA ranking methods at a glance.
Installation
Install directly from PyPI:
pip install mcda-vista
To include the interactive Streamlit dashboard:
pip install mcda-vista[app]
For development (linting, type-checking, tests):
git clone https://github.com/dabrze/mcda-vista.git
cd mcda-vista
pip install -e ".[dev]"
Quick Start
from mcda_vista import generate_vista, plot_vista
result = generate_vista("topsis", resolution=101, delta=0.10, progress=True)
fig = plot_vista(result, point_size=7)
fig.savefig("topsis_vista.png", dpi=300)
generate_vista sweeps a 101 × 101 grid of alternatives over the criterion space, evaluates
the ranking method (in this case TOPSIS) at every point, and returns a VistaResult dataclass. plot_vista
renders it as a scatter plot coloured by the relation type - adjust the point_size parameter to the
resolution and size of the image.
You will find practical examples of how to use vistas in the notebooks folders. A portion of that functionality is highlighted below.
Available Ranking Methods
The package works with pyDecision's built-in methods and any custom method that follows the expected interface. The following methods are registered by default:
| Key | Display Name | Key Parameters |
|---|---|---|
saw |
SAW | delta — indifference threshold (default 0.1) |
topsis |
TOPSIS | delta — indifference threshold (default 0.1) |
vikor |
VIKOR | v — strategy coefficient (default 0.5) |
macbeth |
MACBETH | delta — indifference threshold (default 0.1) |
borda |
Borda | (parameter-free) |
oreste |
ORESTE | alpha — alpha threshold (default 0.4) |
spotis |
SPOTIS | delta — indifference threshold (default 0.1) |
etopsis |
E-TOPSIS | aggregation (A/I/R), epsilon, delta |
uta |
UTA | k — breakpoints, form (L/X/V/S), delta |
assess |
ASSESS | k — breakpoints, form (L/X/V/S), delta |
electre_iii |
ELECTRE III | q, p, v — thresholds; alpha, beta — cut-level |
electre_iiic |
ELECTRE IIIc | q, p, v — thresholds; lamb — credibility cutting level |
promethee_i |
PROMETHEE I | f (t1–t7) — preference function; q, p, s |
promethee_ii |
PROMETHEE II | f (t1–t7), q, p, s, delta |
promethee_iii |
PROMETHEE III | f (t1–t7), q, p, s, lmbd — interval width |
regime |
REGIME | (parameter-free) |
List registered methods programmatically:
from mcda_vista.methods import list_methods
print(list_methods())
If a pyDecision method is not available by default, you can add it by creating an adapter with register_method() or use a custom callable (see below).
Custom Methods
You can pass any callable that accepts a dataset, weights, and keyword parameters and returns a Relation:
from mcda_vista import generate_vista, plot_vista, Relation
import numpy as np
def my_method(dataset, weights, **params):
# dataset[0] = reference, dataset[1] = test point
score_ref = np.dot(dataset[0], weights)
score_test = np.dot(dataset[1], weights)
delta = params.get("delta", 0.05)
if abs(score_ref - score_test) < delta:
return Relation.INDIFFERENT
return Relation.BETTER if score_test > score_ref else Relation.WORSE
result = generate_vista(my_method, resolution=101, delta=0.05)
fig = plot_vista(result)
fig.savefig("custom_method.png", dpi=300)
Exploratory Diagnostic Protocol
The VISTA exploratory protocol is a systematic six-step checklist that assesses whether a ranking method meets the decision maker's expectations:
- Dominance relation — no violations in dominating/dominated cones
- Self-indifference — identical alternatives are indifferent
- Diagonal preference change — at most one transition along the diagonal
- Radial preference change — at most one transition along any ray
- Preference ratio — shows whether the Better/Worse ratio is balanced or not
- Third alternative stability (IIA check) — verifies whether the VISTA remains stable when a third alternative is added
from mcda_vista.protocol import run_protocol, plot_protocol_report
report = run_protocol("topsis", resolution=101, delta=0.10)
fig = plot_protocol_report(report, point_size=3)
fig.savefig("protocol_report.png", dpi=300)
print(report.summary())
VISTA Protocol Report: topsis
=============================
✓ PASS Dominance relation: No violations (2500 dominating, 2500 dominated points).
✗? FAIL Self-indifference: Reference point is Error — likely a numerical issue (nearest grid point at distance 0.0000).
✓ PASS Diagonal preference change: Upper-right: 1 transition(s), lower-left: 1 transition(s).
✓ PASS Radial preference change: All 36 rays have at most 1 transition.
● IMBALANCED Preference ratio: Imbalanced (56.8% worse, 37.9% better than reference).
✗ FAIL Third alternative stability: Max change 14.4% > 5%. Changes: [0.5, 0.5]: 4.5%, [0.25, 0.5]: 10.3%, [0.5, 0.75]: 4.5%, [0.25, 0.25]: 7.4%, [0.25, 0.75]: 14.4%.
The protocol uses equal weights and the midpoint as reference by default.
Optionally pass extra_weights to test weight sensitivity (e.g., extra_weights=[[0.25, 0.75], [0.25, 0.50], [0.50, 0.50], [0.50, 0.25], [0.75, 0.25]]).
See notebooks/12_protocol_check.ipynb for a full walkthrough with Fuzzy TOPSIS.
VISTA Grid
Use plot_vista_grid to compare multiple methods in a single faceted figure.
The example below contrasts different PROMETHEE I function types side by side:
from mcda_vista import generate_vista
from mcda_vista.plotting import plot_vista_grid
weights = [[0.25, 0.50], [0.50, 0.50], [0.50, 0.25]]
promethee_types = ["t1", "t2", "t3", "t4"]
results = [
[
generate_vista("promethee_i", resolution=101, weights=w, f=ptype, q=0.05, p=0.20)
for ptype in promethee_types
]
for w in weights
]
fig = plot_vista_grid(
results,
row_labels=[f"w={w}" for w in weights],
col_labels=["PROMETHEE I (t1)", "PROMETHEE I (t2)", "PROMETHEE I (t3)","PROMETHEE I (t4)"],
title="Comparison of PROMETHEE I versions",
point_size=1.5,
)
fig.savefig("vista_grid_promethee.png", dpi=300)
Experiments
Reproducible experiments are configured via YAML files stored in
experiments/configs/. Each config specifies the method, parameter
ranges, resolution, and output paths. To run an experiment:
python experiments/run_experiments.py experiments/configs/my_config.yaml --plot
Results (CSV grids + metadata JSON) are written to the configured output
directory and can be reloaded with load_vista().
Dashboard
The optional Streamlit dashboard provides an interactive UI for exploring VISTA maps interactively. Launch it with:
streamlit run src\mcda_vista\app\dashboard.py
Select a method, adjust parameters with sliders, and watch the VISTA map update live. Install the dashboard extra to enable it:
pip install .[app]
License
This project is licensed under the MIT License.
Support and Citation
If you have questions or run into problems, please open an issue on GitHub.
If you use VISTA in your research, please cite:
@article{vista,
author = {Susmaga, Robert and Szcz\c{e}ch, Izabela and Brzezinski, Dariusz},
title = {Visualization of Preferential Relations in Analyses of Multicriteria Ranking Methods},
note = {In review},
year = {2026}
}
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcda_vista-0.2.0.tar.gz.
File metadata
- Download URL: mcda_vista-0.2.0.tar.gz
- Upload date:
- Size: 2.6 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b13077cece7c5340a80dfe42048fac7614ee324c1e284261355bb5c9e4c21853
|
|
| MD5 |
6041062696a43d15411bfa8c542a0657
|
|
| BLAKE2b-256 |
bab55d403cb2459f4a36c347cdfe47f304b3350c70ca4155b2e95d0c540354af
|
Provenance
The following attestation bundles were made for mcda_vista-0.2.0.tar.gz:
Publisher:
publish.yml on dabrze/mcda-vista
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcda_vista-0.2.0.tar.gz -
Subject digest:
b13077cece7c5340a80dfe42048fac7614ee324c1e284261355bb5c9e4c21853 - Sigstore transparency entry: 1226314561
- Sigstore integration time:
-
Permalink:
dabrze/mcda-vista@1b01fa5a61f7e0f17fab40d63797bd0a1ae6a6bf -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/dabrze
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@1b01fa5a61f7e0f17fab40d63797bd0a1ae6a6bf -
Trigger Event:
release
-
Statement type:
File details
Details for the file mcda_vista-0.2.0-py3-none-any.whl.
File metadata
- Download URL: mcda_vista-0.2.0-py3-none-any.whl
- Upload date:
- Size: 66.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
13876c79fade19562d4af32ad290055c810914a51b3bf0e4ae17318cf505376e
|
|
| MD5 |
8d66ac610e7e8af13710cd8ee68fe50f
|
|
| BLAKE2b-256 |
0ce94d89b0ac061c02dc4fbfaed8685e1d65493bff734c5eae6831aff61e10e0
|
Provenance
The following attestation bundles were made for mcda_vista-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on dabrze/mcda-vista
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcda_vista-0.2.0-py3-none-any.whl -
Subject digest:
13876c79fade19562d4af32ad290055c810914a51b3bf0e4ae17318cf505376e - Sigstore transparency entry: 1226314615
- Sigstore integration time:
-
Permalink:
dabrze/mcda-vista@1b01fa5a61f7e0f17fab40d63797bd0a1ae6a6bf -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/dabrze
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@1b01fa5a61f7e0f17fab40d63797bd0a1ae6a6bf -
Trigger Event:
release
-
Statement type: