Как мне создать график поверхности в matplotlib, когда Z уже вычислен?

#python #numpy #matplotlib

#python #numpy #matplotlib

Вопрос:

Я видел следующий пример для графика поверхности здесь, в разделе Графика поверхности:

 from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
import numpy as np


fig = plt.figure()
ax = fig.gca(projection='3d')

# Make data.
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2   Y**2)
Z = np.sin(R)

# Plot the surface.
surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm,
                       linewidth=0, antialiased=False)

# Customize the z axis.
ax.set_zlim(-1.01, 1.01)
ax.zaxis.set_major_locator(LinearLocator(10))
ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))

# Add a color bar which maps values to colors.
fig.colorbar(surf, shrink=0.5, aspect=5)

plt.show()
  

В примере координаты X и Y предоставляются в виде векторов, которые позже будут повторно использоваться как координатная сетка XY с помощью команды mesh .

В примере Z вычисляется непосредственно из X, Y. Однако в моем случае я использую ранее вычисленное значение для Z (так или иначе, я уже выполнял функцию сетки на предыдущих шагах):

 array([[1.00000000e 00, 1.00000000e 01, 1.59135708e 06],
       [1.00000000e 00, 1.10000000e 01, 2.44938222e 06],
       [1.00000000e 00, 1.20000000e 01, 3.96364528e 06],
       [1.00000000e 00, 1.30000000e 01, 6.13414627e 06],
       [1.00000000e 00, 1.40000000e 01, 8.96088517e 06],
       [2.00000000e 00, 1.00000000e 01, 1.59386643e 06],
       [2.00000000e 00, 1.10000000e 01, 2.45962860e 06],
       [2.00000000e 00, 1.20000000e 01, 3.98162868e 06],
       [2.00000000e 00, 1.30000000e 01, 6.15986668e 06],
       [2.00000000e 00, 1.40000000e 01, 8.99434261e 06],
       [3.00000000e 00, 1.00000000e 01, 1.59647579e 06],
       [3.00000000e 00, 1.10000000e 01, 2.46997497e 06],
       [3.00000000e 00, 1.20000000e 01, 3.99971208e 06],
       [3.00000000e 00, 1.30000000e 01, 6.18568710e 06],
       [3.00000000e 00, 1.40000000e 01, 9.02790005e 06],
       [4.00000000e 00, 1.00000000e 01, 1.59918515e 06],
       [4.00000000e 00, 1.10000000e 01, 2.48042135e 06],
       [4.00000000e 00, 1.20000000e 01, 4.01789548e 06],
       [4.00000000e 00, 1.30000000e 01, 6.21160752e 06],
       [4.00000000e 00, 1.40000000e 01, 9.06155749e 06]])
  

Итак, первый столбец — это X, второй — Y, а третий — Z.

Z берется из R, который вычисляется с использованием np.sqrt(X**2 Y**2) и X , Y уже являются переменными, созданными с помощью mesh .

Как эти значения должны быть присвоены переменным X , Y и Z ?

Ответ №1:

Предположим, у вас есть aray arr . Затем вы можете привести его к формату, ожидаемому matplotlib как:

 # Make data.
X = arr[:,0].reshape((4,5)).T
Y = arr[:,1].reshape((4,5)).T
Z = arr[:,2].reshape((4,5)).T
  

и построить:

 from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
import numpy as np


fig = plt.figure()
ax = fig.gca(projection='3d')
# Plot the surface.
surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm,
                       linewidth=0, antialiased=False)

# Customize the z axis.
# ax.set_zlim(-1.01, 1.01)
# ax.zaxis.set_major_locator(LinearLocator(10))
ax.zaxis.set_major_formatter(FormatStrFormatter('%.1E'))

# Add a color bar which maps values to colors.
fig.colorbar(surf, shrink=.7, aspect=5, pad=.1);
  

введите описание изображения здесь

Вы также можете обобщить, как:

 from itertools import groupby
total_length = arr.shape[0]
group_length = [len(list(g)) for _,g in groupby(arr[:,0])]
print(f"Reshape 1st: {int(total_length/group_length[0])}",f"Reshape 2nd: {int(group_length[0])}",sep="n")
Reshape 1st: 4 
Reshape 2nd: 5
  

Комментарии:

1. Спасибо, Сергей, почему вы используете именно 4 и 5 ( .reshape(4,5) )?

2. Это потому, что ваш массив структурирован: 4 группы по 5 точек