[英]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.meshgrid
或numpy.mgrid
生成適當的X和Y 2D數組。
編輯:只是為了解釋mgrid
和meshgrid
作用,讓我們看一下它們的輸出:
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.