使用matplotlib tricontou绘制相位图

2024-06-26 14:07:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我想用一个个性化的彩色地图来绘制有限元模拟结果的图像。 我一直在尝试使用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

你知道我怎样才能得到一个像第二个一样的图形,一个和第一个图形一样的颜色图,而不需要创建一个非常大而且昂贵的颜色图吗?在

编辑:我写了一个可以开箱即用的小代码:它再现了我遇到的问题,我还试图将托马斯·库恩的答案应用到我的问题上。不过,色卡似乎有一些问题。。。你知道我怎么解决这个问题吗?在

^{pr2}$

最后一个解决方案是像我上面所做的那样:创建一个大得多的colormap,它达到zmax,并且每2pi周期性。但是colorbar不太好。。。在

结果如下: Figure1Figure2


Tags: self颜色np地图fig绘制pltax
1条回答
网友
1楼 · 发布于 2024-06-26 14:07:47

我猜您的问题是因为在调用tricontourf之前对数据使用模(我猜,这会对数据进行一些插值,然后将插值的数据映射到colormap)。{{cd2>你可以传递给你的函数。在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

编辑

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

^{pr2}$

要获取此图片:

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

相关问题 更多 >