2011-03-03 10 views
9

मेरे पास एक अनुकरण है जो सिमुलेशन के प्रत्येक पुनरावृत्ति के लिए सतह डेटा की गणना करता है। मैं यह देखने के लिए कि यह कैसे विकसित होता है और एल्गोरिदम की जांच करने के लिए एक ही खिड़की (प्रत्येक पुनरावृत्ति में साजिश को अद्यतन करना) के लिए एक सतह साजिश के रूप में उस डेटा को लगातार साजिश करना चाहता हूं।पायथन-matplotlib का उपयोग कर निरंतर 3 डी साजिश (यानी आंकड़ा अद्यतन)?

मेरा विचार एक वर्ग बनाना था जो खिड़की/साजिश को आरंभ करेगा और फिर सिमुलेशन लूप के अंदर से उस खिड़की को फिर से खींचा जाएगा। यहाँ वर्ग मैं के साथ आया है:

import numpy as np 
import matplotlib.pyplot as plt 
from mpl_toolkits.mplot3d import Axes3D 
from matplotlib import cm 
from matplotlib.ticker import LinearLocator, FixedLocator, FormatStrFormatter 
import matplotlib 
matplotlib.interactive(False) 

class plot3dClass(object): 

    def __init__(self, systemSideLength, lowerCutoffLength): 
     self.systemSideLength = systemSideLength 
     self.lowerCutoffLength = lowerCutoffLength 
     self.fig = plt.figure() 
     self.ax = self.fig.add_subplot(111, projection='3d') 
     self.ax.set_zlim3d(-10e-9, 10e9) 

     X = np.arange(0, self.systemSideLength, self.lowerCutoffLength) 
     Y = X 
     self.X, self.Y = np.meshgrid(X, Y) 

     self.ax.w_zaxis.set_major_locator(LinearLocator(10)) 
     self.ax.w_zaxis.set_major_formatter(FormatStrFormatter('%.03f')) 

     heightR = np.zeros(self.X.shape) 
     self.surf = self.ax.plot_surface(self.X, self.Y, heightR, rstride=1, cstride=1, cmap=cm.jet, linewidth=0, antialiased=False) 
     #~ self.fig.colorbar(self.surf, shrink=0.5, aspect=5) 

     plt.show() 


    def drawNow(self, heightR): 

     self.surf = self.ax.plot_surface(self.X, self.Y, heightR, rstride=1, cstride=1, cmap=cm.jet, linewidth=0, antialiased=False) 
     plt.draw()      # redraw the canvas 

     time.sleep(1) 

समस्या मैं इस कोड के साथ है, कि कोड '() plt.show' पर रुक जाता है और केवल जारी है, जब मैं साजिश विंडो को बंद है। मुझे यह भी यकीन नहीं है कि 'self.ax.plot_surface (...)' और 'plt.draw()' की कॉल आकृति को अपडेट करेगी जैसा मैं चाहूंगा।

तो क्या यह कक्षा सही दिशा है?

यदि हां: क्या संशोधन की आवश्यकता है?

यदि नहीं: क्या कोई मुझे सलाह दे सकता है कि मैं क्या हासिल करना चाहता हूं?

मुझे लगता है कि इस समस्या को दूसरों के लिए तुच्छ लग सकता है लेकिन मैं (ईमानदारी से) पूरे दिन खर्च कल Google पर किया था और कोशिश कर रहा है और मैं एक नुकसान में हूँ ...

किसी भी मदद की बहुत सराहना करेंगे, ताकि मैं अपने वास्तविक काम पर वापस आ सकूं।

पहले से टैंक बहुत पहले।

एक संदर्भ के रूप में:

मैं भी निम्नलिखित कोड है जो करता है, जो मैं चाहता मिला, लेकिन यह 2 डी में है, इसलिए यह मेरे सीधे मदद नहीं करता है:

from pylab import * 
import time 

ion() 

tstart = time.time()    # for profiling 
x = arange(0,2*pi,0.01)   # x-array 
line, = plot(x,sin(x)) 

for i in arange(1,200): 
    line.set_ydata(sin(x+i/10.0)) # update the data 
    draw()       # redraw the canvas 

print 'FPS:' , 200/(time.time()-tstart) 

उत्तर

7

आप की जरूरत नहीं है plt.show() पर यदि यह एक एनिमेटेड (इंटरैक्टिव) साजिश है। आप इंटरेक्टिव सेट को भी सच करना चाहते हैं, झूठी नहीं जो आपके 2 डी उदाहरण में ion() पर कॉल करने जैसा ही है। इसके अलावा, यदि आप उन्हें सभी देखना नहीं चाहते हैं तो आपको पिछले फ्रेम से सतह प्लॉट remove() की आवश्यकता है।

अन्यथा आप बहुत करीब थे।

यह मेरे लिए काम करता है:

import numpy as np 
import matplotlib.pyplot as plt 
from mpl_toolkits.mplot3d import Axes3D 
from matplotlib import cm 
from matplotlib.ticker import LinearLocator, FixedLocator, FormatStrFormatter 
import matplotlib, time 

class plot3dClass(object): 

    def __init__(self, systemSideLength, lowerCutoffLength): 
     self.systemSideLength = systemSideLength 
     self.lowerCutoffLength = lowerCutoffLength 
     self.fig = plt.figure() 
     self.ax = self.fig.add_subplot(111, projection='3d') 
     self.ax.set_zlim3d(-10e-9, 10e9) 

     rng = np.arange(0, self.systemSideLength, self.lowerCutoffLength) 
     self.X, self.Y = np.meshgrid(rng,rng) 

     self.ax.w_zaxis.set_major_locator(LinearLocator(10)) 
     self.ax.w_zaxis.set_major_formatter(FormatStrFormatter('%.03f')) 

     heightR = np.zeros(self.X.shape) 
     self.surf = self.ax.plot_surface( 
      self.X, self.Y, heightR, rstride=1, cstride=1, 
      cmap=cm.jet, linewidth=0, antialiased=False) 
     # plt.draw() maybe you want to see this frame? 

    def drawNow(self, heightR): 
     self.surf.remove() 
     self.surf = self.ax.plot_surface( 
      self.X, self.Y, heightR, rstride=1, cstride=1, 
      cmap=cm.jet, linewidth=0, antialiased=False) 
     plt.draw()      # redraw the canvas 
     time.sleep(1) 

matplotlib.interactive(True) 

p = plot3dClass(5,1) 
for i in range(2): 
    p.drawNow(np.random.random(p.X.shape)) 
+0

यह मेरे कंप्यूटर (विन XP, पायथन 2.7.3) पर काम नहीं करता है: मैं देखता हूं कि अंतिम ग्राफ –

+0

है plt.draw() लाइन के बाद इसे self.fig.canvas.flush_events() की आवश्यकता है। (क्रेडिट http://stackoverflow.com/a/4098938/415551) –

1

मैं हालांकि मैं अभी तक यह पता करने की कोशिश की करने के लिए नहीं है, पॉल से जवाब के लिए आभारी हूँ।

इस बीच मुझे एक और समाधान मिला जो मायावी का उपयोग करके ओपनजीएल के साथ काम करता है और प्रस्तुत करता है, जो ठीक है क्योंकि मुझे केवल वास्तविक समय की त्वरित दृश्य प्रतिक्रिया की आवश्यकता है। हालांकि मैं Ubuntu के अंतर्गत निम्नलिखित पैकेज इंस्टॉल करने के लिए किया था: अजगर-enthoughtbase और mayavi2

कोड यह रहा:

import numpy as np 
import time 
from enthought.mayavi import mlab 
from enthought.tvtk.tools import visual 

    class plot3dClass(object): 

     def __init__(self, systemSideLength, lowerCutoffLength): 
      self.systemSideLength = systemSideLength 
      self.lowerCutoffLength = lowerCutoffLength 

      rangeMax = self.systemSideLength 
      X = np.arange(0, self.systemSideLength, self.lowerCutoffLength) 
      Y = X 

      matrixSize = int(round(self.systemSideLength/self.lowerCutoffLength)) 
      heightR = np.zeros((matrixSize, matrixSize)) 

      fig = mlab.figure(size=(500,500)) 
      visual.set_viewer(fig) 
      self.surf = mlab.surf(X, Y, heightR, warp_scale = 1e1) # NOTE: the warp_scale factor is relative to the scale of the x- and y-axes 
      box_extent = (0,rangeMax, 0,rangeMax, -1e-7,1e-7) # NOTE: the extent options refers to the size and position in the 3D space relative to the origin 

      mlab.outline(self.surf, color=(0.7, .7, .7), extent = box_extent) 

     def drawNow(self, heightR): 
      self.surf.mlab_source.scalars = heightR 
      time.sleep(0.033) 

इस वर्ग है काफी नहीं है, जहां मैं यह चाहते हैं होने के लिए और मैं साथ दो तात्कालिक मुद्दे हैं यह:

  1. एक छोटी इच्छा के बाद खिड़की उबंटू द्वारा भूरे रंग की है (मुझे लगता है) उबंटू सोचता है कि एप्लिकेशन प्रतिक्रिया नहीं दे रहा है।शायद एक उबंटू मुद्दा, लेकिन कष्टप्रद।
  2. मैं यह पता लगाने की कोशिश कर रहा हूं कि मैं एनिमेट करते समय माउस के साथ साजिश को घुमाने में सक्षम कैसे हो सकता हूं।

मैं इन उत्तरों को किसी अन्य धागे में प्राप्त करने का प्रयास करूंगा।

संपादित करें: ठीक है। मैंने पॉल द्वारा सुझाए गए कोड की कोशिश की है और यह मेरे लिए भी काम करता है। हालांकि, इसे आज़माकर मुझे पता चला है कि वास्तविक समय में एनिमेशन करने के लिए MatPlotLib शायद सबसे अच्छा विकल्प नहीं है। कम से कम मेरे लिए यह बेहद धीमी है (शायद केवल 3 डी में?)।

तो अंत में मैं ऊपर से मायावी कार्यान्वयन के साथ रहूंगा, जो कि दो बिंदुओं को छोड़कर, महान काम करता है।

संपादित करें: आप matplotlib समाधान के साथ जाना है, मैं ने पाया है कि आप अंकन वर्ग की घोषणा के अंदर लाइन matplotlib.interactive(True) डाल सकते हैं। इस तरह आप MatPlotLib केवल प्लॉटिंग क्लास के भीतर परिभाषित कर सकते हैं।

+1

आप अपने लिए उपयोगी उत्तर नहीं दे रहे हैं। ओपी शीर्षक था: पायथन और ** MatPlotLib ** का उपयोग कर निरंतर 3 डी साजिश (यानी एक आकृति अद्यतन) प्राप्त करने के लिए कैसे? और आप अपने आप को देते हैं और जवाब देते हैं कि matplotlib के बजाय मायावी का उपयोग करता है। दूसरी ओर, आपको matplotlib का उपयोग करके एक वैध उत्तर मिला है और आपने इसे पहली चीज़ की कोशिश नहीं की है ... – joaquin

0

मैं एक ऐसी ही समस्या थी और यह मेरे लिए काम किया:

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

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

for k in xrange(0,X_range): 
    ax.plot(x_input, y_input, z_input) 
    plt.draw() 
    plt.pause(0.02) 
    ax.cla() 

आप के लिए, मैं कल्पना करता समाधान the top answer के लिए इसी तरह कुछ हो plt.pause() साथ time.sleep() की जगह को छोड़कर, जो पहले आंकड़ा बनाना समाप्त होगा सोया हुआ।

संबंधित मुद्दे