在Swift中调用Gnuplot

时间:2015-03-08 11:28:50

标签: swift gnuplot nstask nspipe

我正试图从swift中调用gunplot来在.png中生成一些情节。但是,下面的程序不起作用---生成的1.png文件为空。如果我离开“set term aqua”,它会调用aqua窗口中的情节。但是,当我尝试将输出设置为file(png或pdf)时,结果始终为空文件。

gnuplot命令没问题---我可以正确地手动运行它们。

import Foundation

let task = NSTask()
task.launchPath = "/opt/local/bin/gnuplot"
task.currentDirectoryPath = "~"

let pipeIn = NSPipe()
task.standardInput = pipeIn
task.launch()

let plotCommand: NSString =
  "set term png\n" +
  "set output \"1.png\"\n"
  "plot sin(x)\n" +
  "q\n"

pipeIn.fileHandleForWriting.writeData(plotCommand.dataUsingEncoding(NSUTF8StringEncoding)!)

我是swift和pipe的新手,所以请告诉我代码是否有问题或不推荐。

2 个答案:

答案 0 :(得分:4)

当我们连接字符串时,通常很容易错过一个简单的符号 在这种情况下,您可以修复将\n+添加到set output的行:

 "set output \"1.png\"\n" +

我们的想法是创建一个字符串,好像我们在gnuplot shell中编写一样,所以每个\n我们都在模拟一个新行,每个+我们连接两个或者更多字符串...
这甚至是 gnuplot脚本 ......

的基础

gnuplot通常可以编写外部脚本并使用

加载它
  load "myscript.gnuplot"

或使用

运行它
 gnuplot -persist myscript.gnuplot

通过这种方式,您将始终有可能在眨眼间重做您的绘图或分析,并且您的结果将始终可重现。

答案 1 :(得分:0)

Swift 5.4

let commandString: String =
    """
    set terminal png
    set output 'FIND_ME_01.png'
    plot sin(x)
    quit\n
    """

func plot() {
    let argv: [String] = ["--persist"] // do not close interactive plot
    let task = Process()
    task.arguments = argv
    //                "/opt/homebrew/bin/gnuplot" // Big Sur, Apple Silicon
    task.launchPath = "/usr/local/bin/gnuplot"    // Big Sur, Intel
    // where to find the output
    let homeDir = FileManager.default.homeDirectoryForCurrentUser
    task.currentDirectoryURL = homeDir.appendingPathComponent("Desktop")


    let pipeIn = Pipe()
    task.standardInput = pipeIn
    let pipeOut = Pipe()
    task.standardOutput = pipeOut
    let pipeErr = Pipe()
    task.standardError = pipeErr
    
    do {
        try task.run()
        let commandData = commandString.data(using: .utf8)!
        pipeIn.fileHandleForWriting.write(commandData)
        
        let dataOut = pipeOut.fileHandleForReading.readDataToEndOfFile()
        if let output = String(data: dataOut, encoding: .utf8) {
            print("STANDARD OUTPUT\n" + output)
        }

        let dataErr = pipeErr.fileHandleForReading.readDataToEndOfFile()
        if let outputErr = String(data: dataErr, encoding: .utf8) {
            print("STANDARD ERROR \n" + outputErr)
        }
    } catch {
        print("FAILED: \(error)")
    }
    task.waitUntilExit()
    print("STATUS: \(task.terminationStatus)")
}

当前的 Swift """ 语法允许多行字符串文字。这避免了对字符串连接的需要。

注意:commandString 需要以换行符结尾。如果末尾没有使用 \n,则需要一个结束的额外空行。

quit\n
"""
quit

"""