2012-04-30 28 views
2

這可能有點瘋狂,但我正嘗試使用matplotlib v1.1.0創建一個3D散點圖的可點擊圖像映射。我已經閱讀了如何做2d圖(c.f. this blog),但3D讓我感到困惑。最基本的問題是我不知道如何獲得3D軸的顯示座標。如何將三維數據單元轉換爲matplotlib顯示單位?

在2d的情況下,爲了獲得正確位於散點的點擊點,您需要將每個散點從數據單位轉換爲顯示單位。這似乎是相當直接使用ax.transData。我希望這也適用於3D軸,但它似乎沒有。例如,以下是我試圖執行的操作:

# create the plot 
from mpl_toolkits.mplot3d import Axes3D 
fig = pylab.figure() 
ax = fig.add_subplot(111, projection = '3d') 
x = y = z = [1, 2, 3] 
sc = ax.scatter(x,y,z) 
# now try to get the display coordinates of the first point 
sc.axes.transData.transform((1,1,1)) 

但是,最後一行給我一個「無效的頂點數組」錯誤。它只有在你傳遞了一個兩點的元組(例如(1,1))的元組時才起作用,但這對於3D圖沒有意義。必須有一個方法將3D投影轉換爲2D顯示座標,但是在互聯網遭遇幾個小時之後,我找不到它。有誰知道如何正確地做到這一點?

回答

3

您可以使用proj3d.proj_transform()將3D座標投影到2D。調用ax.get_proj()來獲得變換矩陣:

import pylab 
from mpl_toolkits.mplot3d import Axes3D 
from mpl_toolkits.mplot3d import proj3d 
fig = pylab.figure() 
ax = fig.add_subplot(111, projection = '3d') 
x = y = z = [1, 2, 3] 
sc = ax.scatter(x,y,z) 

#####################  
x2, y2, _ = proj3d.proj_transform(1, 1, 1, ax.get_proj()) 
print x2, y2 # project 3d data space to 2d data space 
print ax.transData.transform((x2, y2)) # convert 2d space to screen space 
##################### 
def on_motion(e): 
    # move your mouse to (1,1,1), and e.xdata, e.ydata will be the same as x2, y2 
    print e.x, e.y, e.xdata, e.ydata 
fig.canvas.mpl_connect('motion_notify_event', on_motion) 
pylab.show()