Вызов Гнуплота в Свифте

Я пытаюсь вызвать ганфлот из Свифта, чтобы произвести несколько сюжетов в .png, Тем не менее, программа ниже не работает --- в результате 1.png файл пуст Если я оставляю "установить термин аква", он вызывает окно аква с сюжетом в нем. Однако, когда я пытаюсь установить вывод в файл (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, так и в конвейере, поэтому, пожалуйста, скажите мне, если что-то не так или не рекомендуется с кодом.

2 ответа

Решение

Часто легко пропустить простой знак, когда мы объединяем строки.
В этом случае вы можете исправить добавление \n а также + на линию с set output:

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

Идея состоит в том, чтобы создать строку, как если бы мы писали в gnuplot оболочка, поэтому с каждой\n мы моделируем новую линию и с каждым + мы объединяем две или более строки...
это даже идея, лежащая в основе сценариев gnuplot...

Часто с gnuplot удобно писать внешний скрипт и загружать его

  load "myscript.gnuplot"

или запустить его с

 gnuplot -persist myscript.gnuplot

Таким образом, у вас всегда будет возможность переделать ваш график или анализ в мгновение ока, и ваш результат будет всегда воспроизводимым.

Swift 5.4

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

func plotDirect() {
    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)")
}

Текущий Свифт """синтаксис позволяет использовать многострочную строку. Это позволяет избежать конкатенации строк.

Обратите внимание commandStringдолжен заканчиваться новой строкой. Завершающая дополнительная пустая строка необходима, если \n не используется в конце.

      quit\n
"""
      quit

"""
Другие вопросы по тегам