pce*_*con 22 python matplotlib mplot3d contourf
我只是试图用3D绘制曲面及其轮廓,就像在这个例子中一样.
这是我用来做的代码:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
from matplotlib import cm
import numpy
def plot_3d_contour(x_dim, y_dim, x_steps, y_steps, scalar_field, file_path):
fig = plt.figure()
x, y = numpy.mgrid[-x_dim/2:x_dim/2:x_steps*1j, -y_dim/2:y_dim/2:y_steps*1j]
v_min = numpy.min(scalar_field)
v_max = nupmy.max(scalar_field)
ax = fig.gca(projection='3d')
cset = ax.contourf(x, y, scalar_field, zdir='z', offset=v_min, cmap=cm.coolwarm)
cset = ax.contourf(x, y, scalar_field, zdir='x', offset=-x_dim/2-1, cmap=cm.coolwarm)
cset = ax.contourf(x, y, scalar_field, zdir='y', offset=y_dim/2+1, cmap=cm.coolwarm)
ax.plot_surface(x, y, scalar_field, rstride=10, cstride=10, alpha=0.3)
ax.set_xlabel('X')
ax.set_xlim(-x_dim/2-1, x_dim/2+1)
ax.set_ylabel('Y')
ax.set_ylim(-y_dim/2-1, y_dim/2+1)
ax.set_zlabel('Z')
ax.set_zlim(v_min, v_max)
plt.savefig(file_path + '.jpg')
plt.close()
scalar_field = numpy.loadtxt('../scalar_field', delimiter=",")
plot_3d_contour(12, 12, 100, 100, scalar_field, 'scalar_field3D')
Run Code Online (Sandbox Code Playgroud)
但是,我得到一个奇怪的行为,其中a contour(zdir=y)在表面上.此外,我得到了一个奇怪的轮廓z_dir=z(缺少一个部分):

我想知道我错过了什么.标量字段可以在这里找到.
我同意Ajean的观点.我相信问题出现是因为每个matplotlib的艺术家(即PolygonCollection)都是单独渲染的.在同一对象中,不可能在场景中的另一个对象的不同侧面上渲染不同的面.
这是一段有用的代码:
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
file_path = "./3D_surface_and_contour.jpg"
p = 0.05
f = -0.01
def get_data(p):
x, y, z = axes3d.get_test_data(p)
z = f * z
return x, y, z
def plot_3d_contour(p, f):
nrows = 4
ncols = 5
x, y, z = get_data(p)
x_min, x_max = np.min(x), np.max(x)
y_min, y_max = np.min(y), np.max(y)
z_min, z_max = np.min(z), np.max(z)
fig = plt.figure(figsize=(15, 10))
for n in range(nrows * ncols):
i = n % ncols
j = n / ncols
k = n + 1
if j == 0:
azim = -60 + (i - 2) * 15
elev = 30
elif j == 1:
azim = -60
elev = 30 + (i - 2) * 5
elif j == 2:
azim = 60 + (i - 2) * 10
elev = 30
elif j == 3:
azim = 60
elev = 30 + (i - 2) * 5
ax = fig.add_subplot(nrows, ncols, k, projection='3d')
ax.set_title("azim=" + str(azim) + " elev=" + str(elev))
ax.tick_params(labelsize=8)
ax.view_init(azim=azim, elev=elev)
ax.plot_surface(x, y, z, rstride=10, cstride=10, alpha=0.3)
ax.contourf(x, y, z, zdir='z', offset=z_min, cmap=cm.coolwarm)
ax.contourf(x, y, z, zdir='x', offset=x_min, cmap=cm.coolwarm)
if j == 0 or j == 1:
ax.contourf(x, y, z, zdir='y', offset=y_max, cmap=cm.coolwarm)
elif j == 2 or j == 3:
ax.contourf(x, y, z, zdir='y', offset=y_min, cmap=cm.coolwarm)
ax.set_xlabel('X')
ax.set_xlim(x_min, x_max)
ax.set_ylabel('Y')
ax.set_ylim(y_min, y_max)
ax.set_zlabel('Z')
ax.set_zlim(z_min, z_max)
plt.savefig(file_path, dpi=80)
plt.close()
plot_3d_contour(p, f)
Run Code Online (Sandbox Code Playgroud)
它给出了以下图像:

前两行由类似于您的代码生成.您可能会注意到将高程设置view_init为更高的值可以解决问题.但这并不令人满意.我还确定了z值范围的影响(这里没有显示),这个bug似乎只在这个范围很小时出现(你可以用f参数来测试它),这解释了为什么这个例子没有受到影响它.
我建议的解决方案是替换:
ax.contourf(x, y, scalar_field, zdir='y', offset=y_dim/2+1, cmap=cm.coolwarm)
Run Code Online (Sandbox Code Playgroud)
通过:
ax.contourf(x, y, scalar_field, zdir='y', offset=-y_dim/2-1, cmap=cm.coolwarm)
Run Code Online (Sandbox Code Playgroud)
在您的代码中添加以下附加行:
ax.view_init(azim=60, elev=30)
Run Code Online (Sandbox Code Playgroud)
如前一个图像的最后两行所示,这样您就可以避免matplotlib的突发奇想.
| 归档时间: |
|
| 查看次数: |
8988 次 |
| 最近记录: |