【问题标题】:Flat surfaces in matplotlib 3D plotmatplotlib 3D 绘图中的平面
【发布时间】:2020-05-23 19:32:35
【问题描述】:

我正在尝试使用 matplotlib 创建一个 3D 图,它表示特定域的外边界。该边界由上表面和下表面组成,使用plot_surface 方法很容易将其可视化。我的问题是可视化平行于 xz 和 yz 平面的四个平面(见下图)。由于这些表面也限制了域,我希望它们的颜色稍微透明。我的问题是,我怎样才能做到这一点?下面附有上下边界的最小工作示例以及说明所需结果的图像。提前感谢您的帮助!

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

# Values for g11up and g11dw
x = np.linspace(-1, 1, 50)

# Meshgrid
X, Y = np.meshgrid(x, x)
Z = 2 - (X**2 + Y**2)

# Create figure and axes
fig = plt.figure(figsize=(4, 4.5))
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel(r'$x$')
ax.set_ylabel(r'$y$')
ax.set_zlabel(r'$z$')

# Plot the upper surface
ax.plot_surface(X, Y, -Z, cmap=cm.Blues, vmin=-2*Z.max(), vmax=Z.max(),
                alpha=0.9, linewidth=0)

# Plot the lower surface
ax.plot_surface(X, Y, Z, cmap=cm.Blues, vmin=-2*Z.max(), vmax=Z.max(),
                alpha=0.9, linewidth=0)

# Plot edges
z = 1-x**2
for sign in [1, -1]:
    ax.plot(x, np.ones(len(x)), sign*z, color='k', lw=1, zorder=3)
    ax.plot(x, -np.ones(len(x)), sign*z, color='k', lw=1, zorder=4)
    ax.plot(np.ones(len(x)), x, sign*z, color='k', lw=1, zorder=4)
    ax.plot(-np.ones(len(x)), x, sign*z, color='k', lw=1, zorder=3)

ax.set_aspect('equal')
plt.show()
plt.close()

【问题讨论】:

标签: python matplotlib plot 3d


【解决方案1】:

给你:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection # New import

# Values for g11up and g11dw
x = np.linspace(-1, 1, 50)

# Meshgrid
X, Y = np.meshgrid(x, x)
Z = 2 - (X**2 + Y**2)

# Create figure and axes
fig = plt.figure(figsize=(4, 4.5))
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel(r'$x$')
ax.set_ylabel(r'$y$')
ax.set_zlabel(r'$z$')

# Plot the upper surface
ax.plot_surface(X, Y, -Z, cmap=cm.Blues, vmin=-2*Z.max(), vmax=Z.max(),
                alpha=0.9, linewidth=0)

# Plot the lower surface
ax.plot_surface(X, Y, Z, cmap=cm.Blues, vmin=-2*Z.max(), vmax=Z.max(),
                alpha=0.9, linewidth=0)

# Plot edges
z = 1-x**2
for sign in [1, -1]:
    ax.plot(x, np.ones(len(x)), sign*z, color='k', lw=1, zorder=3)
    ax.plot(x, -np.ones(len(x)), sign*z, color='k', lw=1, zorder=4)
    ax.plot(np.ones(len(x)), x, sign*z, color='k', lw=1, zorder=4)
    ax.plot(-np.ones(len(x)), x, sign*z, color='k', lw=1, zorder=3)

# Plot faces
for sign in [1,-1]:
    xyz_upper = np.stack((x,sign*np.ones(x.shape), z)).T
    xyz_lower = np.stack((x,sign*np.ones(x.shape),-z)).T[::-1]
    xyz = np.concatenate((xyz_upper,xyz_lower))
    verts = [ ( xyz[i,0], xyz[i,1], xyz[i,2] ) for i in range(xyz.shape[0])  ]
    ax.add_collection3d(Poly3DCollection([verts], alpha=0.5, facecolor='orange'))

ax.set_aspect('equal')
plt.show()

必须有一种方法可以将 numpy 数组直接传递给Poly3DCollection 而无需将其转换为元组列表,但我没有寻找它。

这是结果:

显然我选择了橙色,我只画了垂直于 y 轴的两个面,但将其延伸到另一侧是笔直的。

我的回答受到了answer 的启发。 换颜色的时候可能会碰到this bug

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-10
    相关资源
    最近更新 更多