簡體   English   中英

用python 3d繪圖

[英]3d plotting with python

我正在嘗試在python中繪制表面。 我有N×N值的表格。 我創建了兩個向量X和Y,每個元素N個。 當我嘗試繪制此圖時,出現錯誤:

ValueError: total size of new array must be unchanged

我檢查了示例,然后看到對於Z的N個元素,對於X和Y有N個元素。

這對我來說毫無意義。 我為什么需要N個元素而不是N個N個?

這是一個示例代碼:

導入隨機導入數學

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

bignum = 100

mat = []
X = []
Y = []

for x in range(0,bignum):
    mat.append([])
    X.append(x);
    for y in range (0,bignum):
        mat[x].append(random.random())
        Y.append(y)

fig = plt.figure(figsize=plt.figaspect(2.))
ax = fig.add_subplot(1,1,1, projection='3d')
surf = ax.plot_surface(X,Y,mat)

首先,永遠不要做這樣的事情:

mat = []
X = []
Y = []

for x in range(0,bignum):
    mat.append([])
    X.append(x);
    for y in range (0,bignum):
        mat[x].append(random.random())
        Y.append(y)

這等效於:

mat = np.random.random((bignum, bignum))
X, Y = np.mgrid[:bignum, :bignum]

...但是速度快了幾個數量級,並且使用的內存只有使用列表然后轉換為數組的一部分。

但是,您的示例效果很好。

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

bignum = 100
mat = np.random.random((bignum, bignum))
X, Y = np.mgrid[:bignum, :bignum]

fig = plt.figure()
ax = fig.add_subplot(1,1,1, projection='3d')
surf = ax.plot_surface(X,Y,mat)
plt.show()

在此處輸入圖片說明

如果您閱讀了plot_surface的文檔,則可以清楚地看到X,Y和Z應該是2D數組。

這樣,您就可以通過固有地定義點之間的連通性來繪制更復雜的曲面(例如球體)。 (例如,從matplotlib畫廊中看到以下示例: http : //matplotlib.sourceforge.net/examples/mplot3d/surface3d_demo2.html

如果您具有一維X和Y數組,並且希望從2D網格中獲得一個簡單的曲面,請使用numpy.meshgridnumpy.mgrid生成適當的X和Y 2D數組。

編輯:只是為了解釋mgridmeshgrid作用,讓我們看一下它們的輸出:

print np.mgrid[:5, :5]

產量:

array([[[0, 0, 0, 0, 0],
        [1, 1, 1, 1, 1],
        [2, 2, 2, 2, 2],
        [3, 3, 3, 3, 3],
        [4, 4, 4, 4, 4]],

       [[0, 1, 2, 3, 4],
        [0, 1, 2, 3, 4],
        [0, 1, 2, 3, 4],
        [0, 1, 2, 3, 4],
        [0, 1, 2, 3, 4]]])

因此,它返回形狀為2x5x5的單個3D數組,但將其更容易地視為兩個2D數組。 一個代表5x5網格上任何點的i坐標,而另一個代表j坐標。

由於python解壓縮的工作方式,我們可以這樣寫:

xx, yy = np.mgrid[:5, :5]

Python並不在乎mgrid返回什么,它只會嘗試將其分解為兩個項目。 因為numpy數組會在其第一個軸的切片上進行迭代,所以如果解壓縮形狀為(2x5x5)的數組,我們將得到2個,5x5數組。 同樣,我們可以執行以下操作:

xx, yy, zz = np.mgrid[:5, :5, :5]

...並獲得3個3D 5x5x5索引陣列。 另外,如果我們用不同的范圍切片(例如xx, yy = np.mgrid[10:15, 3:8] ,它將平鋪索引從10到14(含)和3到7(含)。

mgrid還有很多其他功能(它可能需要復雜的step參數來模擬linspace ,例如xx, yy = np.mgrid[0:1:10j, 0:5:5j]將返回2個10x5數組,其數字在0- 1和0-5),但讓我們跳到meshgrid一秒鍾。

meshgrid接受兩個數組,並以與mgrid類似的方式將它們平鋪。 舉個例子:

x = np.arange(5)
y = np.arange(5)
xx, yy = np.meshgrid(x, y)
print xx, yy

產量:

(array([[0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4]]), 

array([[0, 0, 0, 0, 0],
       [1, 1, 1, 1, 1],
       [2, 2, 2, 2, 2],
       [3, 3, 3, 3, 3],
       [4, 4, 4, 4, 4]]))

meshgrid實際上碰巧返回了2個,5x5 2D數組的元組,但是區別並不重要。 關鍵區別在於指標不必在特定方向上增加。 它只是平鋪給定的數組。 舉個例子:

x = [0.1, 2.4, -5, 19]
y = [-4.3, 2, -1, 18.4]
xx, yy = np.meshgrid(x, y)

產量:

(array([[  0.1,   2.4,  -5. ,  19. ],
       [  0.1,   2.4,  -5. ,  19. ],
       [  0.1,   2.4,  -5. ,  19. ],
       [  0.1,   2.4,  -5. ,  19. ]]),
 array([[ -4.3,  -4.3,  -4.3,  -4.3],
       [  2. ,   2. ,   2. ,   2. ],
       [ -1. ,  -1. ,  -1. ,  -1. ],
       [ 18.4,  18.4,  18.4,  18.4]]))

您會注意到,它只是平鋪了我們提供的值。

基本上,當您需要使用與輸入網格相同形狀的索引時,可以使用它們。 當您要根據網格值評估函數時,它最有用。

例如

import numpy as np
import matplotlib.pyplot as plt

x, y = np.mgrid[-10:10, -10:10]
dist = np.hypot(x, y) # Linear distance from point 0, 0
z = np.cos(2 * dist / np.pi)

plt.title(r'$\cos(\frac{2*\sqrt{x^2 + y^2}}{\pi})$', size=20)
plt.imshow(z, origin='lower', interpolation='bicubic',
          extent=(x.min(), x.max(), y.min(), y.max()))
plt.colorbar()
plt.show()

在此處輸入圖片說明

暫無
暫無

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

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