2012-01-12 1 views
10

के साथ 3 डी साजिश मैं पाइथन में एक सतह साजिश करने की कोशिश कर रहा हूं। मेरे पास एन मानों द्वारा एन की एक तालिका है। मैंने एन तत्वों में से प्रत्येक को दो वैक्टर एक्स और वाई बनाया है। जब मैं इस साजिश करने का प्रयास करें, मैं कोई त्रुटि मिलती है:पाइथन

ValueError: total size of new array must be unchanged 

मैं उदाहरण जाँच की है और मैं एक्स के लिए एन तत्वों देखते हैं जेड के एन तत्वों के लिए वहाँ है कि देख सकते हैं और वाई

यह नहीं करता है ' मेरे लिए कोई समझ नहीं है। मुझे एन तत्वों की आवश्यकता क्यों है और एन द्वारा एन नहीं?

यहां एक नमूना कोड है:

आयात यादृच्छिक आयात गणित

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) 
+0

आप कोड की पंक्तियों त्रुटि फेंक पोस्ट कर सकते हैं? – NoBugs

उत्तर

20

पहले, कभी इस तरह बातें नहीं करते:

:

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() 

enter image description here

आप plot_surface के लिए दस्तावेज़ पढ़ें, तो यह स्पष्ट रूप से कहा गया है कि एक्स, Y, और Z 2 डी सरणियों होने की उम्मीद है।

ऐसा इसलिए है कि आप बिंदुओं के बीच कनेक्टिविटी को मूल रूप से परिभाषित करके अधिक जटिल सतहों (जैसे गोलाकार) प्लॉट कर सकते हैं। (उदा matplotlib गैलरी से इस उदाहरण देखें: http://matplotlib.sourceforge.net/examples/mplot3d/surface3d_demo2.html)

आप -1 डी एक्स और वाई सरणियों है, और एक 2 डी ग्रिड से एक सरल सतह चाहते हैं, तो का उपयोग numpy.meshgrid या numpy.mgrid उचित एक्स और वाई 2 डी सरणियों उत्पन्न करने के लिए।

संपादित करें: बस समझाने के लिए क्या 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]]]) 

इसलिए, यह एक एकल, 3 डी रिटर्न सरणी 2x5x5 के आकार के साथ, लेकिन इसके बारे में दो 2 डी सरणी के रूप में सोचना आसान है। एक 5x5 ग्रिड पर किसी भी बिंदु के लिए i निर्देशांक का प्रतिनिधित्व करता है, जबकि दूसरा j निर्देशांक का प्रतिनिधित्व करता है।

जिस तरह से अजगर के खोल कार्यों के

, हम बस लिख सकते हैं:

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

अजगर की परवाह नहीं करता कि वास्तव में क्या mgrid रिटर्न, यह सिर्फ दो आइटम में खोल दे की कोशिश करेंगे। चूंकि numpy arrays उनके पहले धुरी के स्लाइस पर पुनरावृत्त होते हैं, इसलिए हम 2, 5x5 सरणी प्राप्त करेंगे यदि हम किसी सरणी को (2x5x5) के आकार से अनपैक करते हैं।इसी तरह, हम चीजें कर सकते हैं जैसे:

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

... और 3, 3 डी 5x5x5 प्रविष्टियों के सरणी प्राप्त करें। इसके अलावा, अगर हम (एक अलग श्रेणी के साथ स्लाइस जैसे xx, yy = np.mgrid[10:15, 3:8] यह। टाइल indicies 10 से 14 (सम्मिलित) और 3 से 7 (सम्मिलित)

थोड़ा अधिक है कि mgrid करता है (यह करने के लिए जटिल कदम तर्क ले सकते हैं नकल linspace, जैसे xx, yy = np.mgrid[0:1:10j, 0:5:5j] 0-1 और 0-5 के बीच बढ़ती हुई संख्या, क्रमशः) के साथ 2 10x5 सरणियों वापस आ जाएगी, लेकिन एक पल के लिए 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 2 डी सरणियों के एक टपल वापस जाने के लिए होता है, लेकिन उस भेद फर्क नहीं पड़ता। मुख्य अंतर यह है कि संस्थाओं को किसी विशेष दिशा में वृद्धि नहीं करनी पड़ती है। यह सिर्फ उन सरणी को टाइल करता है जो इसे दिया जाता है।

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() 

enter image description here

+2

जो आप बिल्कुल सही हैं, लेकिन यह उदाहरण में काम करेगा यदि 'एक्स .append (x) 'दूसरे लूप के अंदर स्थानांतरित किया गया था। 'plot_surface' अभी भी काम करता है यदि आपके पास 1 डी सरणी है जो एनएक्सएन लंबी है। त्रुटि यह कह रही है कि matplotlib 1 डी सरणी को दोबारा नहीं बदल सकता है ताकि यह एन 2 डी सरणी द्वारा एन हो। आप भी बहुत तेज हैं। – Yann

+0

धन्यवाद। यह देखने के लिए सिर्फ एक परीक्षण है कि मैं सतह की साजिश को समझता हूं। मैं, वास्तव में, फूरियर के ट्रांसफॉर्म के समान कुछ करने की योजना बना रहा हूं और मुझे नहीं पता कि पाइथन में एकल लाइन में जटिल ऑपरेशन या सशर्त ऑपरेशन कैसे करें। मैं इसके लिए एक नया सवाल पोस्ट करूंगा। – Yotam

+0

@Yann - आह, ठीक है! मैंने वास्तव में अपना कोड नहीं चलाया क्योंकि यह पोस्ट किया गया था ... मान लीजिए मुझे चाहिए! ऐसा लगता है जैसे आपने वास्तव में अपने प्रश्न का उत्तर दिया था। ... और जो कुछ भी लायक है, उसके लिए आपने मुझे पंच को और भी अक्सर मार दिया। :) –