You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mahout.apache.org by ap...@apache.org on 2016/05/01 23:51:53 UTC

mahout git commit: MAHOUT-1838: Simple 2d and 3d plots of sampled drm points. closes apache/mahout#230

Repository: mahout
Updated Branches:
  refs/heads/master 0d6c4e024 -> b0cede1e2


MAHOUT-1838: Simple 2d and 3d plots of sampled drm points. closes apache/mahout#230


Project: http://git-wip-us.apache.org/repos/asf/mahout/repo
Commit: http://git-wip-us.apache.org/repos/asf/mahout/commit/b0cede1e
Tree: http://git-wip-us.apache.org/repos/asf/mahout/tree/b0cede1e
Diff: http://git-wip-us.apache.org/repos/asf/mahout/diff/b0cede1e

Branch: refs/heads/master
Commit: b0cede1e2725c16b039c18c4eb0ee4aa324d7389
Parents: 0d6c4e0
Author: Andrew Palumbo <ap...@apache.org>
Authored: Sun May 1 17:51:01 2016 -0400
Committer: Andrew Palumbo <ap...@apache.org>
Committed: Sun May 1 17:51:34 2016 -0400

----------------------------------------------------------------------
 examples/bin/spark-shell-plot.mscala            |  86 ++++++++++++-
 .../org/apache/mahout/visualization/MGrid.scala |  65 ++++++++++
 .../apache/mahout/visualization/MHisto.scala    |  66 ++++++++++
 .../apache/mahout/visualization/MHisto3d.scala  |  65 ++++++++++
 .../apache/mahout/visualization/MPlot2d.scala   |  65 ++++++++++
 .../apache/mahout/visualization/MPlot3d.scala   |  68 +++++++++++
 .../org/apache/mahout/visualization/MSurf.scala |  67 ++++++++++
 .../mahout/visualization/MahoutPlot.scala       |  53 ++++++++
 .../org/apache/mahout/visualization/mlpot.scala |  24 ----
 .../apache/mahout/visualization/mplot2d.scala   |  69 -----------
 .../apache/mahout/visualization/mplot3d.scala   |  24 ----
 .../apache/mahout/visualization/package.scala   | 122 +++++++++++++++++++
 12 files changed, 654 insertions(+), 120 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mahout/blob/b0cede1e/examples/bin/spark-shell-plot.mscala
----------------------------------------------------------------------
diff --git a/examples/bin/spark-shell-plot.mscala b/examples/bin/spark-shell-plot.mscala
index 73578f7..4efb0c0 100644
--- a/examples/bin/spark-shell-plot.mscala
+++ b/examples/bin/spark-shell-plot.mscala
@@ -1,4 +1,24 @@
-import org.apache.mahout.visualization.mplot2d
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+
+// this is the only import needed
+import org.apache.mahout.visualization._
+//import org.apache.mahout.visualization.MPlot2d
 
 val mxRnd = Matrices.symmetricUniformView(5000000, 2, 1234)
 val drmRand = drmParallelize(mxRnd)
@@ -11,9 +31,69 @@ val drmSin = drmRand.mapBlock() {case (keys, block) =>
   }
   keys -> blockB
 }
+mplot2d(drmRand, samplePercent = .1)
+mplot2d(drmSin, samplePercent = .1)
+
+// 3d scatter
+//import org.apache.mahout.visualization.MPlot3d
+val mxRnd3d = Matrices.symmetricUniformView(50000, 3, 1234)
+val drmRand3d = drmParallelize(mxRnd3d)
+
+val drmGauss = drmRand3d.mapBlock() {case (keys, block) =>
+  val blockB = block.like()
+  for (i <- 0 until block.nrow) {
+    val x: Double = block(i, 0)
+    val y: Double = block(i, 1)
+    val z: Double = block(i, 2)
+
+    blockB(i, 0) = x
+    blockB(i, 1) = y
+    blockB(i, 2) = Math.exp(-((Math.pow(x, 2)) + (Math.pow(y, 2)))/2)
+  }
+  keys -> blockB
+}
+
+mplot3d(drmGauss, samplePercent = 50)
+
+// 3d Surface needs to be ordered. --not working correctly as is
+//import org.apache.mahout.visualization.MSurf
+msurf(drmGauss, samplePercent = 10)
+
+
+// 3d grid --not still not rendering -needs fix
+//import org.apache.mahout.visualization.MGrid
+val mxRnd3d = Matrices.symmetricUniformView(50000, 3, 1234)
+val drmRand3d = drmParallelize(mxRnd3d)
+
+val drmGauss = drmRand3d.mapBlock() {case (keys, block) =>
+  val blockB = block.like()
+  for (i <- 0 until block.nrow) {
+    val x: Double = block(i, 0)
+    val y: Double = block(i, 1)
+    val z: Double = block(i, 2)
+
+    blockB(i, 0) = x
+    blockB(i, 1) = y
+    blockB(i, 2) = Math.exp(-((Math.pow(x, 2)) + (Math.pow(y, 2)))/2)
+  }
+  keys -> blockB
+}
+
+mgrid(drmGauss, samplePercent = 10)
+
+
+// 2 and 3d histograms of gaussian data
+//import org.apache.mahout.visualization.MHisto3d
+//import org.apache.mahout.visualization.MHisto
+val mxRnd3d = Matrices.gaussianView(50000, 3, 1234)
+val drmRand3d = drmParallelize(mxRnd3d)
 
-new mplot2d(drmRand, samplePercent = 1)
-new mplot2d(drmSin, samplePercent = 1)
+// check out frequencies of the first column across 10 bins of original data.
+mhisto(drmRand3d, 20, samplePercent = 50)
 
+// create a 3d-Histogram
+val h3d = mhisto3d(drmRand3d, 10, samplePercent = 10)
 
+// export the canvas to the filesystem
+h3d.exportPNG("/tmp/histo3d.png")
 

http://git-wip-us.apache.org/repos/asf/mahout/blob/b0cede1e/math-scala/src/main/scala/org/apache/mahout/visualization/MGrid.scala
----------------------------------------------------------------------
diff --git a/math-scala/src/main/scala/org/apache/mahout/visualization/MGrid.scala b/math-scala/src/main/scala/org/apache/mahout/visualization/MGrid.scala
new file mode 100644
index 0000000..3f6e654
--- /dev/null
+++ b/math-scala/src/main/scala/org/apache/mahout/visualization/MGrid.scala
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.mahout.visualization
+
+import java.awt.{BorderLayout, Color}
+import javax.swing.JFrame
+
+import org.apache.mahout.math._
+import org.apache.mahout.math.drm._
+import org.apache.mahout.math.scalabindings.RLikeOps._
+import org.apache.mahout.math.scalabindings._
+import smile.plot._
+
+
+/**
+  * Create a grid plot of a DRM by sampling a given percentage
+  * and plotting corresponding points of (drmXYZ(::,0), drmXYZ(::,1), drmXYZ(::,2))
+  *
+  * @param drmXYZ an m x 3 Drm drm to plot
+  * @param samplePercent the percentage the drm to sample
+  * @tparam K
+  */
+class MGrid[K](drmXYZ: DrmLike[K], samplePercent: Double = 1, setVisible: Boolean = true) extends MahoutPlot{
+
+  val drmSize = drmXYZ.checkpoint().numRows()
+  val sampleDec: Double = (samplePercent / 100.toDouble)
+  val numSamples: Int = (drmSize * sampleDec).toInt
+
+   mPlotMatrix = drmSampleKRows(drmXYZ, numSamples, false)
+
+  // matrix rows
+  val m = mPlotMatrix.numRows()
+
+  // roll a set of 3d points in an m x 3 drm  into a m x m x 3 matrix.
+  val array3d: Array[Array[Array[Double]]] = mxXYZ2array3d(mPlotMatrix)
+
+  canvas = Grid.plot(array3d)
+  canvas.setTitle("3d Grid Plot: " + samplePercent + " % sample of " + drmSize + " points")
+
+  plotPanel = new PlotPanel(canvas)
+
+  plotFrame = new JFrame("Grid Plot")
+  plotFrame.setLayout(new BorderLayout())
+  plotFrame.add(plotPanel)
+  plotFrame.setSize(300, 300)
+  if (setVisible) {
+    plotFrame.setVisible(true)
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/mahout/blob/b0cede1e/math-scala/src/main/scala/org/apache/mahout/visualization/MHisto.scala
----------------------------------------------------------------------
diff --git a/math-scala/src/main/scala/org/apache/mahout/visualization/MHisto.scala b/math-scala/src/main/scala/org/apache/mahout/visualization/MHisto.scala
new file mode 100644
index 0000000..201bdeb
--- /dev/null
+++ b/math-scala/src/main/scala/org/apache/mahout/visualization/MHisto.scala
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.mahout.visualization
+
+import java.awt.{BorderLayout, Color}
+import javax.swing.JFrame
+
+import org.apache.mahout.math._
+import org.apache.mahout.math.drm._
+import org.apache.mahout.math.scalabindings.RLikeOps._
+import org.apache.mahout.math.scalabindings._
+import smile.plot._
+
+
+/**
+  * Create a Histogram of bims of a DRM by sampling a given percentage
+  * and plotting corresponding points of (drmXY(::,0),drmXY(::,1))
+  *
+  * @param drmXY an m x 1 Drm Column, drm to plot
+  * @param numBins: number of bins
+  * @param samplePercent the percentage the drm to sample. Default =1
+  * @tparam K
+  */
+class MHisto[K](drmXY: DrmLike[K], numBins: Int, samplePercent: Double = 1, setVisible: Boolean = true)  extends MahoutPlot {
+  val drmSize = drmXY.checkpoint().numRows()
+  val sampleDec: Double = (samplePercent / 100.toDouble)
+
+  val numSamples: Int = (drmSize * sampleDec).toInt
+
+  mPlotMatrix = drmSampleKRows(drmXY, numSamples, false)
+  val arrays = Array.ofDim[Double](mPlotMatrix.numRows())
+  for (i <- 0 until mPlotMatrix.numRows()) {
+       arrays(i) = mPlotMatrix(i, 0)
+  }
+
+  // just use bins during development, can define ranges etc later
+  canvas = Histogram.plot(arrays, numBins)
+  canvas.setTitle("2d Histogram: " + samplePercent + " % sample of " + drmSize +" points")
+  canvas.setAxisLabels("x_0", "frequency")
+
+  plotPanel = new PlotPanel(canvas)
+
+  plotFrame = new JFrame("2d Histogram")
+  plotFrame.setLayout(new BorderLayout())
+  plotFrame.add(plotPanel)
+  plotFrame.setSize(300,300)
+  if (setVisible) {
+     plotFrame.setVisible(true)
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/mahout/blob/b0cede1e/math-scala/src/main/scala/org/apache/mahout/visualization/MHisto3d.scala
----------------------------------------------------------------------
diff --git a/math-scala/src/main/scala/org/apache/mahout/visualization/MHisto3d.scala b/math-scala/src/main/scala/org/apache/mahout/visualization/MHisto3d.scala
new file mode 100644
index 0000000..2c871f5
--- /dev/null
+++ b/math-scala/src/main/scala/org/apache/mahout/visualization/MHisto3d.scala
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.mahout.visualization
+
+import java.awt.{BorderLayout, Color}
+import javax.swing.JFrame
+
+import org.apache.mahout.math._
+import org.apache.mahout.math.drm._
+import org.apache.mahout.math.scalabindings.RLikeOps._
+import org.apache.mahout.math.scalabindings._
+import smile.plot._
+
+
+/**
+  * Create 3d Histogram of a DRM by sampling a given percentage
+  * and plotting corresponding points of (drmXYZ(::,0), drmXYZ(::,1), drmXYZ(::,2))
+  *
+  * @param drmXY an m x 3 Drm drm to plot
+  * @param numBins num bins to define histogram on
+  * @param samplePercent the percentage the drm to sample
+  * @tparam K
+  */
+class MHisto3d[K](drmXY: DrmLike[K],numBins: Int, samplePercent: Double = 1, setVisible: Boolean = true) extends MahoutPlot {
+  val drmSize = drmXY.checkpoint().numRows()
+  val sampleDec: Double = (samplePercent / 100.toDouble)
+
+  val numSamples: Int = (drmSize * sampleDec).toInt
+
+  mPlotMatrix = drmSampleKRows(drmXY, numSamples, false)
+  val arrays: Array[Array[Double]] = Array.ofDim[Double](mPlotMatrix.numRows(), 2)
+  for (i <- 0 until mPlotMatrix.numRows()) {
+    arrays(i)(0) = mPlotMatrix(i, 0)
+    arrays(i)(1) = mPlotMatrix(i, 1)
+  }
+
+  canvas = Histogram3D.plot(arrays, Palette.jet(256, 1.0f))
+  canvas.setTitle("3d Histogram: " + samplePercent + " % sample of " + drmSize + " points")
+
+  plotPanel = new PlotPanel(canvas)
+
+  plotFrame = new JFrame("3d Histogram")
+  plotFrame.setLayout(new BorderLayout())
+  plotFrame.add(plotPanel)
+  plotFrame.setSize(300, 300)
+  if (setVisible) {
+    plotFrame.setVisible(true)
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/mahout/blob/b0cede1e/math-scala/src/main/scala/org/apache/mahout/visualization/MPlot2d.scala
----------------------------------------------------------------------
diff --git a/math-scala/src/main/scala/org/apache/mahout/visualization/MPlot2d.scala b/math-scala/src/main/scala/org/apache/mahout/visualization/MPlot2d.scala
new file mode 100644
index 0000000..5b77a2c
--- /dev/null
+++ b/math-scala/src/main/scala/org/apache/mahout/visualization/MPlot2d.scala
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.mahout.visualization
+
+import java.awt.{BorderLayout, Color}
+import javax.swing.JFrame
+
+import org.apache.mahout.math._
+import scalabindings._
+import RLikeOps._
+import drm._
+import smile.plot._
+
+
+/**
+  * Create a scatter plot of a DRM by sampling a given percentage
+  * and plotting corresponding points of (drmXY(::,0),drmXY(::,1))
+  *
+  * @param drmXY an m x 2 Drm drm to plot
+  * @param samplePercent the percentage the drm to sample
+  * @tparam K
+  */
+class MPlot2d[K](drmXY: DrmLike[K], samplePercent: Double  = 1, setVisible: Boolean = true)  extends MahoutPlot {
+   val drmSize = drmXY.checkpoint().numRows()
+   val sampleDec: Double = (samplePercent / 100.toDouble)
+
+   val numSamples: Int = (drmSize * sampleDec).toInt
+
+   mPlotMatrix = drmSampleKRows(drmXY, numSamples, false)
+   val arrays: Array[Array[Double]]  = Array.ofDim[Double](mPlotMatrix.numRows(), 2)
+   for (i <- 0 until mPlotMatrix.numRows()) {
+        arrays(i)(0) = mPlotMatrix(i, 0)
+        arrays(i)(1) = mPlotMatrix(i, 1)
+   }
+
+   canvas = ScatterPlot.plot(arrays, Color.BLUE)
+   canvas.setTitle("2d scatter Plot: " + samplePercent + " % sample of " + drmSize +" points")
+   canvas.setAxisLabels("x_0", "x_1")
+
+   plotPanel = new PlotPanel(canvas)
+
+   plotFrame = new JFrame("2d scatter Plot")
+   plotFrame.setLayout(new BorderLayout())
+   plotFrame.add(plotPanel)
+   plotFrame.setSize(300,300)
+   if (setVisible) {
+        plotFrame.setVisible(true)
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/mahout/blob/b0cede1e/math-scala/src/main/scala/org/apache/mahout/visualization/MPlot3d.scala
----------------------------------------------------------------------
diff --git a/math-scala/src/main/scala/org/apache/mahout/visualization/MPlot3d.scala b/math-scala/src/main/scala/org/apache/mahout/visualization/MPlot3d.scala
new file mode 100644
index 0000000..c7e023d
--- /dev/null
+++ b/math-scala/src/main/scala/org/apache/mahout/visualization/MPlot3d.scala
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.mahout.visualization
+
+import java.awt.{BorderLayout, Color}
+import java.io.File
+import javax.swing.JFrame
+
+import org.apache.mahout.math._
+import scalabindings._
+import RLikeOps._
+import drm._
+import smile.plot._
+
+import scala.collection.JavaConversions._
+
+
+/**
+  * Create a scatter plot of a DRM by sampling a given percentage
+  * and plotting corresponding points of (drmXYZ(::,0), drmXYZ(::,1), drmXYZ(::,2))
+  *
+  * @param drmXYZ an m x 3 Drm drm to plot
+  * @param samplePercent the percentage the drm to sample
+  * @tparam K
+  */
+class MPlot3d[K](drmXYZ: DrmLike[K], samplePercent: Double = 1, setVisible: Boolean = true) extends MahoutPlot {
+  val drmSize = drmXYZ.checkpoint().numRows()
+  val sampleDec: Double = (samplePercent / 100.toDouble)
+
+  val numSamples: Int = (drmSize * sampleDec).toInt
+
+  mPlotMatrix = drmSampleKRows(drmXYZ, numSamples, false)
+  val arrays: Array[Array[Double]] = Array.ofDim[Double](mPlotMatrix.numRows(), 3)
+  for (i <- 0 until mPlotMatrix.numRows()) {
+    arrays(i)(0) = mPlotMatrix(i, 0)
+    arrays(i)(1) = mPlotMatrix(i, 1)
+    arrays(i)(2) = mPlotMatrix(i, 2)
+  }
+
+  canvas = ScatterPlot.plot(arrays, Color.RED)
+  canvas.setTitle("3d scatter Plot: " + samplePercent + " % sample of " + drmSize + " points")
+
+  plotPanel = new PlotPanel(canvas)
+
+  plotFrame = new JFrame("3d scatter Plot")
+  plotFrame.setLayout(new BorderLayout())
+  plotFrame.add(plotPanel)
+  plotFrame.setSize(300, 300)
+  if (setVisible) {
+    plotFrame.setVisible(true)
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/mahout/blob/b0cede1e/math-scala/src/main/scala/org/apache/mahout/visualization/MSurf.scala
----------------------------------------------------------------------
diff --git a/math-scala/src/main/scala/org/apache/mahout/visualization/MSurf.scala b/math-scala/src/main/scala/org/apache/mahout/visualization/MSurf.scala
new file mode 100644
index 0000000..d07f01f
--- /dev/null
+++ b/math-scala/src/main/scala/org/apache/mahout/visualization/MSurf.scala
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.mahout.visualization
+
+import java.awt.{BorderLayout, Color}
+import javax.swing.JFrame
+
+import org.apache.mahout.math._
+import scalabindings._
+import RLikeOps._
+import drm._
+import smile.plot._
+
+
+
+/**
+  * Create a s surface plot of a DRM by sampling a given percentage
+  * and plotting corresponding points of (drmXYZ(::,0), drmXYZ(::,1), drmXYZ(::,2))
+  *
+  * @param drmXYZ an m x 3 Drm drm to plot
+  * @param samplePercent the percentage the drm to sample
+  * @tparam K
+  */
+class MSurf[K](drmXYZ: DrmLike[K], samplePercent: Double = 1, setVisible: Boolean = true) extends MahoutPlot {
+  val drmSize = drmXYZ.checkpoint().numRows()
+  val sampleDec: Double = (samplePercent / 100.toDouble)
+
+  val numSamples: Int = (drmSize * sampleDec).toInt
+
+  mPlotMatrix = drmSampleKRows(drmXYZ, numSamples, false)
+
+  val arrays: Array[Array[Double]]  = Array.ofDim[Double](mPlotMatrix.numRows(), 3)
+  for (i <- 0 until mPlotMatrix.numRows()) {
+    arrays(i)(0) = mPlotMatrix(i, 0)
+    arrays(i)(1) = mPlotMatrix(i, 1)
+    arrays(i)(2) = mPlotMatrix(i, 2)
+  }
+
+  canvas = Surface.plot(arrays, Palette.jet(256, 1.0f))
+  canvas.setTitle("Surface Plot: " + samplePercent + " % sample of " + drmSize +" points")
+
+  plotPanel = new PlotPanel(canvas)
+
+  plotFrame = new JFrame("Surface Plot")
+  plotFrame.setLayout(new BorderLayout())
+  plotFrame.add(plotPanel)
+  plotFrame.setSize(300, 300)
+  if (setVisible) {
+    plotFrame.setVisible(true)
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/mahout/blob/b0cede1e/math-scala/src/main/scala/org/apache/mahout/visualization/MahoutPlot.scala
----------------------------------------------------------------------
diff --git a/math-scala/src/main/scala/org/apache/mahout/visualization/MahoutPlot.scala b/math-scala/src/main/scala/org/apache/mahout/visualization/MahoutPlot.scala
new file mode 100644
index 0000000..8688a3d
--- /dev/null
+++ b/math-scala/src/main/scala/org/apache/mahout/visualization/MahoutPlot.scala
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.mahout.visualization
+
+import java.awt.Graphics2D
+import java.awt.image.BufferedImage
+import java.io.File
+import javax.imageio.ImageIO
+import javax.swing.JFrame
+
+import org.apache.mahout.math.Matrix
+import smile.plot.{PlotCanvas, PlotPanel}
+
+
+trait MahoutPlot  {
+
+  var canvas : PlotCanvas = _
+  var plotPanel: PlotPanel = _
+  var plotFrame: JFrame = _
+  var mPlotMatrix: Matrix = _
+  def contentPane = canvas
+
+  // export a PNG of the plot to /tmp/test.png
+  def exportPNG(path: String ="/tmp/test.png") = {
+    val bi: BufferedImage =
+      new BufferedImage(contentPane.getWidth, contentPane.getHeight, BufferedImage.TYPE_INT_ARGB)
+
+    val g2d: Graphics2D = bi.createGraphics
+
+    contentPane.printAll(g2d)
+
+    val file: File = new File(path)
+
+    ImageIO.write(bi, "PNG", file)
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/mahout/blob/b0cede1e/math-scala/src/main/scala/org/apache/mahout/visualization/mlpot.scala
----------------------------------------------------------------------
diff --git a/math-scala/src/main/scala/org/apache/mahout/visualization/mlpot.scala b/math-scala/src/main/scala/org/apache/mahout/visualization/mlpot.scala
deleted file mode 100644
index 18b692d..0000000
--- a/math-scala/src/main/scala/org/apache/mahout/visualization/mlpot.scala
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package org.apache.mahout.visualization
-
-
-trait mlpot  {
-
-}

http://git-wip-us.apache.org/repos/asf/mahout/blob/b0cede1e/math-scala/src/main/scala/org/apache/mahout/visualization/mplot2d.scala
----------------------------------------------------------------------
diff --git a/math-scala/src/main/scala/org/apache/mahout/visualization/mplot2d.scala b/math-scala/src/main/scala/org/apache/mahout/visualization/mplot2d.scala
deleted file mode 100644
index 20e2743..0000000
--- a/math-scala/src/main/scala/org/apache/mahout/visualization/mplot2d.scala
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.mahout.visualization
-
-import java.awt.{BorderLayout, Color}
-import java.io.File
-import javax.swing.JFrame
-
-import org.apache.mahout.math._
-import scalabindings._
-import RLikeOps._
-import drm._
-import smile.plot._
-
-import scala.collection.JavaConversions._
-
-
-/**
-  * Create a s scatter plot of a DRM by sampling a given percentage
-  * and plotting corresponding points of (drmXY(::,0),drmXY(::,2))
-  *
-  * @param drmXY an m x 2 Drm drm to plot
-  * @param samplePercent the percentage the drm to sample
-  * @tparam K
-  */
-class mplot2d[K](drmXY: DrmLike[K], samplePercent: Int = 1, setVisible: Boolean = true)  {
-     val drmSize = drmXY.checkpoint().numRows()
-     val sampleDec: Double = (samplePercent.toDouble / 100.toDouble)
-
-     val numSamples: Int = (drmSize * sampleDec).toInt
-     
-     val mPlotMatrix: Matrix = drmSampleKRows(drmXY, numSamples, false)
-     val arrays: Array[Array[Double]]  = Array.ofDim[Double](mPlotMatrix.numRows(), 2)
-     for (i <- 0 until mPlotMatrix.numRows()) {
-          arrays(i)(0) = mPlotMatrix(i, 0)
-          arrays(i)(1) = mPlotMatrix(i, 1)
-     }
-
-     val canvas: PlotCanvas = ScatterPlot.plot(arrays,Color.BLUE)
-     canvas.setTitle("2d Plot: " + samplePercent + " % sample of " + drmSize +" points")
-     canvas.setAxisLabels("x_0", "x_1")
-
-     val plotPanel: PlotPanel = new PlotPanel(canvas)
-
-     val plotFrame: JFrame = new JFrame("2d Plot")
-     plotFrame.setLayout(new BorderLayout())
-     plotFrame.add(plotPanel)
-     plotFrame.setSize(300,300)
-     if (setVisible) {
-          plotFrame.setVisible(true)
-          plotFrame.show()
-     }
-
-}

http://git-wip-us.apache.org/repos/asf/mahout/blob/b0cede1e/math-scala/src/main/scala/org/apache/mahout/visualization/mplot3d.scala
----------------------------------------------------------------------
diff --git a/math-scala/src/main/scala/org/apache/mahout/visualization/mplot3d.scala b/math-scala/src/main/scala/org/apache/mahout/visualization/mplot3d.scala
deleted file mode 100644
index 24e2415..0000000
--- a/math-scala/src/main/scala/org/apache/mahout/visualization/mplot3d.scala
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package org.apache.mahout.visualization
-
-
-class mplot3d {
-
-}

http://git-wip-us.apache.org/repos/asf/mahout/blob/b0cede1e/math-scala/src/main/scala/org/apache/mahout/visualization/package.scala
----------------------------------------------------------------------
diff --git a/math-scala/src/main/scala/org/apache/mahout/visualization/package.scala b/math-scala/src/main/scala/org/apache/mahout/visualization/package.scala
new file mode 100644
index 0000000..fcbadea
--- /dev/null
+++ b/math-scala/src/main/scala/org/apache/mahout/visualization/package.scala
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.mahout
+
+
+import org.apache.mahout.math._
+import org.apache.mahout.math.drm.{DrmLike, _}
+import org.apache.mahout.math.scalabindings.RLikeOps._
+import org.apache.mahout.math.scalabindings._
+
+
+package object visualization {
+
+  /**
+    * Roll a set of datapoints in a mx3 matrix into a 3D Array()()()
+    *
+    * @param mxXYZ Matrix of data points x_0 = mx(i,0), x_1 = mx(i,1), x_2 = mx(i,2)
+    * @return an Array[Array[Array[Double]]] 3d Array
+    */
+  def mxXYZ2array3d(mxXYZ: Matrix): Array[Array[Array[Double]]] = {
+
+    // number of datapoints
+    val m = mxXYZ.numRows()
+
+    // 3d array to return
+    val array3d: Array[Array[Array[Double]]] =  Array.ofDim[Double](m, m, 3)
+    // roll a set of 3d points in an m x 3 matrix into a m x m x 3 Array.
+    //TODO: FIX this:
+    for (i <- 0 until m) {
+      for (j <- 0 until m) {
+        for (k <- 0 until 3) {
+          array3d(i)(j)(k) = mxXYZ(i, k)
+        }
+      }
+    }
+    array3d
+  }
+
+  /**
+    * Syntatic sugar for MSurf class
+    * @param drmXYZ
+    * @param samplePercent
+    * @param setVisible
+    * @tparam K
+    * @return
+    */
+  def msurf[K](drmXYZ: DrmLike[K], samplePercent: Double = 1, setVisible: Boolean = true): MahoutPlot =
+    new MSurf[K](drmXYZ: DrmLike[K], samplePercent, setVisible)
+
+  /**
+    * Syntatic sugar for MPlot2d class
+    * @param drmXY
+    * @param samplePercent
+    * @param setVisible
+    * @tparam K
+    * @return
+    */
+  def mpot2d[K](drmXY: DrmLike[K], samplePercent: Double = 1, setVisible: Boolean = true): MahoutPlot =
+    new MPlot2d[K](drmXY: DrmLike[K], samplePercent, setVisible)
+
+  /**
+    * Syntatic sugar for MPlot3d class
+    * @param drmXYZ
+    * @param samplePercent
+    * @param setVisible
+    * @tparam K
+    * @return
+    */
+  def mplot3d[K](drmXYZ: DrmLike[K], samplePercent: Double = 1, setVisible: Boolean = true): MahoutPlot =
+    new MPlot3d[K](drmXYZ: DrmLike[K], samplePercent, setVisible)
+
+  /**
+    * Syntatic sugar for MGrid class
+    * @param drmXYZ
+    * @param samplePercent
+    * @param setVisible
+    * @tparam K
+    * @return
+    */
+  def mgrid[K](drmXYZ: DrmLike[K], samplePercent: Double = 1, setVisible: Boolean = true): MahoutPlot =
+    new MGrid[K](drmXYZ: DrmLike[K], samplePercent, setVisible)
+
+  /**
+    *
+    * @param drmX
+    * @param numBins
+    * @param samplePercent
+    * @param setVisible
+    * @tparam K
+    * @return
+    */
+  def mhisto[K](drmX: DrmLike[K], numBins: Int, samplePercent: Double = 1, setVisible: Boolean = true): MahoutPlot =
+    new MHisto[K](drmX: DrmLike[K], numBins, samplePercent, setVisible)
+
+  /**
+    *
+    * @param drmXY
+    * @param numBins
+    * @param samplePercent
+    * @param setVisible
+    * @tparam K
+    * @return
+    */
+  def mhisto3d[K](drmXY: DrmLike[K], numBins: Int, samplePercent: Double = 1, setVisible: Boolean = true): MahoutPlot =
+    new MHisto3d[K](drmXY: DrmLike[K], numBins, samplePercent, setVisible)
+
+
+}