matplotlib set_array()在tripcolor的bug?

yptwkmov  于 2023-10-24  发布在  其他
关注(0)|答案(2)|浏览(104)

我是Pythonmatplotlib的新手,最近我引用THIS来更新我的tripcolor图。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.tri as tri
import math

r = np.zeros((100,100))
t = np.zeros((100,100))
for i in range(0,100):
    for j in range(0,100):
        r[i,j]=i
        t[i,j]=2*math.pi*j/100
x=r*np.cos(t)
y=r*np.sin(t)
z=r*r

xf=x.flatten()
yf=y.flatten()
zf=z.flatten()
triang = tri.Triangulation(xf,yf)

如果我按照预期使用tripcolor

# Works well
p = plt.tripcolor(triang, zf)

correct figure出现。但是,如果我尝试在创建tripcolor之后更新 *,

# Not working well
p = plt.tripcolor(triang, xf)
p.set_array(zf)

然后,wrong figure出现。xfzf具有相同的尺寸。
我做错了什么?问题的原因是什么,我如何避免它?
非常感谢。

更新
谢谢大家我自己解决了
关键是我需要为每个区域分配 *color *,这是由shading参数控制的,tripcolor的默认值是'flat',也就是说,color for each vertex。所以,当我绘制第一个图时,我需要确保阴影是'gouraud',它为每个区域分配 *color *。
所以,

p = plt.tripcolor(triang, xf, shading='gouraud')
p.set_array(zf)

就像我想的那样。

zzlelutf

zzlelutf1#

的原因

p = plt.tripcolor(triang, xf)
p.set_array(zf)

并没有像预期的那样工作,如下所示。在你的例子中,plt.tripcolor()返回一个PolyCollectionPolyCollectionset_array()本质上会设置那个集合的颜色。但是,底层的三角形不会被改变,这样你最终得到的是来自xf的三角形,而不是来自zf的颜色。
由于tripcolor PolyCollection的生成非常复杂(因为它调用Triangulation本身),而且可能没有帮助函数来外部设置数据(至少我不知道有任何帮助函数),解决方案可能是根本不更新tripcolor,而是生成一个新的。
有什么理由要更新吗?直接创建p = plt.tripcolor(triang, zf)不就行了?
如果有一个真实的原因,比如在动画中,一个选项是在设置下一个之前删除第一个tripcolor图。

# create one plot 
p = plt.tripcolor(triang, xf)
#delete this plot (you need both lines actually!!)
p.remove()
del p
#create second plot
p = plt.tripcolor(triang, zf)

不过,这并不是真正有效的,如果有人有更好的主意,我也想听听。

qlvxas9a

qlvxas9a2#

要将set_array()tripcolor(..., shading="flat)一起使用,您需要传入与每个 * 三角形 * 而不是每个点/顶点的颜色对应的值。表示每个三角形的值只是组成三角形的三个点的平均值。例如:

import matplotlib.pyplot as plt
import matplotlib.tri as mtri

# x: shape (n,) array of x values
# y: shape (n,) array of y values
# values: shape (n,) array of z values

# If you have the triangle indices:
# triangles: shape (m, 3) int array of triangle indices

fig, ax = plt.subplots()
im = ax.tripcolor(x, y, values, triangles=triangles, shading="flat")
new_values = values / 2
tri_values = new_values[triangles].mean(axis=1)
im.set_array(tri_values)

# Or using a Triangulation object, if you don't have triangles to begin with:

tri = mtri.Triangulation(x, y)
fig, ax = plt.subplots()
im = ax.tripcolor(tri, values, shading="flat")
new_values = values / 2
tri_values = new_values[tri.triangles].mean(axis=1)
im.set_array(tri_values)

相关问题