如何在Python中为三元图例填充子三角形混合色
三元图子三角形三色填充实现方案
1. 预处理分量矩阵
首先确保A、B、C三个矩阵的对应元素和为1(三元图分量的核心要求),若未归一化则先执行归一化:
import numpy as np # 假设A、B、C为形状匹配的numpy.ndarray total = A + B + C A_norm = A / total B_norm = B / total C_norm = C / total
2. 分量到RGB颜色的映射
根据你定义的顶点(红→A、黑→B、绿→C),通过分量加权生成对应RGB颜色:
- 红色顶点对应
(1, 0, 0)(A=1,B/C=0) - 黑色顶点对应
(0, 0, 0)(B=1,A/C=0) - 绿色顶点对应
(0, 1, 0)(C=1,A/B=0)
每个子三角形的颜色计算逻辑如下:
# 生成扁平化的RGB颜色数组,对应所有子三角形 colors = np.stack([A_norm.flatten(), C_norm.flatten(), np.zeros_like(A_norm.flatten())], axis=1)
注:若顶点与分量的对应关系不同,只需调整RGB通道的关联分量即可。
3. 绘制填充的三元图
利用ternary库结合matplotlib的多边形绘制功能,遍历每个子三角形并填充对应颜色:
import ternary import matplotlib.pyplot as plt # 初始化三元图,scale值需与矩阵维度匹配(如N×N矩阵对应scale=N-1) fig, tax = ternary.figure(scale=A.shape[0]-1) tax.boundary(linewidth=2) tax.set_title("三色填充三元图", fontsize=12) # 设置顶点标签对应你的颜色定义 tax.left_axis_label("黑 (B)", fontsize=10) tax.right_axis_label("绿 (C)", fontsize=10) tax.top_axis_label("红 (A)", fontsize=10) scale = tax.scale # 遍历所有子三角形 for i in range(scale): for j in range(scale - i): # 获取当前子三角形的三元坐标(a+b+c=scale) point1 = (i, j, scale - i - j) point2 = (i + 1, j, scale - i - j - 1) point3 = (i, j + 1, scale - i - j - 1) # 转换为matplotlib可用的笛卡尔坐标 coords = [tax.convert_coordinates(p, axisorder='abc') for p in [point1, point2, point3]] # 获取当前子三角形的归一化分量,生成颜色 color = (A_norm[i, j], C_norm[i, j], 0) # 绘制填充多边形 poly = plt.Polygon(coords, facecolor=color, edgecolor='white', linewidth=0.5) tax.ax.add_patch(poly) # 优化显示效果 tax.clear_matplotlib_ticks() tax._redraw_labels() plt.show()
核心注意点
- 坐标对应:确保矩阵索引与三元图坐标一一匹配,比如
(i,j)对应三元组(i,j,scale-i-j),分别关联A、B、C分量。 - 颜色逻辑:黑色分量B会降低整体亮度,A值越高颜色越红,C值越高颜色越绿。
- 网格匹配:
scale参数必须与矩阵维度对应,比如10×10矩阵对应scale=9(三元图网格点数量为scale+1)。
内容的提问来源于stack exchange,提问作者emax
相关产品推荐
相关产品推荐

