aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakob Odersky <jodersky@gmail.com>2012-10-08 12:20:40 +0200
committerJakob Odersky <jodersky@gmail.com>2012-10-08 12:20:40 +0200
commite5e135bf1c2c386037496e3f40adb10e0184e066 (patch)
tree5653db65bf02c3c740fa1f6648a6f402e302d38a /src
parentf47512f3b84fce4c561256c65e224d0b65405e2b (diff)
downloadscalam-e5e135bf1c2c386037496e3f40adb10e0184e066.tar.gz
scalam-e5e135bf1c2c386037496e3f40adb10e0184e066.tar.bz2
scalam-e5e135bf1c2c386037496e3f40adb10e0184e066.zip
*refactor tree
*refactor colorSchemes
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/scalam/charting/MatlabChart.scala9
-rw-r--r--src/main/scala/scalam/m/ast/tree.scala8
-rw-r--r--src/main/scala/scalam/plotting/Plot.scala109
-rw-r--r--src/main/scala/scalam/plotting/colorSchemes.scala39
4 files changed, 110 insertions, 55 deletions
diff --git a/src/main/scala/scalam/charting/MatlabChart.scala b/src/main/scala/scalam/charting/MatlabChart.scala
index 4c8032a..9ab3c69 100644
--- a/src/main/scala/scalam/charting/MatlabChart.scala
+++ b/src/main/scala/scalam/charting/MatlabChart.scala
@@ -70,9 +70,16 @@ object MatlabChart {
private 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 = Random.nextString(10)
+ new DataSet(data, name)
+ }
+
val test = 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"""))
+ 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 testChart = new MatlabChart(test, "title", "x [\\sigma \\epsilon]", "\\vec{y} [\\frac{1}{2}]", colorScheme = new HSV(test))
diff --git a/src/main/scala/scalam/m/ast/tree.scala b/src/main/scala/scalam/m/ast/tree.scala
index cad1859..a99b50c 100644
--- a/src/main/scala/scalam/m/ast/tree.scala
+++ b/src/main/scala/scalam/m/ast/tree.scala
@@ -13,9 +13,11 @@ case class DoubleLiteral(x: Double) extends Expression { def m = x.toString }
case class StringLiteral(x: String) extends Expression { def m = "'" + x.toString + "'" }
case object SliceLiteral extends Expression { def m = ":" }
case class ArrayLiteral(elements: Expression*) extends Expression {
- def m = elements.mkString("[", ",", "]")
+ def m = elements.map(_.m).mkString("[", ",", "]")
+}
+case class MatrixLiteral(rows: Expression*) extends Expression {
+ def m = rows.map(_.m).mkString("[", ";", "]")
}
-
case class Variable(id: Identifier) extends Expression { def m = id.m }
case class IndexMatrix(id: Identifier, indices: Expression*) extends Expression {
def m = id.m + indices.map(_.m).mkString("(", ",", ")")
@@ -23,7 +25,7 @@ case class IndexMatrix(id: Identifier, indices: Expression*) extends Expression
case class IndexStructure(id: Identifier, indices: Expression*) extends Expression {
def m = id.m + indices.map(_.m).mkString("{", ",", "}")
}
-case class Call(function: Identifier, params: Expression*) extends Expression {
+case class Function(function: Identifier, params: Expression*) extends Expression {
def m = function.m + params.map(_.m).mkString("(", ",", ")")
}
diff --git a/src/main/scala/scalam/plotting/Plot.scala b/src/main/scala/scalam/plotting/Plot.scala
index b9a0492..1a92f79 100644
--- a/src/main/scala/scalam/plotting/Plot.scala
+++ b/src/main/scala/scalam/plotting/Plot.scala
@@ -13,71 +13,90 @@ class Plot(
grid: Boolean = true,
legend: Boolean = true,
fontSize: Int = 10,
- colorScheme: ColorScheme = Uniform(Black),
+ 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)
+ 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)
+ case (d, i) => RichDataSet(d, Path("data") / i.toString, Identifier("data" + (i + 1)))
}
- val statements: List[Statement] = {
- def data = for ((d, i) <- richDataSets.zipWithIndex.toList) yield {
- val id = Identifier("data" + i)
- val load = Identifier("load")
- Assign(id, Call(load, StringLiteral(d.localPath.path)))
- }
+ private val colors = colorScheme(dataSets)
- val figureId = Identifier("fh")
- def figure = {
- val on = StringLiteral("on")
- val off = StringLiteral("off")
-
- val newFigure = Assign(figureId, Call(Identifier("figure")))
- val holdOn = Evaluate(Call(Identifier("hold"), on))
- val grid = Evaluate(Call(Identifier("grid"), if (this.grid) on else off))
- val title = Evaluate(Call(Identifier("title"), StringLiteral(this.title)))
- val xlabel = Evaluate(Call(Identifier("xlabel"), StringLiteral(this.xLabel)))
- val ylabel = Evaluate(Call(Identifier("ylabel"), StringLiteral(this.yLabel)))
- val fontSize = Evaluate(Call(Identifier("set"), Call(Identifier("gca")), StringLiteral("fontsize"), IntLiteral(this.fontSize)))
- List(newFigure, holdOn, grid, title, xlabel, ylabel, fontSize)
+ 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
}
-
- def plot = for (assignment <- data) yield {
- val plot = Identifier("plot")
+ 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(
- Call(
- plot,
- IndexMatrix(assignment.variable, SliceLiteral, IntLiteral(1)),
- IndexMatrix(assignment.variable, SliceLiteral, IntLiteral(2))))
- }
-
- def legend = if (this.legend)
- Evaluate(Call(Identifier("legend"), (for (d <- dataSets) yield StringLiteral(d.name)): _*)) :: Nil
- else Nil
-
- def wait = List(Evaluate(Call(Identifier("waitfor"), Variable(figureId))))
+ 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))))
- data ::: figure ::: plot ::: legend ::: wait
+ 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 / "results.m")
+ val plotFile = (directory / localPlotFile)
plotFile.createFile(createParents = true, failIfExists = false)
- for (processor <- plotFile.outputProcessor; out = processor.asOutput)
+ 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 " + "results.m".takeWhile(_ != '.'),
- directory.fileOption,
- "" -> ""
- ) #> (directory / "log.txt").fileOption.get run
+ "matlab -nodesktop -nosplash -r " + localPlotFile.path.takeWhile(_ != '.'),
+ directory.fileOption,
+ "" -> "") #> (directory / "log.txt").fileOption.get run
}
}
diff --git a/src/main/scala/scalam/plotting/colorSchemes.scala b/src/main/scala/scalam/plotting/colorSchemes.scala
index 270e775..0664575 100644
--- a/src/main/scala/scalam/plotting/colorSchemes.scala
+++ b/src/main/scala/scalam/plotting/colorSchemes.scala
@@ -4,19 +4,44 @@ import scalam.DataSet
import scalam.m.ast._
trait Color {
- def mColor: Expression
+ def expression: Expression
}
class RGB(r: Double, g: Double, b: Double) extends Color {
- def mColor = ArrayLiteral(DoubleLiteral(r), DoubleLiteral(g), DoubleLiteral(b))
+ def expression = ArrayLiteral(DoubleLiteral(r), DoubleLiteral(g), DoubleLiteral(b))
}
-case object Green extends RGB(0, 1, 0)
+
case object Red extends RGB(1, 0, 0)
+case object Green extends RGB(0, 1, 0)
case object Blue extends RGB(0, 0, 1)
case object Magenta extends RGB(1, 0, 1)
case object Cyan extends RGB(0, 1, 1)
case object Yellow extends RGB(1, 1, 0)
case object Black extends RGB(0, 0, 0)
+
+trait ColorScheme {self =>
+ def apply(dataSets: Seq[DataSet]): Map[DataSet, Color]
+}
+
+class MColorScheme(val function: Identifier) extends ColorScheme {
+ private val ColorVariable = Identifier("cc")
+
+ def initial(dataSets: Seq[DataSet]) = Assign(ColorVariable, Function(function, IntLiteral(dataSets.length)))
+
+ def apply(dataSets: Seq[DataSet]) = (for ((d, i) <- dataSets.zipWithIndex) yield d -> new Color {
+ def expression = IndexMatrix(ColorVariable, IntLiteral(i + 1), SliceLiteral)
+ }).toMap
+
+}
+
+case class Uniform(color: Color) extends ColorScheme {
+ def apply(dataSets: Seq[DataSet]) = dataSets.map(_ -> color).toMap
+}
+object HSV extends MColorScheme(Identifier("hsv"))
+object JET extends MColorScheme(Identifier("jet"))
+
+
+/*
trait ColorScheme { self =>
def color(dataSet: DataSet): Color
@@ -28,6 +53,7 @@ trait ColorScheme { self =>
}
}
+
trait ColorSchemeFactory[C <: ColorScheme] { self =>
def apply(dataSets: Seq[DataSet]): C
@@ -37,7 +63,7 @@ trait ColorSchemeFactory[C <: ColorScheme] { self =>
}
}
-trait MColorScheme extends ColorScheme{
+trait MColorScheme extends ColorScheme {
protected val function: Identifier
protected val dataSets: Seq[DataSet]
private val indices: Map[DataSet, Int] = dataSets.zipWithIndex.toMap
@@ -47,7 +73,7 @@ trait MColorScheme extends ColorScheme{
def initial = Assign(ColorVariable, Call(function, IntLiteral(dataSets.length)))
def color(dataSet: DataSet) = new Color{
- def mColor = IndexMatrix(ColorVariable, IntLiteral(indices(dataSet) + 1), SliceLiteral)
+ def expression = IndexMatrix(ColorVariable, IntLiteral(indices(dataSet) + 1), SliceLiteral)
}
}
@@ -59,4 +85,5 @@ object JET extends ColorSchemeFactory[JET] {def apply(dataSets: Seq[DataSet]) =
case class Uniform(color: Color) extends ColorScheme {
def color(dataSet: DataSet) = color
-} \ No newline at end of file
+}
+*/ \ No newline at end of file