Python: how to fill a ternary plot

27 Views Asked by At

I want to make a legend in python as a ternary plot to compare the values of three matrices A,B,C. This what I am doing.

import numpy as np
import matplotlib.patches as mpatches
def create_color_map(A, B, C):
    """
    Creates a color map based on the values in three matrices (A, B, C) representing
    pixel values between 0 and 1.

    Args:
        A, B, C (numpy.ndarray): Arrays of the same shape representing the three values
                 for each pixel. Values range from 0 to 1.

    Returns:
        numpy.ndarray: A color map with RGB values for each pixel, shaped (N, M, 3),
                       where N and M are the dimensions of the input arrays.
    """

    # Handle potential shape mismatches
    if not np.all(A.shape == B.shape == C.shape):
        raise ValueError("Arrays A, B, and C must have the same shape.")

    # Ensure values are within 0-1 range (clamp if necessary)
    A = np.clip(A, 0, 1)
    B = np.clip(B, 0, 1)
    C = np.clip(C, 0, 1)

    # Calculate weights for each color component (black, red, green)
    black_weights = 1 - A - B
    red_weights = B
    green_weights = C

    # Combine weights and scale to 0-255 range (assuming uint8 output)
    colors = np.dstack((black_weights * 255, red_weights * 255, green_weights * 255)).astype(np.uint8)
    return colors

# Create sample matrices (A, B, C)
A = np.array([[0.2, 0.7, 0.1],
              [0.0, 0.5, 0.9],
              [1.0, 0.3, 0.0]])
B = np.array([[0.9, 0.1, 0.6],
              [0.3, 0.0, 0.2],
              [0.0, 0.8, 0.3]])
C = np.array([[0.0, 0.2, 0.8],
              [0.5, 0.6, 0.1],
              [0.3, 0.0, 0.4]])

# Generate the color map
color_map = create_color_map(A, B, C)


# Visualize the color map using matplotlib
plt.imshow(color_map)
plt.title("Color Map Visualization")
# Create legend
vertices = [(0, 0), (1, 0), (0.5, np.sqrt(3)/2)]  # Triangle vertices
colors = ['black', 'red', 'green']  # Vertex colors
plt.show()

enter image description here

Now I would like to create a legend as a ternary map where I have color combinations for different values of A,B,C. This is what I am doing.

import ternary

def plot_ternary_legend():
    """Plot ternary legend with vertices red, black, and green."""
    fig, tax = ternary.figure(scale=1)
    tax.boundary()
    tax.set_title("Ternary Legend", fontsize=20)

    # Define vertices
    red = (1, 0, 0)     # Red
    black = (0, 0, 0)   # Black
    green = (0, 1, 0)   # Green

    # Plot vertices
    tax.scatter([red, black, green], marker='o', color=['red', 'black', 'green'], label=['Red', 'Black', 'Green'])

    # Label vertices
    tax.legend()

    tax.gridlines(multiple=0.1, color="blue", alpha=0.5)
    tax.ticks(axis='lbr', linewidth=1, multiple=0.1, tick_formats="%.1f")
    tax.clear_matplotlib_ticks()

    plt.show()

# Plot ternary legend
plot_ternary_legend()

enter image description here

I would like to to fill the subtriangles inside the ternary plot with colors representing the mix of red, black, and green. How can I do that?

0

There are 0 best solutions below