1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
package scalam.plotting
import scala.sys.process._
import scalam.DataSet
import scalam.m.ast._
import scalax.file.Path
class Plot(
val dataSets: Seq[DataSet],
title: String,
xLabel: String,
yLabel: String,
grid: Boolean = true,
legend: Boolean = true,
fontSize: Int = 10,
colorScheme: ColorScheme = JET,
name: String = "plot" + Plot.next) {
val directory = Path(name)
val localPlotFile = Path("results.m")
private case class RichDataSet(underlying: DataSet, localPath: Path, id: Identifier)
private val richDataSets = dataSets.zipWithIndex.map {
case (d, i) => RichDataSet(d, Path("data") / i.toString, Identifier("data" + (i + 1)))
}
private val colors = colorScheme(dataSets)
lazy val statements: List[Statement] = {
def loadData(dataSet: RichDataSet) = Assign(dataSet.id, Function(Identifier("load"), StringLiteral(dataSet.localPath.path)))
def initialColor(ds: Seq[DataSet]) = colorScheme match {
case predefined: MColorScheme => predefined.initial(ds) :: Nil
case _ => Nil
}
val figureId = Identifier("fh")
val on = StringLiteral("on")
val off = StringLiteral("off")
def newFigure(figureId: Identifier) = Assign(figureId, Function(Identifier("figure")))
def hold(b: Boolean) = Evaluate(Function(Identifier("hold"), if (b) on else off))
def grid(show: Boolean) = Evaluate(Function(Identifier("grid"), if (show) on else off))
def title(s: String) = Evaluate(Function(Identifier("title"), StringLiteral(s)))
def xLabel(s: String) = Evaluate(Function(Identifier("xlabel"), StringLiteral(s)))
def yLabel(s: String) = Evaluate(Function(Identifier("ylabel"), StringLiteral(s)))
def fontSize(size: Int) = Evaluate(Function(Identifier("set"), Variable(Identifier("gca")), StringLiteral("fontsize"), IntLiteral(size)))
def plot(dataSet: RichDataSet) =
Evaluate(
Function(
Identifier("plot"),
IndexMatrix(dataSet.id, SliceLiteral, IntLiteral(1)),
IndexMatrix(dataSet.id, SliceLiteral, IntLiteral(2)),
StringLiteral("color"),
colors(dataSet.underlying).expression))
def legend(dataSets: Seq[DataSet]) =
Evaluate(Function(Identifier("legend"), (for (d <- dataSets) yield StringLiteral(d.name)): _*)) :: Nil
def wait(figureId: Identifier) = List(Evaluate(Function(Identifier("waitfor"), Variable(figureId))))
val commands = new scala.collection.mutable.ListBuffer[Statement]
commands ++= (for (d <- richDataSets) yield loadData(d))
commands ++= initialColor(richDataSets.map(_.underlying))
commands += newFigure(figureId)
commands += hold(true)
commands += grid(this.grid)
commands += title(this.title)
commands += xLabel(this.xLabel)
commands += yLabel(this.yLabel)
commands += fontSize(this.fontSize)
commands ++= (for (d <- richDataSets) yield plot(d))
if (this.legend) commands ++= legend(dataSets)
commands ++= wait(figureId)
commands.toList
}
private def preamble = {
val df = new java.text.SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss")
val now = (new java.util.Date(System.currentTimeMillis()))
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n" +
"% Generated by scalam, v1.0 %\n" +
"% " + df.format(now) + " %\n" +
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
}
def save() = {
for (d <- richDataSets) d.underlying.save(directory / d.localPath)
val plotFile = (directory / localPlotFile)
plotFile.createFile(createParents = true, failIfExists = false)
for (processor <- plotFile.outputProcessor; out = processor.asOutput) {
out.write(preamble)
for (s <- statements) out.write(s.m + "\n")
}
}
def run() = {
Process(
"matlab -nodesktop -nosplash -r " + localPlotFile.path.takeWhile(_ != '.'),
directory.fileOption,
"" -> "") #> (directory / "log.txt").fileOption.get run
}
}
object Plot {
private[this] var counter = -1
private def next = { counter += 1; counter }
}
|