我正试图从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的新手,所以请告诉我代码是否有问题或不推荐。
答案 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
"""