Data visualization is an integral part of data science. Visualization needs fall into two broad categories: during the development and validation of new models and, at the end of the pipeline, to distill meaning from the data and the models to provide insight to external stakeholders.
The two types of visualizations are quite different. At the data exploration and model development stage, the most important feature of a visualization library is its ease of use. It should take as few steps as possible to go from having data as arrays of numbers (or CSVs or in a database) to having data displayed on a screen. The lifetime of graphs is also quite short: once the data scientist has learned all he can from the graph or visualization, it is normally discarded. By contrast, when developing visualization widgets for external stakeholders, one is willing to tolerate increased development time for greater flexibility. The visualizations can have significant lifetime, especially if the underlying data changes over time.
The tool of choice in Scala for the first type of visualization is breeze-viz. When developing visualizations for external stakeholders, web-based visualizations (such as D3) and Tableau tend to be favored.
In this chapter, we will explore breeze-viz. In Chapter 14, Visualization with D3 and the Play Framework, we will learn how to build Scala backends for JavaScript visualizations.
Breeze-viz is (no points for guessing) Breeze's visualization library. It wraps JFreeChart, a very popular Java charting library. Breeze-viz is still very experimental. In particular, it is much less feature-rich than matplotlib in Python, or R or MATLAB. Nevertheless, breeze-viz allows access to the underlying JFreeChart objects so one can always fall back to editing these objects directly. The syntax for breeze-viz is inspired by MATLAB and matplotlib.
Let's get started. We will work in the Scala console, but a program similar to this example is available in BreezeDemo.scala
in the examples corresponding to this chapter. Create a build.sbt
file with the following lines:
scalaVersion := "2.11.7" libraryDependencies ++= Seq( "org.scalanlp" %% "breeze" % "0.11.2", "org.scalanlp" %% "breeze-viz" % "0.11.2", "org.scalanlp" %% "breeze-natives" % "0.11.2" )
Start an sbt
console:
$ sbt console scala> import breeze.linalg._ import breeze.linalg._ scala> import breeze.plot._ import breeze.plot._ scala> import breeze.numerics._ import breeze.numerics._
Let's start by plotting a sigmoid curve, . We will first generate the data using Breeze. Recall that the
linspace
method creates a vector of doubles, uniformly distributed between two values:
scala> val x = linspace(-4.0, 4.0, 200) x: DenseVector[Double] = DenseVector(-4.0, -3.959798... scala> val fx = sigmoid(x) fx: DenseVector[Double] = DenseVector(0.0179862099620915,...
We now have the data ready for plotting. The first step is to create a figure:
scala> val fig = Figure() fig: breeze.plot.Figure = breeze.plot.Figure@37e36de9
This creates an empty Java Swing window (which may appear on your taskbar or equivalent). A figure can contain one or more plots. Let's add a plot to our figure:
scala> val plt = fig.subplot(0) plt: breeze.plot.Plot = breeze.plot.Plot@171c2840
For now, let's ignore the 0
passed as argument to .subplot
. We can add data points to our plot
:
scala> plt += plot(x, fx) breeze.plot.Plot = breeze.plot.Plot@63d6a0f8
The plot
function takes two arguments, corresponding to the x and y values of the data series to be plotted. To view the changes, you need to refresh the figure:
scala> fig.refresh()
Look at the Swing window now. You should see a beautiful sigmoid, similar to the one below. Right-clicking on the window lets you interact with the plot and save the image as a PNG:
You can also save the image programmatically as follows:
scala> fig.saveas("sigmoid.png")
Breeze-viz currently only supports exporting to PNG.