2013-11-18 2 views
0

Этот вопрос является продолжением предыдущего one, но на этот раз это цветовая схема и порядок треугольника. Я хочу интерполировать экспериментальные данные по поверхности, чтобы обеспечить непрерывную цветовую палитру, но поверхность известна только на ее угловом узле. Чтобы интерполировать, я помещаю канонический пример, который работает довольно хорошо, но не работает на реальных данных.Изменение порядка треугольников для соответствия colormap

Действительно, как показано в примере ниже, исходная триангуляция приводит к двум треугольникам с огромным промежутком между ними, cf first picture. Когда интерполяция выполнена, она не улучшается, и цветовая палитра также теряется, ср. второе изображение. Самое лучшее до сих пор - переключение z и y, чтобы получить смежные треугольники с самого начала, что приводит к успешной интерполяции. Однако, как вы могли заметить на третьем рисунке, поверхность наклонена на 90 °, что является нормальным, так как я переключаю y на z и наоборот.

Однако, когда я выключаю y и z в функции tri_surf с ax.plot_trisurf(new.x, new_z, new.y, **kwargs), цветовая палитра не следует, ср. picture 4.

Я подумал о том, чтобы каким-то образом изменить цветную карту или создать новые треугольники из интерполированных с triang = tri.Triangulation(new.x, new_z), но без каких-либо успехов. Итак, любая идея или намек на правильное выполнение начальной триангуляции с двумя соседними треугольниками, как и для третьего изображения, но с поверхностно-ориентированной корреляцией и, в конечном счете, с цветовой палитрой, пропорциональной значению Y.

import numpy 
from mpl_toolkits.mplot3d import Axes3D 
import matplotlib.pyplot as plt 
from matplotlib import cm 
import matplotlib.tri as tri 

x=numpy.array([0.00498316, 0.00498316, 0.00996632, 0.00996632]) 
y=numpy.array([-0.00037677, -0.00027191, -0.00078681, -0.00088475]) 
z=numpy.array([0., -0.0049926, 0., -0.00744763]) 

# Initial Triangle  
fig = plt.figure() 
ax = Axes3D(fig) 
triang = tri.Triangulation(x, y) 

norm = plt.Normalize(vmax=y.max(), vmin=y.min()) 
ax.plot_trisurf(x, y, z, triangles=triang.triangles) 

# Interpolated Triangle 
fig = plt.figure() 
ax = Axes3D(fig) 
triang = tri.Triangulation(x, y) 
refiner = tri.UniformTriRefiner(triang) 
interpolator = tri.LinearTriInterpolator(triang, z) 
new, new_z = refiner.refine_field(z, interpolator, subdiv=4) 

kwargs = dict(triangles=new.triangles, cmap=cm.jet, norm=norm, linewidth=0,  antialiased=False) 
ax.plot_trisurf(new.x, new.y, new_z, **kwargs) 

# Best so far 
fig = plt.figure() 
ax = Axes3D(fig) 
triang = tri.Triangulation(x, z) 
refiner = tri.UniformTriRefiner(triang) 
interpolator = tri.LinearTriInterpolator(triang, y) 
new, new_z = refiner.refine_field(y, interpolator, subdiv=4) 

kwargs = dict(triangles=new.triangles, cmap=cm.jet, norm=norm, linewidth=0, antialiased=False) 
ax.plot_trisurf(new.x, new.y, new_z, **kwargs) 

plt.show() 

enter image description here enter image description here enter image description here enter image description here

+0

Вы нормализуют цветовую палитру на основе гамма-лимитов; Я думаю, если бы вы нормализовались на z (это значение по умолчанию), вы получите симпатичный набор цветов. Какую информацию вам нравится в цветовой пачке? –

+0

Реальные данные - это деформация крыла вблизи его резонанса. Ось y для меня - самые важные данные, являющиеся основным прогибом, и, таким образом, мои ключевые данные ... – TazgerO

ответ

1

Видимо автоматическая триангуляция не дает правильных треугольников для вас, но вы можете указать, как вы хотите, чтобы ваши треугольники вручную:

triang = tri.Triangulation(x, y, [[3,2,1],[1,2,0]]) 

# alternatively: 
triang = tri.Triangulation(x, y, [[3,2,0],[1,3,0]]) 

Эти два способа дают весьма разные результаты:

on the left: [[3,2,1],[1,2,0]], on the right: [[3,2,0],[1,3,0]]

Однако теперь интерполяция становится неудобно, потому что для некоторых (х, у) существует множество Z-значение .. Один из способов обхода этой проблемы является интерполирования и построение 2 больших треугольников отдельно:

import numpy 
from mpl_toolkits.mplot3d import Axes3D 
import matplotlib.pyplot as plt 
from matplotlib import cm 
import matplotlib.tri as tri 


def plot_refined_tri(x, y, z, ax, subdiv=4, **kwargs): 
    triang = tri.Triangulation(x, y) 
    refiner = tri.UniformTriRefiner(triang) 
    interpolator = tri.LinearTriInterpolator(triang, z) 
    new, new_z = refiner.refine_field(z, interpolator, subdiv=subdiv) 
    ax.plot_trisurf(new.x, new.y, new_z, triangles=new.triangles, **kwargs) 


x=numpy.array([0.00498316, 0.00498316, 0.00996632, 0.00996632]) 
y=numpy.array([-0.00037677, -0.00027191, -0.00078681, -0.00088475]) 
z=numpy.array([0., -0.0049926, 0., -0.00744763]) 

fig = plt.figure() 
ax = Axes3D(fig) 
# note: I normalized on z-values to "fix" the colormap 
norm = plt.Normalize(vmax=z.max(), vmin=z.min()) 
kwargs = kwargs = dict(linewidth=0.2, cmap=cm.jet, norm=norm) 

idx = [3,2,1] 
plot_refined_tri(x[idx], y[idx], z[idx], ax, **kwargs) 

idx = [1,2,0] 
plot_refined_tri(x[idx], y[idx], z[idx], ax, **kwargs) 

plt.show() 

Результат:

This looks good

+0

Точно, что я искал ... вы качаете! – TazgerO

+0

@TazgerO, обратите внимание, что в моем коде colormap отображает значения z, а не y-значения! Я не уверен, что есть простой способ применить colormap к чему-либо, кроме оси z.? (так как вы * можете * делать с 'plot_surface') –

+0

@TazgerO, в источнике' plot_trisurf' есть на самом деле этот комментарий: «TODO: поддержка пользовательских цветов лица». Поэтому я боюсь, что сопоставление цвета с значениями y будет сложно. –