5

我正在尝试从 swift 调用 gunplot 以在.png. 但是,下面的程序不起作用 --- 结果1.png文件是空的。但是,如果我离开“set term aqua”,它会调用带有绘图的 aqua 窗口。但是,当我尝试将输出设置为文件(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 和管道都是新手,所以请告诉我代码是否有问题或不推荐。

4

2 回答 2

4

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

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

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

通常使用gnuplot编写外部脚本并加载它很舒服

  load "myscript.gnuplot"

或运行它

 gnuplot -persist myscript.gnuplot

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

于 2015-03-17T17:50:38.910 回答
0

斯威夫特 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

"""
于 2021-06-25T04:45:03.197 回答