Ternary Plotting
Relevant source files
The following files were used as context for generating this wiki page:
Ternary Plotting within the Universal Portfolios project is a specialized visualization utility used to represent data constrained by a constant sum, specifically portfolio weights across three assets where $x + y + z = 1$. It allows for the visual analysis of the performance landscape of Online Portfolio Selection (OLPS) algorithms, such as the Constant Rebalanced Portfolio (CRP), within a triangular coordinate system.
The module provides tools for projecting 3D simplex coordinates onto a 2D plane using Matplotlib, enabling the creation of trajectories (showing how weights evolve over time) and heatmaps (showing performance metrics across the entire weight space).
Geometry and Coordinate Projection
The core of ternary plotting is the mathematical projection of three-dimensional points (representing three asset weights) onto a two-dimensional equilateral triangle (a 3-simplex). This is handled via planar-simplex mapping where the vertical height represents the third component.
Projection Logic
The transformation from 3D coordinates $(x, y, z)$ to 2D Cartesian coordinates $(x', y')$ uses a specific geometric mapping where $z$ determines the height and $y$ determines the horizontal offset.
The logic ensures that the top vertex corresponds to 100% of the third asset, the bottom-left to the first asset, and the bottom-right to the second asset.
Sources: universal/algos/ternary/plotting.py:46-54
Visualization Components
The system supports three primary types of ternary visualizations:
1. Simplex Boundary
The boundary utility draws the triangular frame of the 3-simplex. It uses matplotlib.pyplot.plot to connect the three vertices $(0,0)$, $(scale, 0)$, and $(scale/2, \text{height})$.
Sources: universal/algos/ternary/plotting.py:27-38
2. Trajectory Plotting
Trajectories visualize the movement of portfolio weights over time. The plot function accepts a sequence of weight vectors, projects them, and renders a continuous line. This is particularly useful for visualizing "Follow the Winner" or "Follow the Loser" strategies as they rebalance.
Sources: universal/algos/ternary/plotting.py:68-75
3. Simplex Heatmaps
Heatmaps are used to evaluate functions across the entire possible weight distribution. This is commonly used to find the "Best Constant Rebalanced Portfolio" (BCRP) for a specific set of three assets.
| Function | Purpose |
|---|---|
simplex_points | Iterates through a lattice of points on the simplex based on a specified number of steps. |
triangle_coordinates | Calculates vertex points for individual polygons (triangles) within the heatmap grid. |
heatmap | Renders a color-mapped visualization based on a dictionary of coordinates and values. |
plot_heatmap | A convenience wrapper that applies a provided function to every point in a normalized simplex lattice. |
Sources: universal/algos/ternary/plotting.py:80-142
CRP Visualization and Integration
The CRP (Constant Rebalanced Portfolio) algorithm utilizes ternary plotting to demonstrate how different static weight distributions perform on a specific dataset.
When plot_crps is called with show_3d=True, the system generates a heatmap showing the total wealth generated by every possible combination of weights for three assets.
Sources: universal/algos/crp.py:48-61, universal/tools.py:246-258
Implementation Details
Configuration and Constants
The module defines specific geometric constants and default styles for consistency across plots.
| Constant | Value | Description |
|---|---|---|
SQRT3OVER2 | math.sqrt(3) / 2.0 | Standard height ratio for equilateral triangles. |
DEFAULT_COLOR_MAP | pyplot.get_cmap("jet") | Default colormap used for heatmaps. |
Sources: universal/algos/ternary/plotting.py:9-14
Functional Architecture
The data flow for generating a heatmap follows a systematic iteration through the simplex space:
- Lattice Generation:
simplex_pointsyields $(x_1, x_2, x_3)$ integer triplets. - Normalization: Values are divided by the total steps to ensure they sum to 1.0.
- Evaluation: A metric (e.g.,
total_wealthfromAlgoResult) is calculated for the point. - Tessellation: Triangular polygons are filled with colors derived from the metric using a
colormapper.
Sources: universal/algos/ternary/plotting.py:108-142, universal/result.py:126-128
Ternary plotting serves as a critical diagnostic tool in the universal-portfolios library, specifically for three-asset scenarios. It provides a visual bridge between the abstract multi-dimensional weight space and human-readable performance surfaces, allowing developers to identify optimal static weightings and observe the dynamic behavior of complex online portfolio selection algorithms.