Created
September 3, 2020 13:30
-
-
Save damuellen/bbf4344845ccbf6a54d13527e9349913 to your computer and use it in GitHub Desktop.
PerformanceDataPlot
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
public class PerformanceDataPlot { | |
let xy1s: [[(x: TimeInterval, y: Double)]] | |
let xy2s: [[(x: TimeInterval, y: Double)]] | |
public var y1Titles: [String] | |
public var y2Titles: [String] | |
public var y1Label: String = "" | |
public var y2Label: String = "" | |
public init(xy1s: [[(TimeInterval, Double)]], xy2s: [[(TimeInterval, Double)]] = []) | |
{ | |
self.xy1s = xy1s | |
self.xy2s = xy2s | |
self.y1Titles = Array(repeating: "", count: xy1s.count) | |
self.y2Titles = Array(repeating: "", count: xy2s.count) | |
} | |
func plot(code: String) throws | |
{ | |
let inputPipe = Pipe() | |
let inputFile = inputPipe.fileHandleForWriting | |
let gnuplot = Process() | |
gnuplot.executableURL = .init(fileURLWithPath: "/usr/bin/gnuplot") | |
gnuplot.arguments = ["-p", "-e", code] | |
gnuplot.standardInput = inputPipe | |
try gnuplot.run() | |
inputFile.write(plotData.data(using: .utf8)!) | |
} | |
public func plot(toFile: String? = nil) { | |
var code: String = "" | |
if let file = toFile { | |
code = """ | |
set terminal pdf size 18,10 enhanced color font 'Helvetica,16' lw 1; | |
set output \"\(file).pdf \"; | |
set title '\(file)'; | |
unset key; | |
""" | |
} | |
code += setCommands + plotCommands | |
try! plot(code: code) | |
} | |
var plotData: String { | |
let xy1 = xy1s.map { $0.map { $0.x.description + ", " + $0.y.description } | |
.joined(separator: "\n") }.joined(separator: "\ne\n") + "\ne\n" | |
let xy2 = xy2s.map { $0.map { $0.x.description + ", " + $0.y.description } | |
.joined(separator: "\n") }.joined(separator: "\ne\n") + "\ne\n" | |
return xy1 + xy2 | |
} | |
var setCommands: String { | |
let setCommands = [ | |
"grid", | |
"ylabel '\(y1Label)'", | |
"y2label '\(y2Label)'", | |
"xlabel 'Time'", | |
"style textbox opaque margins 1.0, 1.0 fc bgnd border lt -1 linewidth 1.0", | |
"xdata time", | |
"timefmt '%s'", | |
#"format x '%d %b'"#, | |
#"xrange ["\(xy1s.first!.first!.0)":"\(xy1s.first!.last!.0)"]"#, | |
"xtics 60. * 60. * 24. ", | |
"xtics rotate", | |
"autoscale", | |
"autoscale y2", | |
"style data lines", | |
"ytics nomirror 10", | |
"y2tics;" | |
] | |
return setCommands.map { "set " + $0 }.joined(separator: ";") | |
} | |
var plotCommands: String { | |
let plotCommands = ["plot '-' using 1:2 title '\(y1Titles.first!)' axes x1y1 with lines linewidth 2"] | |
+ xy1s.indices.dropFirst().map { i in "'' using 1:2 title '\(y1Titles[i])' axes x1y1 with lines linewidth 2" } | |
+ xy2s.indices.map { i in "'' using 1:2 title '\(y2Titles[i])' axes x1y2 with lines linewidth 2" } | |
return plotCommands.joined(separator: ",") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment