- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我想用个性化的颜色图绘制有限元模拟结果的图像。我一直在尝试使用 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)
正如您所看到的,当存在模数时,相位从 2pi 变为 0 时会出现一些问题,这是来自 tricontourf...
我的第一个解决方法是直接在我的 Z 阶段工作。问题是,如果我这样做,我需要创建一个更大的颜色图。最终,相位将非常大,如果我想要正确的颜色分辨率,颜色图也会非常大......此外,我希望右侧的颜色图中只有一个周期(就像在第一个图中)。
知道如何获得与第二个图一样的图,具有与第一个图相同的色图,而无需创建非常大且昂贵的色图吗?
编辑:我写了一个开箱即用的小代码:它重现了我遇到的问题,我也尝试将 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 是周期性的。然而颜色条不会很好......
最佳答案
我猜你的问题是在你调用 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()
结果是这样的:
编辑:
由于您从 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')
获取这张图片:
关于python - 使用 matplotlib tricontourf 绘制相位图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52202032/
我正在尝试用 Python 制作颜色图,除了这个让 map 看起来很糟糕的小烦恼外,我什么都有。 代码很简单。我只是使用一个值矩阵并使用 tricontourf 绘制它们。我在我的情节中循环遍历集合并
我想用个性化的颜色图绘制有限元模拟结果的图像。我一直在尝试使用 tricontourf 将其绘制如下: #Z = self.phi.compute_vertex_values(self.mes
我在尝试绘制压力图时遇到了问题。 import numpy as np import matplotlib.pyplot as plt import matplotlib.tri as mtri im
我有一些 numpy 数组,其中包含我将在 2D 网格上可视化的数据。有些数据是非物理的,我想屏蔽这些数据。但是,我不知道如何正确设置 tricontour 的 mask 属性。我试过: import
我在常规笛卡尔网格上定义了一些数据。我只想显示其中一些具有基于中心半径的条件。这将有效地创建一个在中心有一个孔的环状结构。因此,我无法使用 imshow。 tricontourf 或 tripcolo
我是一名优秀的程序员,十分优秀!