Need help with scalaplot?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

sameersingh
124 Stars 18 Forks BSD 2-Clause "Simplified" License 94 Commits 10 Opened issues

Description

Library to plot graphs using a scala frontend, and various backends such as gnuplot, jfreegraph, matplotlib, etc.

Services available

!
?

Need anything else?

Contributors list

# 376,308
Shell
Scala
CSS
86 commits
# 118,759
excel
data-fr...
dtw
scalajs
3 commits

Build Status

scalaplot

This is a library for quick and easy plotting of simple plots (such as XY line plots, scatter plots) and supports outputs using different engines (currently Gnuplot and JFreeGraph).

Note: The project is still in beta. If you just need a clean way to interface Java with gnuplot, see gnujavaplot.

Requirements

  • maven
  • for gnuplot: gnuplot 4.6 with pdf support (on the mac+homebrew,
    brew install pdflib-lite gnuplot
    )

Installation

Maven dependency

The easiest (and recommended) way to use scalaplot is as a maven dependency. Insert the following in your

pom
file:
  ...
  
    org.sameersingh.scalaplot
    scalaplot
    0.0.4
  
  ...

SBT dependency

Or to use scalaplot with SBT, add the following dependency to your

build.sbt
file:
libraryDependencies += "org.sameersingh.scalaplot" % "scalaplot" % "0.0.4"

Creating Charts

Currently, the library supports line and point (scatter) charts. Let's start with a simple, complete example:

import org.sameersingh.scalaplot.Implicits._

val x = 0.0 until 2.0 * math.Pi by 0.1 output(PNG("docs/img/", "test"), xyChart(x ->(math.sin(), math.cos())))

which produces

Example scalaplot

while

output(ASCII, xyChart(x ->(math.sin(_), math.cos(_))))

produces

    1 BBBB------+--AAAAAA-+---------+--------+---------+---------BBB------++
      +   BB    +AA      AAA        +        +         +       BB+         +
  0.8 ++    BB AA           AA                               BB           ++
      |      AA               A                            BB              |
  0.6 ++    A  BB              A                          B               ++
      |    A     B              AA                       B                 |
  0.4 ++  A       B               A                     B                 ++
      |  A         B               A                   B                   |
  0.2 ++A           B               A                 B                   ++
    0 AA             B               A               B                    ++
      |               B               A             B              A       |
 -0.2 ++               B               A           B              A       ++
      |                 B               A        BB              A         |
 -0.4 ++                 BB              A      B               A         ++
      |                    B             A     B               A           |
 -0.6 ++                    B             AA  B              AA           ++
      |                      B              AB              A              |
 -0.8 ++                      BB           B AA           AA              ++
      +         +         +     BBB +    BB  + AA      +AA       +         +
   -1 ++--------+---------+--------BBBBBB----+---AAAAAAA---------+--------++
      0         1         2         3        4         5         6         7

As another example to introduce a bit of customization:

import org.sameersingh.scalaplot.Implicits._

val x = 0.0 until 10.0 by 0.01 val rnd = new scala.util.Random(0)

output(PNG("docs/img/", "scatter"), xyChart( x -> Seq(Y(x, style = XYPlotStyle.Lines), Y(x.map(_ + rnd.nextDouble - 0.5), style = XYPlotStyle.Dots))))

produces

Example scatter

Output Formats

The library, of course, supports different output formats. Most of these also produce an accompanying Gnuplot source file, allowing archival and further customization if needed. The current list of formats are:

output(ASCII, xyChart(...)) // returns the string as above
output(SVG, xyChart(...)) // returns the SVG text, which can be embedded in html or saved as a SVG file
output(PDF(dir, name), xyChart(...)) // produces dir/name.gpl as the gnuplot source, and attempts dir/name.pdf
output(PNG(dir, name), xyChart(...)) // produces dir/name.gpl as the gnuplot source, and attempts dir/name.png
output(GUI, xyChart(...)) // opens a window with the plot, which can be modified/exported/resized/etc.

Note that scalaplot calls the

gnuplot
command to render the image in
dir/name.EXT
, but in case it fails, do the following:
$ cd dir/
$ gnuplot name.gpl

which will create

name.EXT
, where
EXT
is one of
PDF
or
PNG
.

XYChart

The

xyChart
function is the main entry point for creating charts. The first argument of plot requires a
XYData
object, that we will describe in the next section. The rest of the arguments customize the aspects of the chart that are not data-specific.
val d: XYData = ...
xyChart(d)
xyChart(d, "Chart Title!")
xyChart(d, x = Axis(label = "Age"), y = Axis(log = true))

Here are the relevant definitions and default parameters that you can override:

def xyChart(data: XYData, title: String = "",
            x: NumericAxis = new NumericAxis,
            y: NumericAxis = new NumericAxis,
            pointSize: Option[Double] = None,
            legendPosX: LegendPosX.Type = LegendPosX.Right,
            legendPosY: LegendPosY.Type = LegendPosY.Center,
            showLegend: Boolean = false,
            monochrome: Boolean = false,
            size: Option[(Double, Double)] = None): XYChart
def Axis(label: String = "",
         backward: Boolean = false,
         log: Boolean = false,
         range: Option[(Double, Double)] = None): NumericAxis

Data

The data is the first argument of the plot function, and can be specified in many different ways, depending on the format your data is available in. Primarily,

XYData
consists of multiple sequences of
(Double,Double)
pairs, where each sequence forms a single series (line in line plots). Here are some ways of data can be specified.

If you have a single

x
sequence and multiple
y
sequences, you can use:
// data
val x = (1 until 100).map(_.toDouble)
val y1 = (1 until 100).map(j => math.pow(j, 1))
val y2 = (1 until 100).map(j => math.pow(j, 2))
val y3 = (1 until 100).map(j => math.pow(j, 3))

xyChart(x ->(y1, y2, y3)) xyChart(x ->(math.sin(), math.cos())) // inline definition xyChart(x -> Seq(Y(y1, "1"), Y(y2, "2"), Y(y3, "3"))) // with labels and other possible customizations xyChart(x -> Seq(Yf(math.sin, "sin"), Yf(math.cos, color = Color.Blue), Yf(math.tan, lw = 3.0))) // Yf for functions

where each series can be fully customized using the following:

def Y(yp: Seq[Double],
      label: String = "Label",
      style: XYPlotStyle.Type = XYPlotStyle.LinesPoints,
      color: Option[Color.Type] = None,
      ps: Option[Double] = None,
      pt: Option[PointType.Type] = None,
      lw: Option[Double] = None,
      lt: Option[LineType.Type] = None,
      every: Option[Int] = None)
def Yf(f: Double => Double,
       label: String = "Label",
       style: XYPlotStyle.Type = XYPlotStyle.LinesPoints,
       color: Option[Color.Type] = None,
       ps: Option[Double] = None,
       pt: Option[PointType.Type] = None,
       lw: Option[Double] = None,
       lt: Option[LineType.Type] = None,
       every: Option[Int] = None)

If you have sequences of

(x,y)
pairs as your data, or if you want to use different
x
for each series:
xyChart(List(x -> Y(y1), x -> Y(y2)))
xyChart(List(x -> Y(y1, "1"), x -> Y(y2, color = Color.Blue)))

val xy1 = x zip y1 val xy2 = x zip y2 xyChart(List(XY(xy1), XY(xy2))) xyChart(List(XY(xy1, "1"), XY(xy2, "2")))

where the customization is similar to above:

def XY(points: Seq[(Double, Double)],
       label: String = "Label",
       style: XYPlotStyle.Type = XYPlotStyle.LinesPoints,
       color: Option[Color.Type] = None,
       ps: Option[Double] = None,
       pt: Option[PointType.Type] = None,
       lw: Option[Double] = None,
       lt: Option[LineType.Type] = None,
       every: Option[Int] = None)

Other Implicits

Scalaplot also supports a number of other implicits to make things easier to use.

val d: XYData = x ->(y1, y2, y3)
val c: XYChart = d // automatic conversion from data to chart

// series val s1: XYSeries = x -> y1 val s2: XYSeries = x zip y2 val f1 = math.sin(_) val s1f: XYSeries = x -> f1 val s2f: XYSeries = x -> Yf(math.sin)

// series to data val d1: XYData = s1 val d2: XYData = Seq(s1, s2) val d2l: XYData = s1 :: s2 :: List()

Explicit Data Structures

For even further customization of the charts, you will need to dive into the API instead of relying on the above implicits.

XY Line Charts

First step is to get your data into

Seq[Double]
.
val x = (1 until 100).map(_.toDouble)
val y = x.map(i => i*i)

Create a dataset that represents these sequences.

val series = new MemXYSeries(x, y, "Square")
val data = new XYData(series)

You can add more series too.

data += new MemXYSeries(x, x.map(i => i*i*i), "Cube")

Let's create the chart.

val chart = new XYChart("Powers!", data)
chart.showLegend = true

Rendering Charts

Even though multiple backends are being supported to render the charts, gnuplot is the most actively developed and supported since it allows post plotting customizations (editing the script files), may possible output formats, and ease of use.

Gnuplot

Generates gnuplot scripts that will need to be run to actually generate the images.

val plotter = new GnuplotPlotter(chart)
plotter.writeToPdf("dir/", "name")

The output looks like

Example gnuplot output

JFreegraph

JFreegraph can also be called similarly to produce pdf plots (use

JFGraphPlotter
). However, it also supports a
gui()
option for when you just want to see the graph.
val plotter = new JFGraphPlotter(chart)
plotter.gui()

produces

Example jfreegraph output

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.