Я пытаюсь построить некоторые данные для измерения, сделанного между двумя поверхностями. Направление z в системе определяется как нормальное к поверхностям. Проблема в том, что вдоль оси x моего графика я меняю расстояние между двумя поверхностями, что означает, что для каждого среза изменяется минимальное/максимальное значение оси y. Я обошёл это, представив нормализованную ось Y, где z_min - нижняя поверхность, а z_max - верхняя поверхность: 
Однако такое представление несколько искажает данные. В идеале я хотел бы показать фактическое расстояние до стены по оси Y и просто оставить области за пределами границ системы белыми. Я (плохо) набросал то, что представляю здесь (фактическое распределение на тепловой карте, конечно, должно выглядеть иначе): 
Я могу довольно легко изобразить то, что хочу, в виде 3D-графика рассеяния, например: 
Но как преобразовать данные в форму для построения тепловой карты?
Я предполагаю, что мне придется взорвать массив MxN и заполнить недостающие значения с помощью интерполяции или просто пометить их как NAN? Но тогда я также не совсем уверен, как добавить жесткую отсечку к моей цветовой схеме, чтобы сделать все за пределами системы белым.
Ответ 1 · рейтинг 2 · tacaswell
Вы можете сделать это с помощью pcolormesh, который принимает углы четырехугольников в качестве аргументов.
X, Y = np.meshgrid(np.linspace(0, 10, 100), np.linspace(0, 2*np.pi, 150),)
h = np.sin(Y)
Y *= np.linspace(.5, 1, 100)
fig, ax = plt.subplots(1, 1)
ax.pcolormesh(X, Y, h)
Ответ 2 · рейтинг 2 · GBy
Ниже приведена реализация с контурной треугольной сеткой, основанная на примере CT Zhu.
Если ваша область не является выпуклой, вам нужно будет предоставить свои собственные треугольники для триангуляции, так как триангуляция Делоне по умолчанию создает сетку выпуклой оболочки из ваших точек.
import matplotlib
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.tri as mtri
y = np.array([np.linspace(-i, i, 51) for i in (
np.linspace(5, 10))[::-1]])
x = (np.zeros((50, 51)) +
np.linspace(1, 6, 50)[..., np.newaxis])
z = (np.zeros((50, 51)) -
np.linspace(-5, 5, 51)**2 + 10) # make up some z data
x = x.flatten()
y = y.flatten()
z = z.flatten()
print "x shape: ", x.shape
triang = mtri.Triangulation(x, y)
plt.tricontourf(triang, z)
plt.colorbar()
plt.show()
Ответ 3 · рейтинг 1 · CT Zhu
Я думаю, может быть, 2D-интерполяция с использованием griddata будет тем, что вам нужно?
from matplotlib.mlab import griddata
xi=linspace(1,5,100)
yi=linspace(-10.5, 10.5, 100)
y=array([linspace(-i, i, 51) for i in (linspace(5,10))[::-1]]) #make up some y vectors with different range
x=zeros((50,51))+linspace(1,6, 50)[...,newaxis]
z=zeros((50,51))-linspace(-5, 5,51)**2+10 #make up some z data
x=x.flatten()
y=y.flatten()
z=z.flatten()
zi=griddata(x, y, z, xi, yi)
plt.contourf(xi, yi, zi, levels=-linspace(-5, 5,51)**2+10)