簡體   English   中英

Pyplot 3d scatter:指向前方后方重疊點的點

[英]Pyplot 3d scatter: points at the back overlap points at the front

我正在使用matplotlib准備三維圖,我對多個數據集有一個非常奇怪的行為。 我有兩個數據集,基本上描述了3d中的兩個shell:一個內殼和一個外殼。 要在3d中繪制它我做:

fig = plt.figure()

ax = fig.add_subplot(111, projection='3d')    

ax.scatter(outer_z[:n], outer_x[:n], outer_y[:n], c='black', marker='.', lw=0)
ax.scatter(inner_z[:n],  inner_x[:n], inner_y[:n], c='red', marker='.', lw=0)

ax.set_xlabel("Z")
ax.set_ylabel("X")
ax.set_zlabel("Y")

ax.set_xlim([-5,5])
ax.set_ylim([5,-5])
ax.set_zlim([-5,5])

(軸的順序僅用於透視目的)。 但是,當我保存圖形時,我沒有得到兩個炮彈:

在此輸入圖像描述 在此輸入圖像描述

我得到一層超過另一層,后面明顯的點出現在前面。 你可以在圖片上看到外殼后面應該在內殼后面的一些點被繪制在內殼的前面。 這真的很煩人,因為它不追求“3D中的情節”的目的。 有沒有人知道為什么會發生這種情況以及如何解決這個問題? 非常感謝!

我知道這不是解決問題的方法,但也許可以解釋為什么它的行為方式如此。

這與Matplotlib實際上沒有3D引擎的事實有關。 Mplot3D獲取你的點並將它們投影到2D繪圖上(對於每個對象)的樣子,然后Matplotlib一次繪制一個對象; Matplotlib是一個2D繪圖框架,Mplot3D可以讓一些3D功能正常工作而無需為Matplotlib編寫成熟的3D引擎。

這意味着您繪制不同圖形的順序(在這種情況下是紅色和黑色點)很重要,如果您在紅點后繪制黑點,它們將顯示在紅點前面,而不管它們是什么位置。

讓我用另一個例子說明這一點。

theta   = np.linspace(0, 2*np.pi, 100, endpoint=True)

helix_x = np.cos(3*theta)
helix_y = np.sin(3*theta)
helix_z = theta

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')    

line_x  = np.zeros(100)
line_y  = np.zeros(100)

ax.plot(line_x, line_y, theta, lw='3', color='r')
ax.plot(helix_x, helix_y, helix_z, lw='2', color='k')

ax.set_xlabel("Z")
ax.set_ylabel("X")
ax.set_zlabel("Y")

ax.set_xlim([-1.5,1.5])
ax.set_ylim([-1.5,1.5])
ax.set_zlim([0,2*np.pi])

這給出了: 在此輸入圖像描述

但是從頂視圖可以看出該線在螺旋線內:

在此輸入圖像描述

但是,如果您交換繪制這些線的順序:

ax.plot(line_x, line_y, theta, lw='3', color='r')
ax.plot(helix_x, helix_y, helix_z, lw='2', color='k')

然后,您會看到螺旋后繪制的線:

在此輸入圖像描述

最終,這意味着您必須手動確定哪些點將位於其他點之前。 然后,您可以使用zorder參數來確定哪些對象將位於其他對象的前面。 但是你必須為每個視角(角度,高度)做到這一點。 在這種情況下,您可能需要將內部線分解為“infront_of_helix”和“behind_helix”部分,然后分別在螺旋線的前面和后面繪制它們。

我希望有人能夠對這個問題進行更詳細的闡述,因為我自己對這個話題感興趣。 我知道mplot3d有一些基本方法可以確保前點顯示首先,我相信,當它使用着色算法但是我不完全確定。

非常感謝你的解釋:)我認為它確實可能是這樣的。 但我忘了在我的問題中說,無論ax.scatter命令的順序是什么都發生了,這很奇怪。 在讀到你的答案之前我發現了ax.plot命令不會發生這種情況。 因此,我換了:

ax.scatter(outer_z[:n], outer_x[:n], outer_y[:n], c='black', marker='.', lw=0)
ax.scatter(inner_z[:n],  inner_x[:n], inner_y[:n], c='red', marker='.', lw=0)

通過

ax.plot(outer_z[:n],  outer_x[:n], outer_y[:n], '.', markersize=1, color='black') 
ax.plot(inner_z[:n], inner_x[:n], inner_y[:n], '.', markersize=1, color='red') 

我得到了以下圖片:

在此輸入圖像描述

這適合我。 但是,我知道,如果我改變觀點,我會將紅色外殼出現在黑色外觀之上。 我后來發現的一個問題是.plot函數沒有vmin和vmax參數(作為.scatter),這使得將顏色定義為以vmin和vmax開始的漸變更難...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM