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
108
109
110
111
112
113
114
115
116
|
package scalam.plotting
import scala.sys.process._
import scalam.m.ast._
import scalax.file.Path
import scalam.plotting.styles._
class Plot(
val dataSets: Seq[DataSet],
title: String,
xLabel: String,
yLabel: String,
grid: Boolean = true,
legend: Boolean = true,
fontSize: Int = 10,
styles: Seq[Style[_]] = Seq(),
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)))
}
lazy val roots: List[Root] = {
def loadData(dataSet: RichDataSet) =
Assign(dataSet.id, Function(Identifier("load"), StringLiteral(dataSet.localPath.path))) withComment SimpleComment(dataSet.id.m)
val (initial: Seq[Seq[Statement]], styleMaps: Iterable[DataSet => StyleElement]) = styles.map(_.apply(dataSets)).unzip
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) = Function(Identifier("hold"), if (b) on else off)
def grid(show: Boolean) = Function(Identifier("grid"), if (show) on else off)
def title(s: String) = Function(Identifier("title"), StringLiteral(s))
def xLabel(s: String) = Function(Identifier("xlabel"), StringLiteral(s))
def yLabel(s: String) = Function(Identifier("ylabel"), StringLiteral(s))
def fontSize(size: Int) = Function(Identifier("set"), Variable(Identifier("gca")), StringLiteral("fontsize"), IntLiteral(size))
def plot(dataSet: RichDataSet) = {
val plot = Identifier("plot")
val styleParams = styleMaps.flatMap(styleMap => {val style = styleMap.apply(dataSet.underlying); Seq(style.name, style.expression)})
val params = Seq(
IndexMatrix(dataSet.id, SliceLiteral, IntLiteral(1)),
IndexMatrix(dataSet.id, SliceLiteral, IntLiteral(2))) ++
styleParams
Function(plot, params: _*)
}
def legend(dataSets: Seq[DataSet]) =
Function(Identifier("legend"), (for (d <- dataSets) yield StringLiteral(d.label)): _*) :: Nil
val commands = new scala.collection.mutable.ListBuffer[Root]
commands ++= (for (d <- richDataSets) yield loadData(d))
commands ++= initial.flatten
commands += newFigure(figureId)
commands += hold(true)
commands += grid(this.grid)
commands += fontSize(this.fontSize)
commands += title(this.title)
commands += xLabel(this.xLabel)
commands += yLabel(this.yLabel)
commands ++= (for (d <- richDataSets) yield plot(d))
if (this.legend) commands ++= legend(dataSets)
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()))
Seq(DoubleComment("Generated by scalam, v1.0-new"), DoubleComment(df.format(now)))
}
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) {
for (p <- preamble) out.write(p.line + "\n")
for (r <- roots) out.write(r.line + "\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 }
private def randomDataSet(length: Int) = {
import scala.util.Random
val data = for (i <- 0 until length) yield (i * 1.0, Random.nextDouble() * 10)
val name = "a"
new DataSet(data, name)
}
val ds = Seq(
new DataSet(Seq((0.0, 1.0), (1.0, 1.0), (2.0, 1.0), (3.0, 0.0), (4.0, 1.0), (5.0, 1.0)), "temperature"),
new DataSet(Seq((0.0, 0.0), (1.0, 1.0), (2.0, 4.0), (3.0, 9.0)), """\alpha""")) ++ (0 to 10).map(_ => randomDataSet(10))
val test = new Plot(ds, "title", "x", "y")
}
|