gpt4 book ai didi

python - 使用 matplotlib tricontourf 绘制相位图

转载 作者:太空宇宙 更新时间:2023-11-04 04:33:49 27 4
gpt4 key购买 nike

我想用个性化的颜色图绘制有限元模拟结果的图像。我一直在尝试使用 tricontourf 将其绘制如下:

    #Z = self.phi.compute_vertex_values(self.mesh)
Z = np.mod(self.phi.compute_vertex_values(self.mesh),2*np.pi)
triang = tri.Triangulation(*self.mesh.coordinates().reshape((-1, 2)).T,
triangles=self.mesh.cells())
zMax = np.max(Z)
print(zMax)

#Colormap creation
nColors = np.max(Z)*200/(2*np.pi)
phiRange = np.linspace(0,zMax,nColors)
intensity = np.sin(phiRange)**2
intensityArray = np.array([intensity, intensity, intensity])
colors = tuple(map(tuple, intensityArray.T))
self.cm = LinearSegmentedColormap.from_list("BAM", colors, N=nColors)

#Figure creation
fig, ax = plt.subplots()
levels2 = np.linspace(0., zMax,nColors)

cax = ax.tricontourf(triang, Z,levels=levels2, cmap = self.cm) #plot of the solution
fig.colorbar(cax)

ax.triplot(triang, lw=0.5, color='yellow') #plot of the mesh

plt.savefig("yolo.png")
plt.close(fig)

它给出了结果: enter image description here

正如您所看到的,当存在模数时,相位从 2pi 变为 0 时会出现一些问题,这是来自 tricontourf...

我的第一个解决方法是直接在我的 Z 阶段工作。问题是,如果我这样做,我需要创建一个更大的颜色图。最终,相位将非常大,如果我想要正确的颜色分辨率,颜色图也会非常大......此外,我希望右侧的颜色图中只有一个周期(就像在第一个图中)。 enter image description here

知道如何获得与第二个图一样的图,具有与第一个图相同的色图,而无需创建非常大且昂贵的色图吗?

编辑:我写了一个开箱即用的小代码:它重现了我遇到的问题,我也尝试将 Thomas Kuhn 的回答应用到我的问题上。但是,颜色条似乎存在一些问题...知道如何解决这个问题吗?

import matplotlib.pyplot as plt
import matplotlib.tri as mtri
import numpy as np
import matplotlib.colors as colors

class PeriodicNormalize(colors.Normalize):
def __init__(self, vmin=None, vmax=None, clip=False):
colors.Normalize.__init__(self, vmin, vmax, clip)

def __call__(self, value, clip=None):
x, y = [self.vmin, self.vmax], [0, 1]

return np.ma.masked_array(np.interp(
np.mod(value-self.vmin, self.vmax-self.vmin),x,y
))

# Create triangulation.
x = np.asarray([0, 1, 2, 3, 0.5, 1.5, 2.5, 1, 2, 1.5])
y = np.asarray([0, 0, 0, 0, 1.0, 1.0, 1.0, 2, 2, 3.0])
triangles = [[0, 1, 4], [1, 2, 5], [2, 3, 6], [1, 5, 4], [2, 6, 5], [4, 5, 7],
[5, 6, 8], [5, 8, 7], [7, 8, 9]]
triang = mtri.Triangulation(x, y, triangles)
cm = colors.LinearSegmentedColormap.from_list('test', ['k','w','k'], N=1000)

#Figure 1 : modulo is applied on the data :
#Results : problem with the interpolation, but the colorbar is fine
z = np.mod(10*x,2*np.pi)
zMax = np.max(z)
levels = np.linspace(0., zMax,100)

fig1, ax1 = plt.subplots()
cax1=ax1.tricontourf(triang, z,cmap = cm,levels= levels)
fig1.colorbar(cax1)
plt.show()

#Figure 2 : We use the norm parameter with a custom norm that does the modulo
#Results : the graph is the way it should be but the colormap is messed up
z = 10*x
zMax = np.max(z)
levels = np.linspace(0., zMax,100)

fig2, ax2 = plt.subplots()
cax2=ax2.tricontourf(triang, z,levels= levels,norm = PeriodicNormalize(0, 2*np.pi),cmap = cm)
fig2.colorbar(cax2)
plt.show()

最后的解决方案是像我上面那样做:创建一个更大的颜色图,达到 zmax 并且每 2 pi 是周期性的。然而颜色条不会很好......

结果如下: Figure1 Figure2

最佳答案

我猜你的问题是在你调用 tricontourf 之前对你的数据使用模数引起的(我猜,它对你的数据进行了一些插值,然后将插值数据映射到颜色图) .相反,您可以将 norm 传递给您的 tricontourf 函数。写一个小类以下 this tutorial ,您可以让范数处理数据的模数。由于您的代码本身不可运行,因此我提出了一个更简单的示例。希望这适用于您的问题:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as colors

class PeriodicNormalize(colors.Normalize):
def __init__(self, vmin=None, vmax=None, clip=False):
colors.Normalize.__init__(self, vmin, vmax, clip)

def __call__(self, value, clip=None):
x, y = [self.vmin, self.vmax], [0, 1]

return np.ma.masked_array(np.interp(
np.mod(value-self.vmin, self.vmax-self.vmin),x,y
))

fig,ax = plt.subplots()
x,y = np.meshgrid(
np.linspace(0, 1, 1000),
np.linspace(0, 1, 1000),
)

z = x*10*np.pi
cm = colors.LinearSegmentedColormap.from_list('test', ['k','w','k'], N=1000)
ax.pcolormesh(x,y,z,norm = PeriodicNormalize(0, 2*np.pi), cmap = cm)
plt.show()

结果是这样的:

result of above code

编辑:

由于您从 tricontourf 返回的 ContourSet 跨越了整个阶段,而不仅仅是第一个 [0,2pi],颜色条是为整个范围创建,这就是为什么您会看到颜色图重复多次。我不太确定我是否了解滴答声是如何创建的,但我猜要让它自动正常工作需要做很多工作。相反,我建议像在 this tutorial 中所做的那样“手动”生成一个颜色条。 .但是,这需要您自己创建放置颜色条的轴 (cax)。幸运的是,有一个名为 matplotlib.colorbar.make_axes() 的函数可以为您执行此操作(感谢 this answer)。因此,不要使用原来的 colorbar 命令,而是使用这两行:

cax,kw = mcbar.make_axes([ax2], location = 'right')
cb1 = mcbar.ColorbarBase(cax, cmap = cm, norm = norm, orientation='vertical')

获取这张图片:

result of the mcve in the question with the colorbar generated by the two lines of code above

关于python - 使用 matplotlib tricontourf 绘制相位图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52202032/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com