aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/scalam/plotting
diff options
context:
space:
mode:
authorJakob Odersky <jodersky@gmail.com>2012-10-18 12:47:14 +0200
committerJakob Odersky <jodersky@gmail.com>2012-10-18 12:47:14 +0200
commitccd005b60d87e800718fed605ef4ce2b226b942c (patch)
tree4c6dbc241c95e1bc4d8c5ac6edbb1dc7e6247b21 /src/main/scala/scalam/plotting
parenta4625a6010de7bd32f791200c688a5b5bb9f7b78 (diff)
downloadscalam-ccd005b60d87e800718fed605ef4ce2b226b942c.tar.gz
scalam-ccd005b60d87e800718fed605ef4ce2b226b942c.tar.bz2
scalam-ccd005b60d87e800718fed605ef4ce2b226b942c.zip
lots of changes:
*refactor styles to seperate packages *add io support *add interpreter support (removes need for seperate matlab instance for every figure)) *add plotting syntactic sugar
Diffstat (limited to 'src/main/scala/scalam/plotting')
-rw-r--r--src/main/scala/scalam/plotting/FontSize.scala6
-rw-r--r--src/main/scala/scalam/plotting/Plot.scala16
-rw-r--r--src/main/scala/scalam/plotting/Plotter.scala37
-rw-r--r--src/main/scala/scalam/plotting/package.scala7
-rw-r--r--src/main/scala/scalam/plotting/styles/color/colors.scala26
-rw-r--r--src/main/scala/scalam/plotting/styles/color/styles.scala20
-rw-r--r--src/main/scala/scalam/plotting/styles/colors.scala39
-rw-r--r--src/main/scala/scalam/plotting/styles/line/lines.scala (renamed from src/main/scala/scalam/plotting/styles/lines.scala)5
-rw-r--r--src/main/scala/scalam/plotting/styles/marker/markers.scala (renamed from src/main/scala/scalam/plotting/styles/markers.scala)19
-rw-r--r--src/main/scala/scalam/plotting/styles/marker/styles.scala17
-rw-r--r--src/main/scala/scalam/plotting/styles/styles.scala7
11 files changed, 131 insertions, 68 deletions
diff --git a/src/main/scala/scalam/plotting/FontSize.scala b/src/main/scala/scalam/plotting/FontSize.scala
new file mode 100644
index 0000000..edd2323
--- /dev/null
+++ b/src/main/scala/scalam/plotting/FontSize.scala
@@ -0,0 +1,6 @@
+package scalam.plotting
+
+
+/** Helper class used for implicit font size specification. A font size is nothing but an Int,
+ * but defining an implicit of type int could pollute a lot of code. */
+case class FontSize(fs: Int) \ No newline at end of file
diff --git a/src/main/scala/scalam/plotting/Plot.scala b/src/main/scala/scalam/plotting/Plot.scala
index 38a4da6..f354997 100644
--- a/src/main/scala/scalam/plotting/Plot.scala
+++ b/src/main/scala/scalam/plotting/Plot.scala
@@ -14,7 +14,7 @@ class Plot(
grid: Boolean = true,
legend: Boolean = true,
fontSize: Int = 10,
- styleSchemes: Seq[StyleScheme[Style]] = Seq(),
+ styles: Seq[Style[_]] = Seq(),
name: String = "plot" + Plot.next) {
val directory = Path(name)
@@ -28,7 +28,7 @@ class Plot(
lazy val statements: List[Statement] = {
def loadData(dataSet: RichDataSet) = Assign(dataSet.id, Function(Identifier("load"), StringLiteral(dataSet.localPath.path)))
- val (initial: Seq[Seq[Statement]], styleMaps: Seq[DataSet => Style]) = styleSchemes.map(_.apply(dataSets)).unzip
+ val (initial: Seq[Seq[Statement]], styleMaps: Iterable[DataSet => StyleElement]) = styles.map(_.apply(dataSets)).unzip
val figureId = Identifier("fh")
val on = StringLiteral("on")
@@ -52,7 +52,6 @@ class Plot(
}
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))
@@ -66,7 +65,6 @@ class Plot(
commands += yLabel(this.yLabel)
commands ++= (for (d <- richDataSets) yield plot(d))
if (this.legend) commands ++= legend(dataSets)
- commands ++= wait(figureId)
commands.toList
}
@@ -74,10 +72,10 @@ class Plot(
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"
+
+ "%% Generated by scalam, v1.0\n" +
+ "%% " + df.format(now) + "\n"
+
}
def save() = {
@@ -109,7 +107,7 @@ object Plot {
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)
+ val name = "a"
new DataSet(data, name)
}
diff --git a/src/main/scala/scalam/plotting/Plotter.scala b/src/main/scala/scalam/plotting/Plotter.scala
new file mode 100644
index 0000000..9292490
--- /dev/null
+++ b/src/main/scala/scalam/plotting/Plotter.scala
@@ -0,0 +1,37 @@
+package scalam.plotting
+
+import scalam.DataSet
+import scalam.m._
+import scalam.m.ast._
+import scalam.plotting.styles._
+
+trait Plotter {
+ import Plotter._
+
+ val pwd: scalax.file.Path
+
+ lazy val interpreter = new MatlabInterpreter(pwd)
+
+ //def plot(dataSets: Seq[DataSet], title: String, x: String, y: String, grid: Boolean = true, legend: Boolean = true)(implicit styles: Seq[Style[_]] = defaultStyles, fontSize: FontSize = defaultFontSize): Plot =
+ //new Plot(dataSets, title, x, y, grid, legend, styles = styles, fontSize = fontSize.fs)
+
+ def plot(dataSets: Seq[DataSet], title: String, x: String, y: String, grid: Boolean = true, legend: Boolean = true)(implicit styles: Seq[Style[_]] = defaultStyles, fontSize: FontSize = defaultFontSize) = {
+ val p = new Plot(dataSets, title, x, y, grid, legend, styles = styles, fontSize = fontSize.fs)
+ p.save()
+ val s = Evaluate(Function(Identifier("run"), StringLiteral((p.directory / p.localPlotFile).path)))
+ //val s = "run '" + (p.directory / p.localPlotFile).path + "'"
+ println(s.m)
+ interpreter.evaluate(s)
+ }
+
+ def exit() {
+ interpreter.write("exit")
+ interpreter.close()
+ }
+
+}
+
+object Plotter {
+ val defaultStyles = Seq(color.JET, Uniform(marker.Plus), Uniform(line.Solid))
+ val defaultFontSize = FontSize(16)
+} \ No newline at end of file
diff --git a/src/main/scala/scalam/plotting/package.scala b/src/main/scala/scalam/plotting/package.scala
new file mode 100644
index 0000000..3539470
--- /dev/null
+++ b/src/main/scala/scalam/plotting/package.scala
@@ -0,0 +1,7 @@
+package scalam
+
+import scalam.plotting.styles._
+
+package object plotting {
+
+} \ No newline at end of file
diff --git a/src/main/scala/scalam/plotting/styles/color/colors.scala b/src/main/scala/scalam/plotting/styles/color/colors.scala
new file mode 100644
index 0000000..73fa221
--- /dev/null
+++ b/src/main/scala/scalam/plotting/styles/color/colors.scala
@@ -0,0 +1,26 @@
+package scalam.plotting.styles.color
+
+import scalam.m.ast._
+import scalam.DataSet
+import scalam.plotting.styles.Style
+import scalam.plotting.styles.StyleElement
+
+trait Color extends StyleElement {
+ def name = StringLiteral("Color")
+}
+
+class RGB(r: Double, g: Double, b: Double) extends Color {
+ def expression = ArrayLiteral(DoubleLiteral(r), DoubleLiteral(g), DoubleLiteral(b))
+}
+
+class LiteralColor(value: String) extends Color {
+ def expression = StringLiteral(value)
+}
+
+case object Red extends LiteralColor("r")
+case object Green extends LiteralColor("g")
+case object Blue extends LiteralColor("b")
+case object Magenta extends LiteralColor("m")
+case object Cyan extends LiteralColor("c")
+case object Yellow extends LiteralColor("y")
+case object Black extends LiteralColor("k") \ No newline at end of file
diff --git a/src/main/scala/scalam/plotting/styles/color/styles.scala b/src/main/scala/scalam/plotting/styles/color/styles.scala
new file mode 100644
index 0000000..e50f507
--- /dev/null
+++ b/src/main/scala/scalam/plotting/styles/color/styles.scala
@@ -0,0 +1,20 @@
+package scalam.plotting.styles.color
+
+import scalam.m.ast._
+import scalam.DataSet
+import scalam.plotting.styles.Style
+import scalam.plotting.styles.StyleElement
+
+class MColorStyle(val function: Identifier) extends Style[Color] {
+ private val ColorVariable = Identifier("cc")
+
+ private def initial(dataSets: Seq[DataSet]) = Seq(Assign(ColorVariable, Function(function, IntLiteral(dataSets.length))))
+ private def map(dataSets: Iterable[DataSet]) = (for ((d, i) <- dataSets.zipWithIndex) yield d -> new Color {
+ def expression = IndexMatrix(ColorVariable, IntLiteral(i + 1), SliceLiteral)
+ }).toMap
+
+ override def apply(dataSets: Seq[DataSet]) = (initial(dataSets), map(dataSets))
+}
+
+object HSV extends MColorStyle(Identifier("hsv"))
+object JET extends MColorStyle(Identifier("jet")) \ No newline at end of file
diff --git a/src/main/scala/scalam/plotting/styles/colors.scala b/src/main/scala/scalam/plotting/styles/colors.scala
deleted file mode 100644
index d7463e5..0000000
--- a/src/main/scala/scalam/plotting/styles/colors.scala
+++ /dev/null
@@ -1,39 +0,0 @@
-package scalam.plotting.styles
-
-import scalam.m.ast._
-import scalam.DataSet
-
-trait Color extends Style {
- def name = StringLiteral("Color")
-}
-
-class RGB(r: Double, g: Double, b: Double) extends Color {
- def expression = ArrayLiteral(DoubleLiteral(r), DoubleLiteral(g), DoubleLiteral(b))
-}
-
-class LiteralColor(value: String) extends Color {
- def expression = StringLiteral(value)
-}
-
-case object Red extends LiteralColor("r")
-case object Green extends LiteralColor("g")
-case object Blue extends LiteralColor("b")
-case object Magenta extends LiteralColor("c")
-case object Cyan extends LiteralColor("m")
-case object Yellow extends LiteralColor("y")
-case object Black extends LiteralColor("k")
-
-
-class MColorScheme(val function: Identifier) extends StyleScheme[Color] {
- private val ColorVariable = Identifier("cc")
-
- private def initial(dataSets: Seq[DataSet]) = Seq(Assign(ColorVariable, Function(function, IntLiteral(dataSets.length))))
- private def map(dataSets: Seq[DataSet]) = (for ((d, i) <- dataSets.zipWithIndex) yield d -> new Color {
- def expression = IndexMatrix(ColorVariable, IntLiteral(i + 1), SliceLiteral)
- }).toMap
-
- override def apply(dataSets: Seq[DataSet]) = (initial(dataSets), map(dataSets))
-}
-
-object HSV extends MColorScheme(Identifier("hsv"))
-object JET extends MColorScheme(Identifier("jet")) \ No newline at end of file
diff --git a/src/main/scala/scalam/plotting/styles/lines.scala b/src/main/scala/scalam/plotting/styles/line/lines.scala
index c8c8bf3..63c6d23 100644
--- a/src/main/scala/scalam/plotting/styles/lines.scala
+++ b/src/main/scala/scalam/plotting/styles/line/lines.scala
@@ -1,8 +1,9 @@
-package scalam.plotting.styles
+package scalam.plotting.styles.line
import scalam.m.ast._
+import scalam.plotting.styles.StyleElement
-trait Line extends Style {
+trait Line extends StyleElement {
def name = StringLiteral("LineStyle")
}
diff --git a/src/main/scala/scalam/plotting/styles/markers.scala b/src/main/scala/scalam/plotting/styles/marker/markers.scala
index 6c83cdb..f821396 100644
--- a/src/main/scala/scalam/plotting/styles/markers.scala
+++ b/src/main/scala/scalam/plotting/styles/marker/markers.scala
@@ -1,9 +1,11 @@
-package scalam.plotting.styles
+package scalam.plotting.styles.marker
import scalam.DataSet
import scalam.m.ast._
+import scalam.plotting.styles.Style
+import scalam.plotting.styles.StyleElement
-trait Marker extends Style {
+trait Marker extends StyleElement {
def name = StringLiteral("Marker")
}
case object Plus extends Marker { def expression = StringLiteral("+") }
@@ -19,15 +21,4 @@ case object RightTriangle extends Marker { def expression = StringLiteral(">") }
case object LeftTriangle extends Marker { def expression = StringLiteral("<") }
case object Pentagram extends Marker { def expression = StringLiteral("p") }
case object Hexagram extends Marker { def expression = StringLiteral("h") }
-case object NoMarker extends Marker { def expression = StringLiteral("none") }
-
-object AllMarkerScheme extends StyleScheme[Marker] {
-
- val markers = List(Plus, Circle, Asterisk, Point, Cross, Square, Diamond, UpTriangle, DownTriangle, RightTriangle, LeftTriangle, Pentagram, Hexagram)
- private def map(dataSets: Seq[DataSet]): Map[DataSet, Marker] = dataSets.zipWithIndex.map{
- case (d, i) => d -> markers(i % (markers.length-1))
- }.toMap
-
- override def apply(dataSets: Seq[DataSet]) = (Seq.empty[Statement], map(dataSets))
-
-} \ No newline at end of file
+case object NoMarker extends Marker { def expression = StringLiteral("none") } \ No newline at end of file
diff --git a/src/main/scala/scalam/plotting/styles/marker/styles.scala b/src/main/scala/scalam/plotting/styles/marker/styles.scala
new file mode 100644
index 0000000..9663778
--- /dev/null
+++ b/src/main/scala/scalam/plotting/styles/marker/styles.scala
@@ -0,0 +1,17 @@
+package scalam.plotting.styles.marker
+
+import scalam.DataSet
+import scalam.m.ast._
+import scalam.plotting.styles.Style
+import scalam.plotting.styles.StyleElement
+
+object AllMarkerStyle extends Style[Marker] {
+
+ val markers = List(Plus, Circle, Asterisk, Point, Cross, Square, Diamond, UpTriangle, DownTriangle, RightTriangle, LeftTriangle, Pentagram, Hexagram)
+ private def map(dataSets: Iterable[DataSet]): Map[DataSet, Marker] = dataSets.zipWithIndex.map{
+ case (d, i) => d -> markers(i % (markers.length-1))
+ }.toMap
+
+ def apply(dataSets: Seq[DataSet]) = (Seq.empty[Statement], map(dataSets))
+
+} \ No newline at end of file
diff --git a/src/main/scala/scalam/plotting/styles/styles.scala b/src/main/scala/scalam/plotting/styles/styles.scala
index 7b05955..098fcf7 100644
--- a/src/main/scala/scalam/plotting/styles/styles.scala
+++ b/src/main/scala/scalam/plotting/styles/styles.scala
@@ -4,18 +4,17 @@ import scalam.DataSet
import scalam.m.ast._
-trait Style {
+trait StyleElement {
//command line option
def name: StringLiteral
//expression
def expression: Expression
}
-
-trait StyleScheme[+S <: Style] {
+trait Style[+S <: StyleElement] {
def apply(dataSets: Seq[DataSet]): Tuple2[Seq[Statement], DataSet => S]
}
-case class Uniform[S <: Style](element: S) extends StyleScheme[S] {
+case class Uniform[S <: StyleElement](element: S) extends Style[S] {
override def apply(dataSets: Seq[DataSet]) = (Seq.empty[Statement], (d: DataSet) => element)
} \ No newline at end of file