如何在Python中绘制可旋转的三维散点图?

26

目前我正在使用matplotlib绘制三维散点图,虽然它能完成任务,但我似乎找不到旋转视角以更好地查看数据的方法。

这里是一个例子:

import pylab as p
import mpl_toolkits.mplot3d.axes3d as p3

#data is an ndarray with the necessary data and colors is an ndarray with
#'b', 'g' and 'r' to paint each point according to its class

...

fig=p.figure()
ax = p3.Axes3D(fig)
ax.scatter(data[:,0], data[:,2], data[:,3], c=colors)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
fig.add_axes(ax)
p.show()

我希望能够在执行期间旋转数据,但只要旋转快速简洁,就可以接受任何解决方案。

这里是将PCA应用于鸢尾花数据集后生成的图形比较:
1. Mayavi
alt text
2. Matplotlib
alt text

Mayavi使得数据可视化更加容易,但是Matplotlib看起来更加专业。Matplotlib也更轻量级。

2个回答

30

首先,你需要定义你所说的“更好地查看我的数据”是什么意思...

如果你想要交互式地工作,可以使用鼠标旋转和缩放绘图。

如果你只想通过编程方式旋转轴,则可以使用ax.view_init(elev, azim),其中elevazim是你想从中查看绘图的仰角和方位角(以度为单位)。

或者,你也可以使用ax.elevax.azimax.dist属性来获取/设置当前视点的仰角、方位角和距离。

以上内容引用自这个示例源代码可供借鉴。

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

def randrange(n, vmin, vmax):
    return (vmax-vmin)*np.random.rand(n) + vmin

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
n = 100
for c, m, zl, zh in [('r', 'o', -50, -25), ('b', '^', -30, -5)]:
    xs = randrange(n, 23, 32)
    ys = randrange(n, 0, 100)
    zs = randrange(n, zl, zh)
    ax.scatter(xs, ys, zs, c=c, marker=m)

ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')

plt.show()

我们得到了一个漂亮的散点图: alt text

你可以像下面这样通过程序旋转坐标轴:

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

def randrange(n, vmin, vmax):
    return (vmax-vmin)*np.random.rand(n) + vmin

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
n = 100
for c, m, zl, zh in [('r', 'o', -50, -25), ('b', '^', -30, -5)]:
    xs = randrange(n, 23, 32)
    ys = randrange(n, 0, 100)
    zs = randrange(n, zl, zh)
    ax.scatter(xs, ys, zs, c=c, marker=m)

ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')

ax.azim = 200
ax.elev = -45

plt.show()

alt text

希望这能帮到你一点!


有意思,之前我无法让它旋转,但现在它可以工作了。真是不可思议。如果有什么区别的话,我正在使用带有Python 2.6的Ubuntu 10.10。 - pnodbnda
mplot3d非常方便,比MayaVa更轻巧。但请注意,如果您需要复杂的3D场景,则mplot3d建议使用MayaVi。例如,请参见unutbu上面的答案。 - nealmcb
mplot3d 真是太糟糕了!它甚至没有一个函数来移动绘图的旋转中心,这在 3D 绘图中是至关重要的事情。 - Mehdi
@Mehdi - 是的,mplot3d设计得非常简单。它并不是一个“完整”的三维绘图包。它旨在用于快速粗略的伪三维绘图。如果您需要真正的三维绘图,请使用Mayavi或类似的工具。 - Joe Kington
1
如何通过鼠标进行旋转? - Michelle Owen

14

使用Mayavi,您可以创建如下图所示的绘图:

import enthought.mayavi.mlab as mylab
import numpy as np
x, y, z, value = np.random.random((4, 40))
mylab.points3d(x, y, z, value)
mylab.show()

该GUI允许通过点击和拖动实现旋转,通过右键单击和拖动实现缩放。

alt text


放大这个更好,因为随着放大点的大小也增加了(Matplotlib只增加距离,使放大不那么有用),而且Matplotlib绘制的轴框不能跟随缩放。虽然这个要慢得多/重得多,所以最好只在必须放大时使用它。 - pnodbnda
2
这行代码(import enthought.mayavi.mlab as mylab)对我来说不起作用。enthought 显然不是一个模块。 - Richard
@Richard:你安装了 mayavi 吗? 安装应该附带有导入 mayavi 模块的说明。 - unutbu
请注意,mplot3d FAQ中解释了mplot3d实际上是2D+z而不是完全的3D。例如,“两个3D对象(如多边形或补丁)的交集无法正确呈现”。因此,“在[matplotlib支持其核心(OpenGL)的3D之前],如果您需要复杂的3D场景,我们建议使用MayaVi” - nealmcb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接