Я хочу построить изображение результатов моделирования методом конечных элементов с помощью персонализированной карты цветов.Я пытался использовать 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. Проблема в том, что если я делаю этоМне нужно создать гораздо большую цветовую карту.В конечном счете, фаза будет очень большой, и поэтому я буду иметь цветовую карту, если я хочу правильное цветовое разрешение ... Более того, я бы хотел, чтобы в цветовой карте справа был только один период (как на первом рисунке).
Есть идеи, как мне получить фигуру, похожую на вторую, с такой же цветовой картой, как на первой фигуре, и без создания очень большой и дорогой цветовой карты?
РЕДАКТИРОВАТЬ: Я написал небольшой код, который можно запустить из коробки: он воспроизводит мою проблему, и я также попытался применить ответ Томаса Куна к моей задаче.Однако, кажется, что есть некоторая проблема с цветовой шкалой ... Любая идея, как я мог бы это исправить?
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 пи.Однако цветовая шкала не была бы хороша ...
вот результаты:
