我有使用 matplotlib 的 mplot3d 库绘制的 4D 数据(3D 散点 + 颜色)。为了帮助解析点云在空间中的分布方式,我想使用 2D 直方图/等值线图显示点云在 3 个平面(XY、XZ、YZ)中的每一个平面上的投影。
这是一个 MWE,它使用 ax.plot
来做我想做的事(根据下面的链接)。这在技术上是可行的,但我认为用等高线图替换 ax.plot
中的 buck-shot 会在视觉上更令人愉悦:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# Prepare sample data - normally distributed
NSamples = 5000
vmin, vmax = -2, 2
X = np.random.normal(loc=-.1, scale=.5, size=(NSamples,))
Y = np.random.normal(loc=.1, scale=.25, size=(NSamples,))
Z = np.random.normal(loc=0, scale=1, size=(NSamples,))
# Create figure, add subplot with 3d projection
fig = plt.figure(figsize=(5,5))
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_zlabel("Z")
ax.set_xlim(vmin, vmax)
ax.set_ylim(vmin, vmax)
ax.set_zlim(vmin, vmax)
# Plot the data cloud
ax.scatter(X, Y, Z, s=.5, alpha=.05, color='k')
# Plot the 2D projections using `plot`. This is the piece I'd like to improve
ax.plot(X, Y, '+', markersize=.2, color='r', zdir='z', zs=-2.)
ax.plot(X, Z, '+', markersize=.2, color='g', zdir='y', zs=2.)
ax.plot(Y, Z, '+', markersize=.2, color='b', zdir='x', zs=-2.)
plt.savefig("3DScatter.png")
# Now, I'd *like* for the following histograms to be plotted on each of the XY, XZ, YZ planes
instead of using `plot` above
for label, data_x, data_y in [ ['XY', X, Y], ['XZ', X, Z], ['YZ', Y, Z] ]:
hist, binx, biny = np.histogram2d( data_x, data_y, bins=[xbins, ybins])
plt.figure(figsize=(5,5))
plt.imshow(hist, extent=[vmin,vmax,vmin,vmax])
plt.xlabel(label[1])
产生:
等等
所以要明确一点,有没有一种方法可以在相关的 3D 轴上绘制用上面的 imshow
绘制的 XY、XZ、YZ 2D 直方图?基于 contour
的解决方案也可以。
请注意(我相当确定)这不是 this related question 的重复,其解决方案仅适用于 2D 数据 (f(x,y)),不适用于 3D (f(x,y,z))。
最佳答案
如果您可以使用 contour
或 contourf
,您可以这样做:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# Prepare sample data - normally distributed
NSamples = 5000
vmin, vmax = -2, 2
X = np.random.normal(loc=-.1, scale=.5, size=(NSamples,))
Y = np.random.normal(loc=.1, scale=.25, size=(NSamples,))
Z = np.random.normal(loc=0, scale=1, size=(NSamples,))
# Create figure, add subplot with 3d projection
fig = plt.figure(figsize=(5,5))
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_zlabel("Z")
ax.set_xlim(vmin, vmax)
ax.set_ylim(vmin, vmax)
ax.set_zlim(vmin, vmax)
# Plot the data cloud
ax.scatter(X, Y, Z, s=.5, alpha=.05, color='k')
hist, binx, biny = np.histogram2d( X, Y)
x = np.linspace(X.min(), X.max(), hist.shape[0])
y = np.linspace(Y.min(), Y.max(), hist.shape[1])
x, y = np.meshgrid(x, y)
ax.contour(x, y, hist, zdir='z', offset=-3.)
hist, binx, biny = np.histogram2d( X, Z)
x = np.linspace(X.min(), X.max(), hist.shape[0])
z = np.linspace(Z.min(), Z.max(), hist.shape[1])
x, z = np.meshgrid(x, z)
ax.contour(x, hist, z, zdir='y', offset=3)
hist, binx, biny = np.histogram2d( Y, Z)
y = np.linspace(Y.min(), Y.max(), hist.shape[0])
z = np.linspace(Z.min(), Z.max(), hist.shape[1])
z, y = np.meshgrid(z, y)
ax.contour(hist, y, z, zdir='x', offset=-3)
ax.set_xlim([-3, 3])
ax.set_ylim([-3, 3])
ax.set_zlim([-3, 3])
关于python - 如何在 XY/XZ/YZ 平面上绘制 3D 散点数据的投影?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30292169/