2011-02-04 6 views
3

Qt4 GUI (다른 버튼 포함)에 3D 플롯을 포함하려고합니다. matplotlib의 mplot3d를 사용하면 가능합니까?matplotlib의 Qt4 + mplot3d

2 차원 줄거리는 "matplotlib.backends.backend_qt4agg"를 사용하여 가능하다는 것을 알고 있습니다.

예인 경우 예를 들어주십시오.

아니요, 가장 좋아하는 옵션은 무엇입니까? VTK?

감사합니다.

+0

그것은 2D 플롯을 내장 가능한과 동일해야합니다. Matplotlib의 3D 플롯은 어떠한 방식 으로든 가속화되므로 2D 플롯과는 다른 어떤 것도 할 필요가 없습니다. matplotlib 대 VTK까지는 식료품 가방을화물 열차와 비교하고 있습니다 ... 둘 다 식료품 점을 가지고 다니지 만 공통점이 있습니다! Matplotlib의 3D 플로팅은 Matlab의 3D 플로팅과 비슷합니다 ... 그것은 매우 기본이지만 훌륭한 출판 품질 벡터 출력을 만듭니다. VTK는 대단히 강력합니다 (특히 체적 및 대화식 시각화의 경우). 그러나 더 복잡합니다. –

+0

vtk를 고려하십시오 - Joe가 말했듯이 애플리케이션에 대화 형 시각화가 필요한 경우 더 적합 할 수 있습니다. – Thomas

답변

3

가장 깨끗한 것은 아니지만 보시는 동안. 나는 그것이 tkinter 백엔드만큼 빠르지 않다는 것을 알아 차렸습니다. 그런 다음 다시 작동합니다.

재밌게은 :

import os 
import sys 

from PyQt4 import QtCore, QtGui 

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas 
from matplotlib.backends.backend_qt4 import NavigationToolbar2QT as NavigationToolbar 

from matplotlib.figure import Figure 
from mpl_toolkits.mplot3d import Axes3D 

class QtMplCanvas(FigureCanvas): 
    def __init__(self, parent=None, width = 6.5, height = 5.5, dpi = 100, sharex = None, sharey = None, fig = None): 
     if fig == None: 
      self.fig = Figure(figsize = (width, height), dpi=dpi, facecolor = '#FFFFFF') 
      self.ax = self.fig.add_subplot(111, projection='3d') 
      self.fig.subplots_adjust(left=0.1, bottom=0.1, right=0.9, top=0.9) 
      self.ax.hold(True) 
     else: 
      self.fig = fig 

     FigureCanvas.__init__(self, self.fig) 
     FigureCanvas.setSizePolicy(self, 
      QtGui.QSizePolicy.Expanding, 
      QtGui.QSizePolicy.Expanding) 
     FigureCanvas.updateGeometry(self) 

    def sizeHint(self): 
     w, h = self.get_width_height() 
     return QtCore.QSize(w, h) 

    def minimumSizeHint(self): 
     return QtCore.QSize(10, 10) 

    def sizeHint(self): 
     w, h = self.get_width_height() 
     return QtCore.QSize(w, h) 

    def minimumSizeHint(self): 
     return QtCore.QSize(10, 10) 


class MyNavigationToolbar(NavigationToolbar) : 
    def __init__(self, parent, canvas, direction = 'h') : 

     self.canvas = canvas 
     QWidget.__init__(self, parent) 

     if direction=='h' : 
      self.layout = QHBoxLayout(self) 
     else : 
      self.layout = QVBoxLayout(self) 

     self.layout.setMargin(2) 
     self.layout.setSpacing(0) 

     NavigationToolbar2.__init__(self, canvas) 


    def set_message(self, s): 
     pass 


class MPL_WIDGET_3D(QtGui.QWidget): 
    def __init__(self, parent = None, enableAutoScale = False, enableCSV = False, enableEdit = False, fig = None): 
     QtGui.QWidget.__init__(self, parent) 
     self.canvas = QtMplCanvas(fig) 
     self.canvas.ax.mouse_init() 
     self.toolbar = NavigationToolbar(self.canvas, self.canvas) 
     self.vbox = QtGui.QVBoxLayout() 
     self.vbox.addWidget(self.canvas) 
     self.vbox.addWidget(self.toolbar) 
     self.setLayout(self.vbox) 


     ###########SAVING FIGURE TO CLIPBOARD########## 
     self.cb = None #will be used for the clipboard 
     self.tempPath = getHomeDir() 
     self.tempPath = os.path.join(self.tempPath,'tempMPL.png') 

     self.mpl2ClipAction = QtGui.QAction("Save to Clipboard", self) 
     self.mpl2ClipAction.setShortcut("Ctrl+C") 
     self.addAction(self.mpl2ClipAction) 
     QtCore.QObject.connect(self.mpl2ClipAction,QtCore.SIGNAL("triggered()"), self.mpl2Clip) 

    def mpl2Clip(self): 
     try: 
      self.canvas.fig.savefig(self.tempPath) 
      tempImg = QtGui.QImage(self.tempPath) 
      self.cb = QtGui.QApplication.clipboard() 
      self.cb.setImage(tempImg) 
     except: 
      print 'Error copying figure to clipboard' 
      errorMsg = "Sorry: %s\n\n:%s\n"%(sys.exc_type, sys.exc_value) 
      print errorMsg 

####USED TO GET THE USERS HOME DIRECTORY FOR USE OF A TEMP FILE 

def valid(path): 
    if path and os.path.isdir(path): 
     return True 
    return False 

def env(name): 
    return os.environ.get(name, '') 

def getHomeDir(): 
    if sys.platform != 'win32': 
     return os.path.expanduser('~') 

    homeDir = env('USERPROFILE') 
    if not valid(homeDir): 
     homeDir = env('HOME') 
     if not valid(homeDir) : 
      homeDir = '%s%s' % (env('HOMEDRIVE'),env('HOMEPATH')) 
      if not valid(homeDir) : 
       homeDir = env('SYSTEMDRIVE') 
       if homeDir and (not homeDir.endswith('\\')) : 
        homeDir += '\\' 
       if not valid(homeDir) : 
        homeDir = 'C:\\' 
    return homeDir 


if __name__ == "__main__": 
    app = QtGui.QApplication(sys.argv) 
    mplQt = MPL_WIDGET_3D() 
    mplQt.show() 
    sys.exit(app.exec_()) 
+0

그래서 PyQt에서 3d/surface 플롯을 만드는 더 간단한 방법은 없습니까? 그것을하기 위해 필요한 코드의 엄청난 양처럼 보입니다. –

+0

@Vitto 업데이트 된 접근 방법을 찾으셨습니까? – user3731622

+0

아니, 방금이 접근법을 사용했습니다. bhclowers가 게시 한 코드만큼이나 많은 코드가 필요하지 않습니다. 더 복잡한 예제를 보여준 것 같습니다. –