使用tripcolor绘制多组数据 - 在颜色图中添加透明度

3

我似乎无法解决这个问题。我有多组具有相同x,y点的数据。我进行了Delaunay三角剖分并使用tripcolor绘图。我在这个论坛上读到,要将几组数据绘制到同一图中,我需要指定轴和其他内容,但在这里(matplotlib入门者,抱歉)似乎不起作用。我的代码:

import matplotlib.pyplot as plt
import matplotlib.tri as tri
from pylab import genfromtxt

data=genfromtxt("momentAF.txt")
data2=genfromtxt("momentZZ.txt")

x = data[:,0]
y = data[:,1]
z1 = data[:,4]
z2 = data2[:,4]

circle=plt.Circle((0,0),1,color="black",fill=False)

triang = tri.Triangulation(x, y)

ax = plt.subplot(111)
ax.set_aspect('equal')
ax.add_artist(circle)
ax.tripcolor(triang, z2**2, shading='gouraud', cmap='Greens')
ax.tripcolor(triang, z1**2, shading='gouraud', cmap='Reds')
#plt.colorbar()
plt.title("ST, G'=-0.0")

任何帮助都非常感激,谢谢。
编辑: 我想要的大致示例: 相图 编辑2: 我尝试使用colormap选项“set_under”显示多个数据集而不为它们设置透明度:
my_cmap = cm.get_cmap("Greens")
my_cmap2 = cm.get_cmap("Reds")
my_cmap.set_under('w',alpha=0)
my_cmap2.set_under('w',alpha=0)

然后

ax.tripcolor(triang, z1**2, shading='gouraud', cmap=my_cmap, vmin=0.01)
ax.tripcolor(triang, z2**2, shading='gouraud', cmap=my_cmap2, vmin=0.01)

但是它仍然只显示z1非零的区域(即我的_cmap2中应该透明的区域被白色覆盖掉了)。我还尝试使用掩蔽数组,

masked = np.ma.masked_where(z1<.1,z3**2)
masked2 = np.ma.masked_where(z2<.1,z4**2)

ax.tripcolor(triang, masked, shading='gouraud', cmap="Greens")
ax.tripcolor(triang, masked2, shading='gouraud', cmap="Reds")

尽管如此,仍然毫无结果。


你还没有解释你得到了什么和你期望的是什么。此外,如果您输入虚拟数据 - 请明确指定datadata2的数组,而不是链接到其他小文件,这对我们来说会更容易处理。 - cphlewis
抱歉没有说明问题和数据(它们太大了,无法在此发布)。图形是圆形的,几个数据集在圆的不同部分具有非零值。因此,通过在一个图中绘制多个数据集,我想要获得绿色、红色、蓝色等部分的区域,这些颜色默认情况下位于图的不同部分(由于数据的性质),因此颜色不会重叠。理想的结果是,色图将从红色到透明,这样我就不必使用透明度 alpha,但我不确定是否可能。 - Juraj
set_under函数改变了cmap的lut属性的alpha值,但是似乎TriMesh将其覆盖为传递给tripcolor的alpha值,如果没有传递,则默认为1。 - Yann
顺便提一下,你不能将掩码数组传递给 tripcolor。只有在给出 x,y 坐标时,它才接受 mask 参数。你必须在 Triangulation 对象上应用掩码(这实际上是 tripcolor 所做的,它直接将 x,y,masked 传递给 Triangulation 构造函数),请参见我的编辑。 - Yann
1个回答

1
它不是不起作用,只是你在绘制两次相同的三角剖分,只是改变了颜色(triplot中tripcolor签名后面的参数是数据点的颜色)。 请参阅tripcolor文档: 下一个参数必须是C,颜色值数组,如果在点上定义了颜色值,则每个点一个颜色值,如果在三角形上定义了颜色值,则每个三角形一个颜色值。如果三角剖分中的点数和三角形数相同,则假定在点处定义了颜色值;要强制使用三角形处的颜色值,请使用kwarg facecolors*=C而不仅仅是*C。
因此,您下面的代码所做的是使用cmap为Greens的颜色级别z1 ** 2绘制三角剖分triang,然后在其上方绘制完全相同的三角剖分,只是将颜色级别更改为z2 ** 2并将cmap更改为Reds。
ax.tripcolor(triang, z2**2, shading='gouraud', cmap='Greens')
ax.tripcolor(triang, z1**2, shading='gouraud', cmap='Reds')

当然,你只能看到最后绘制的(红色)因为它正好覆盖了第一个绘制的(绿色)。你可以使用透明度 alpha 来同时看到两者:
ax.tripcolor(triang, z2**2, shading='gouraud', cmap='Greens', alpha=0.5)
ax.tripcolor(triang, z1**2, shading='gouraud', cmap='Reds', alpha=0.5)

但最终结果将是颜色的混合物(以最后绘制的为主),我不确定这是否符合您的要求...
就像cphlewis所说,如果您展示使用的数据和想要的结果,那么理解您想要什么将会更容易。
编辑:
我认为我找到了一种使用掩码实现您想要的方法:
import matplotlib.pyplot as plt
import matplotlib.tri as tri

x = np.random.uniform(-0.7,0.7,10)
y = np.random.uniform(-0.7,0.7,10)
z1 = np.random.uniform(-1,1,10)
z2 = - z1

circle=plt.Circle((0,0),1,color="black",fill=False)

triang1 = tri.Triangulation(x, y)
triang2 = tri.Triangulation(x, y)

mask1 = np.logical_or.reduce(( np.where(z1[triang1.triangles]<=0, 1,0).T ))
mask2 = np.logical_or.reduce(( np.where(z2[triang2.triangles]<=0, 1,0).T ))

triang1.set_mask(mask1)
triang2.set_mask(mask2)

ax = plt.subplot(111)
ax.set_aspect('equal')
ax.add_artist(circle)

t1 = ax.tripcolor(triang1, z1, shading='gouraud', cmap=matplotlib.cm.Greens, alpha=0.5)
t2 = ax.tripcolor(triang2, z2, shading='gouraud', cmap=matplotlib.cm.Reds, alpha=0.5)

基本上,您需要创建一个掩码并将其设置为triang1,这将控制显示哪个三角形。 triang2.triangles是三角形的列表(实际上是一个3 * nb_of_triangles数组,基本上它是一个顶点数组)。 z2 [triang2.triangles]为每个顶点提供相应的zlevel。 np.where(z2[triang2.triangles]<=0,1,0).T测试顶点级别是否为零,因此是否应该屏蔽。 np.logical_or.reduce执行逻辑或,因此如果至少有一个顶点被屏蔽,则屏蔽三角形(因此,只有具有可见顶点的三角形不被屏蔽)。
请注意,可能有一些方法通过直接编辑t1._facecolors来实现透明度,但我真的看不出这些是如何计算的...

嗨,感谢@Yann。图形是在一个圆圈中,几个数据集在圆圈的不同部分具有非零值。因此,通过在一个图中绘制多个数据集,我想要获得绿色、红色、蓝色等部分的区域,这些区域默认情况下位于图的不同部分(这是数据的本质),因此它们不会重叠。 - Juraj
好的,我明白你想做什么。不幸的是,这似乎并不容易实现。我原以为你可以创建具有非常量透明度的自定义颜色映射(因此 cmap 的低级三角形将显示为透明),但似乎不可能:matplotlib.collections.TriMesh 强制所有三角形的 alpha 通道都是恒定的。由于我对这个类的源代码不太熟悉,所以我没有看到任何简单的方法来解决它。 - Yann
一个可能的调整是“合并”两种表示,例如:z_combined = z1**2 - z2**2,并将其与发散的颜色图一起使用:ax.tripcolor(triang, z_combined, shading='gouraud', cmap='RdBu')z_combined采用非零表示的值,并根据符号使其变为红色或蓝色。 - Yann
谢谢你的努力,这是个好主意。理论上来说,这应该可行,唯一的问题是,有时候对于一组数据,在整个图表的另一侧会有非零值。三角剖分会在这些部分之间形成一个巨大的三角形,并将其下方的所有内容覆盖为白色。 不过,这仍然有帮助,因为经过一些努力,我应该能够将数据集分成这些部分,然后就可以解决问题了。 不过,我原本期望会更简单……也许有比matplotlib更好处理这些问题的工具吗? - Juraj
不是很确定你需要什么,但我认为我找到了更好的解决方案。请查看我的新编辑。 - Yann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接