Создание трехмерного графика поверхности с данными из точек сетки разных размеров в Python - PullRequest
0 голосов
/ 16 мая 2018

Я научился объединять точки сетки сетки из двух прямоугольников в python из этого вопроса.Точки объединенной сетки:

enter image description here

Здесь каждая точка сетки содержит свои соответствующие значения, и я хочу построить ее трехмерный график поверхности.Для полной сетки (без пустого места) я написал бы следующий код:

fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
x=np.arange(0,10,1)
y=np.arange(0,12,1)
X, Y = np.meshgrid(x,y)
print (Y)
Z = gridValue.reshape(X.shape)
cset = ax.pcolormesh(X, Y, Z, cmap=cm.coolwarm, linewidth =0, antialiased = False)
ax.clabel(cset, fontsize=9, inline=1)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('σ ')
fig.colorbar(cset, shrink=0.5, aspect =5)
plt.show()

Когда я пытаюсь построить значения сетки (80 точек) с помощью приведенного выше кода, я получаю очевидную ошибку:

ValueError: cannot reshape array of size 80 into shape (12,10)

Я ожидаюследующий рисунок (не совсем точно, но аналогично) в качестве окончательного трехмерного графика поверхности:

enter image description here

Как нарисовать трехмерный график поверхностимоя ситуация?

Спасибо.

РЕДАКТИРОВАТЬ: Я пытался построить, используя следующий фрагмент кода:

fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
x1=np.arange(0,2,1)
x2 = np.arange(0,10,1)
y1 =np.arange(0,5,1)
y2=np.arange(5,12,1)
Y1, X1 = np.meshgrid(x1,y1)
Y2, X2 = np.meshgrid(x2,y2)
gridValue1 = gridValue[:10]
gridValue2 = gridValue[10:]
Z1 = gridValue1.reshape(X1.shape)
Z2 = gridValue2.reshape(X2.shape)
cset1 = ax.plot_surface(X1, Y1, Z1, cmap=cm.coolwarm, linewidth =0, antialiased = False)
cset2 = ax.plot_surface(X2, Y2, Z2, cmap=cm.coolwarm, linewidth =0, antialiased = False)
ax.clabel(cset1, fontsize=9, inline=1)
ax.clabel(cset2, fontsize=9, inline=1)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('σ ')
plt.show()

Я получил следующую цифру с этим кодом:

enter image description here

Теперь проблема заключается в иллюстрациифигураЦветовой код (красный цвет для высокого значения, синий цвет для низкого значения) больше не действителен.Поскольку gridValues точек синего пояса (на первом рисунке) высоки, поэтому большинство из них должно иметь красный цвет на поверхности графика.Таким образом, объединение двух отдельных трехмерных поверхностей не является решением моей проблемы.Любая помощь, пожалуйста!

1 Ответ

0 голосов
/ 16 мая 2018

Если ваш массив gridValue больше вашей сетки с (12,10), вам нужно интерполировать gridValue до правильной формы.В вашем случае, так как я предполагаю, что вы хотите построить показанные фигуры с 80 точками, вам нужно построить массив для gridValue с формой сетки, а затем распределить ваши 80 значений сетки в правильные положенияgridValue массив с формой (12,10).То, как вы можете осуществлять распространение, полностью зависит от имеющейся у вас информации, поэтому, к сожалению, я не могу вам с этим помочь.Но, например, учитывая y-отсортированное последовательное распределение синих и зеленых сеток:

gridValue_new = np.zeros_like(X)
gridValue_new[:, 0] = gridValue[:12]
gridValue_new[:, 1] = gridValue[12:24]
gridValue_new.reshape(-1)[:8, 2:] = gridValue[24:]

Первые две точки распределения линий можно также переписать, используя reshape().

Если вы хотитечтобы построить его в 2d, используйте pcolormesh.Для 3d-печати, использование ax.plot_surface() будет соответствовать вашим потребностям.Если вы хотите построить обе сетки на одной оси, сделайте следующее:

from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt

X, Y = np.meshgrid(np.arange(0, 10, 1), np.arange(0, 12, 1))
X1 = X[5:, :]
Y1 = Y[5:, :]
X2 = X[0:5, 0:2]
Y2 = Y[0:5, 0:2]
Z1 = np.random.rand(7, 10)  # generating some random grid values
Z2 = np.random.rand(5, 2)

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X1, Y1, Z1)
ax.plot_surface(X2, Y2, Z2)

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

vmin = gridValue.min()
vmax = gridValue.max()

ипередайте оба аргумента в plot_surface():

cset1 = ax.plot_surface(X1, Y1, Z1, cmap=cm.coolwarm, linewidth =0, antialiased = False, vmin=vmin, vmax=vmax)
cset2 = ax.plot_surface(X2, Y2, Z2, cmap=cm.coolwarm, linewidth =0, antialiased = False, vmin=vmin, vmax=vmax)

Таким образом, ваш полный код будет выглядеть так:

fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
x1=np.arange(0,2,1)
x2 = np.arange(0,10,1)
y1 =np.arange(0,5,1)
y2=np.arange(5,12,1)
Y1, X1 = np.meshgrid(x1,y1)
Y2, X2 = np.meshgrid(x2,y2)
gridValue1 = gridValue[:10]
gridValue2 = gridValue[10:]
Z1 = gridValue1.reshape(X1.shape)
Z2 = gridValue2.reshape(X2.shape)
vmin = gridValue.min()
vmax = gridValue.max()
cset1 = ax.plot_surface(X1, Y1, Z1, cmap=cm.coolwarm, linewidth =0, antialiased = False, vmin=vmin, vmax=vmax)
cset2 = ax.plot_surface(X2, Y2, Z2, cmap=cm.coolwarm, linewidth =0, antialiased = False, vmin=vmin, vmax=vmax)
ax.clabel(cset1, fontsize=9, inline=1)
ax.clabel(cset2, fontsize=9, inline=1)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('σ ')
plt.show()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...