Calling gnuplot from python

前端 未结 8 635
清酒与你
清酒与你 2020-12-04 18:34

I\'ve a python script that after some computing will generate two data files formatted as gnuplot input.

How do I \'call\' gnuplot from python ?

I want to se

8条回答
  •  情话喂你
    2020-12-04 18:56

    Here's a class that provides an interface to wgnuplot.exe:

    from ctypes import *
    import time
    import sys
    import os
    
    #
    # some win32 constants
    #
    WM_CHAR     = 0X0102
    WM_CLOSE    = 16
    SW_HIDE     = 0
    STARTF_USESHOWWINDOW = 1
    
    WORD    = c_ushort
    DWORD   = c_ulong
    LPBYTE  = POINTER(c_ubyte)
    LPTSTR  = POINTER(c_char) 
    HANDLE  = c_void_p
    
    class STARTUPINFO(Structure):
        _fields_ = [("cb",DWORD),
            ("lpReserved",LPTSTR), 
            ("lpDesktop", LPTSTR),
            ("lpTitle", LPTSTR),
            ("dwX", DWORD),
            ("dwY", DWORD),
            ("dwXSize", DWORD),
            ("dwYSize", DWORD),
            ("dwXCountChars", DWORD),
            ("dwYCountChars", DWORD),
            ("dwFillAttribute", DWORD),
            ("dwFlags", DWORD),
            ("wShowWindow", WORD),
            ("cbReserved2", WORD),
            ("lpReserved2", LPBYTE),
            ("hStdInput", HANDLE),
            ("hStdOutput", HANDLE),
            ("hStdError", HANDLE),]
    
    class PROCESS_INFORMATION(Structure):
        _fields_ = [("hProcess", HANDLE),
            ("hThread", HANDLE),
            ("dwProcessId", DWORD),
            ("dwThreadId", DWORD),]
    
    #
    # Gnuplot
    #
    class Gnuplot:
        #
        # __init__
        #
        def __init__(self, path_to_exe):
            # open gnuplot
            self.launch(path_to_exe)
            # wait till it's ready
            if(windll.user32.WaitForInputIdle(self.hProcess, 1000)):
                print "Error: Gnuplot timeout!"
                sys.exit(1)
            # get window handles
            self.hwndParent = windll.user32.FindWindowA(None, 'gnuplot')
            self.hwndText = windll.user32.FindWindowExA(self.hwndParent, None, 'wgnuplot_text', None)
    
    
    
        #
        # __del__
        #
        def __del__(self):
            windll.kernel32.CloseHandle(self.hProcess);
            windll.kernel32.CloseHandle(self.hThread);
            windll.user32.PostMessageA(self.hwndParent, WM_CLOSE, 0, 0)
    
    
        #
        # launch
        #
        def launch(self, path_to_exe):
            startupinfo = STARTUPINFO()
            process_information = PROCESS_INFORMATION()
    
            startupinfo.dwFlags = STARTF_USESHOWWINDOW
            startupinfo.wShowWindow = SW_HIDE
    
            if windll.kernel32.CreateProcessA(path_to_exe, None, None, None, False, 0, None, None, byref(startupinfo), byref(process_information)):
                self.hProcess = process_information.hProcess
                self.hThread = process_information.hThread
            else:
                print "Error: Create Process - Error code: ", windll.kernel32.GetLastError()
                sys.exit(1)
    
    
    
        #
        # execute
        #
        def execute(self, script, file_path):
            # make sure file doesn't exist
            try: os.unlink(file_path)
            except: pass
    
            # send script to gnuplot window
            for c in script: windll.user32.PostMessageA(self.hwndText, WM_CHAR, ord(c), 1L)
    
            # wait till gnuplot generates the chart
            while( not (os.path.exists(file_path) and (os.path.getsize(file_path) > 0))): time.sleep(0.01)
    

提交回复
热议问题