use*_*839 2 python graph matplotlib matplotlib-3d
基本上,我有一个由一组时间序列组成的曲面图,我想在特定高度添加剖面图,以更好地了解一年中值高于所选阈值的时期。
由此:
其中显示平面但不是剖面
对此:
有什么建议吗?
使用 alpha 和相机仰角并没有解决问题
平面似乎仍然在人物的前面,而不是作为一个截面
正如其他人指出的那样,matplotlib 的 3D 功能有些有限。为了将对象隐藏在其他对象后面,它使用画家算法。因此,对象只是从后到前绘制,并且没有对象部分放置在某个平面之前,部分放置在某个平面之后。Matplotlib 计算每个对象的平均深度来定义顺序。您可以通过 覆盖此订单ax.computed_zorder = False,因为自动计算并不总是如您所愿。
您可以自己绘制“图层”:
一个例子:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
from scipy.ndimage.filters import gaussian_filter
x = np.linspace(-10, 10, 51)
y = np.linspace(-10, 10, 51)
X, Y = np.meshgrid(x, y)
np.random.seed(20220201)
Z = np.random.rand(*X.shape) ** 5
Z[X ** 2 + Y ** 2 > 30] = 0
Z = gaussian_filter(Z, sigma=2) * 100
fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")
ax.computed_zorder = False
ax.plot_surface(X, Y, Z, cmap='turbo')
special_z = 16
ax.plot_surface(X, Y, np.full_like(Z, special_z), color='blue', alpha=0.4)
ax.plot_surface(X, Y, np.where(Z >= special_z, Z, np.nan), cmap='turbo', vmin=0)
plt.show()
Run Code Online (Sandbox Code Playgroud)
另一种方法是一次绘制一层表面。左侧的示例显示了分为 30 层的表面,右侧的示例停在给定的高度,可视化交叉点。
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
from scipy.ndimage.filters import gaussian_filter
x = np.linspace(-10, 10, 51)
y = np.linspace(-10, 10, 51)
X, Y = np.meshgrid(x, y)
np.random.seed(20220201)
Z = np.random.rand(*X.shape) ** 5
Z[X ** 2 + Y ** 2 > 30] = 0
Z = gaussian_filter(Z, sigma=2) * 100
fig = plt.figure()
for which in ['left', 'right']:
ax = fig.add_subplot(121 + (which == 'right'), projection="3d")
ax.computed_zorder = False
layers = np.linspace(Z.min(), Z.max(), 32)[1:-1]
colors = plt.get_cmap('turbo', len(layers)).colors
special_z = 16
plane_drawn = False
for layer, color in zip(layers, colors):
if layer >= special_z and not plane_drawn:
ax.plot_surface(X, Y, np.full_like(Z, special_z), color='blue', alpha=0.5, zorder=2)
plane_drawn = True
ax.contour(X, Y, Z, levels=[layer], offset=layer, colors=[color])
if plane_drawn and which == 'right':
break
plt.show()
Run Code Online (Sandbox Code Playgroud)