【问题标题】:Color according to 3 variables - Maxwell triangle根据 3 个变量的颜色 - 麦克斯韦三角形
【发布时间】:2018-11-24 08:10:52
【问题描述】:

我有一个由三个变量 u,v,w 组成的模型,它们随时间和空间变化。我对三个变量的比率特别感兴趣。 但与其显示三个图,每个图对应一个变量,我宁愿只使用一个图。

我的想法是使用麦克斯韦三角形(颜色三角形,参见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) 处具有相同的值,则颜色应为白色(参见麦克斯韦三角形)。如果我们只有 u,它应该是绿色的。如果我们只有 v,它应该是红色的。如果我们只有 w,它应该是蓝色的。
如果组合更复杂,则每个变量都应“拉”向一个颜色方向,并应根据麦克斯韦三角形中的位置选择颜色。

你明白吗?它不一定必须是彩色三角形,但我会在一个轮廓图中拥有这种信息。颜色三角形将有助于解释颜色。

【问题讨论】:

  • 如果您发布一个示例将非常有用(如有疑问,请参阅stackoverflow.com/help/mcve)。我不太了解您的目标,您有 3 个变量,因此,如果您绘制等高线图,一个轴将是 u,另一个轴是 v,等高线/颜色将是 w。麦克斯韦三角形从何而来?
  • 我添加了信息。我没有提到该系统在空间上是明确的——对此感到抱歉。我希望这会有所帮助?!

标签: python matplotlib colors colorbar


【解决方案1】:

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

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

这并不意味着麦克斯韦三角形不能用作一种 3D 颜色图,将 3 个值映射到一种颜色。实际上这样做是很自然的,因为 Maxwell 使用了 3 个值 abc,因此颜色可以在 RGB 坐标中表示为 (a,b,c)。唯一缺少的是标准化。

在提供的链接中,麦克斯韦三角形被定义为a+b+c=1。但是,matplotlib 接受 RGB 坐标作为 0 和 1 之间的 3 个浮点数,其中白色显然是 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 不同于零并且远大于 vw。对于大 x 和小 y,w 占主导地位,颜色确实是蓝色,而当v 占主导地位(大 y 和小 x)时,颜色是红色。它还表明,对于所有三个矩阵的相同值,生成的颜色是白色。

【讨论】:

  • 非常感谢。这正是我一直在寻找的。​​span>
猜你喜欢
  • 1970-01-01
  • 2020-11-27
  • 2017-08-09
  • 1970-01-01
  • 2017-04-10
  • 2020-07-17
  • 1970-01-01
  • 2015-02-21
  • 1970-01-01
相关资源
最近更新 更多