根据3个变量的颜色-麦克斯韦三角形


问题内容

我有一个由三个变量u,v,w组成的模型,这些变量随时间和空间而变化。我对这三个变量的比率特别感兴趣。但是,我不想显示三个图,每个显示一个变量,而是只使用一个图。

我的想法是使用Maxwell三角形(彩色三角形,请参见http://homepages.abdn.ac.uk/npmuseum/article/Maxwell/MaxTri.html)。我可以轻松缩放每个变量的最大值(最大值为1)。但是我不知道这个想法是否可以实现。如果有道理,它应该已经存在。我的问题:

  1. 如何将三个变量转换为代表颜色的单个值(例如,如果我有一个填充的轮廓图,我希望每个网格单元都有“其比率”)?
  2. 我可以将颜色三角形用作颜色条吗?

我尝试举一个简短的例子,以使其更易于理解:

import numpy as np
import matplotlib.pyplot as plt
# create three arrays for the state variables
# space is a 200x200 grid
size = 200
u = np.random.rand(size,size)
v = np.random.rand(size,size)
w = np.random.rand(size,size)
# now I could create 3 subplots and plot the spatial distribution
# for each variable
# but I want something like
col = np.zeros((200,200))
for i in range(200): # loop in x-direction
    for j in range(200): # loop in y-direction
        col[i,j] = colorTriangle(u[i,j],v[i,j],w[i,j])
plt.contourf(col)

功能colorTriangle不存在。但是我想要这样的东西:如果每个变量在(i,j)处都具有相同的值,则颜色应为白色(请参见麦克斯韦三角形)。如果我们只有你,那应该是绿色。如果只有v,则应为红色。如果只有w,则应该为蓝色。
如果组合更复杂,则每个变量应沿一个颜色方向“拉动”,并且应根据麦克斯韦三角形中的位置选择颜色。

你有主意吗?它不一定必须是颜色三角形,但是我会在一个contourf图中获得此类信息。颜色三角形将有助于解释颜色。


问题答案:

要回答第一个问题,应该注意很多事情。

首先, 单个值 可以表示颜色的唯一方法是使用颜色映射,该映射将标量映射到颜色。但是,麦克斯韦三角形不能减少为单个值。

这并不意味着麦克斯韦三角形不能用作将3个值映射到一种颜色的3D色彩图。其实,这是很自然的事,因为麦克斯韦使用3个值ab以及c使颜色在RGB坐标来表示(a,b,c)。唯一缺少的是规范化。

在提供的链接中,麦克斯韦三角形定义为a+b+c=1。但是,matplotlib接受RGB坐标,因为3的浮点数介于0和1之间,其中白色显然是1,1,1,而不是1/3,1/3,1/3。因此,i,j考虑到这一点,每个将具有三个值,必须将其转换为0和1之间的3个浮点数。

因此,除了标准化除以和以外,a+b+c=1我们还必须标准化除以每个三项运算的最大值。

最终,可以使用显示最终图像imshow

def colorTriangle(r,g,b):
    image = np.stack([r,g,b],axis=2)
    return image/image.max(axis=2)[:,:,None]

size = 200
X,Y = np.meshgrid(np.linspace(0,1,200),np.linspace(0,1,200))
u = np.full_like(X,.2)
v = Y
w = X**2
plt.imshow(colorTriangle(v,u,w),origin='lower',extent=(0,1,0,1)) 
# Note that v is first in order to be represented by red

输出图像如下:

颜色三角形

在这里可以清楚地看到,对于x和y较小的值(其中vw为零),颜色为绿色,与u零不同,并且比v和大得多w。对于大x和小y,w则占主导地位,而颜色的确是蓝色,而当v占主导地位时(大y和小x),颜色为红色。还显示出,对于所有三个矩阵的相等值,所得颜色为白色。