cibotech / evilplot

A Scala combinator-based plotting library.
https://cibotech.github.io/evilplot
BSD 3-Clause "New" or "Revised" License
242 stars 25 forks source link

EvilPlot

Test Status Scala.js

EvilPlot is about combinators for graphics.

Documentation for EvilPlot is available here.

Getting Started

Add EvilPlot to your build with:

libraryDependencies += "io.github.cibotech" %% "evilplot" % "0.9.0" // Use %%% instead of %% if you're using ScalaJS

Take a look at the full getting started guide. EvilPlot is published for Scala 2.12 and Scala 2.13.

Table of Contents

Low-Level Drawing API

The low-level drawing API exists in the com.cibo.evilplot.geometry package. Drawing primitives extend the Drawable trait. Once constructed, these can then be rendered using a RenderContext (such as CanvasRenderContext, used for rendering to a JavaScript canvas or Graphics2DRenderContext, used for rendering to java.awt.Graphics2D).

Drawing primitives can be divided into three categories: drawing, positioning, and style. The following primitives for drawing are available:

The following primitives for positioning are available:

The following primitives for style are available:

The com.cibo.evilplot.geometry package object provides several convenience functions for creating and composing these primitives.

For Interaction events

Plot API

The plot API is in the com.cibo.evilplot.plot package. Using this API, one creates a plot using a plot constructor. Once a plot is constructed, it is possible to change properties and add components to the plot. The following plot constructors are available (though additional constructors can be added):

Multiple plots can be combined using the following plot constructors:

Plot components are available in the com.cibo.evilplot.plot.components package, though the com.cibo.evilplot.plot package object provides implicits on the Plot object itself to make them easier to use.

Annotations

Annotations are text (or other Drawables) placed on top of the plot area. The X and Y coordinate parameters provide the relative position of the annotation (in the range 0 to 1).

Axes

The following methods (from the package object) are available for adjusting axes. These take arguments to alter the type of axis.

Bounds

By default, the bounds of the plot area are determined by the data and plot constructor. However, it's possible to alter the bounds explicitly:

Grids

Labels

Labels for a single plot:

Labels for faceted plots:

Legends

Lines

Padding

Add padding around a plot area. This is mostly used for lining up plot areas of multiple plots in facets.

Custom Plots and Plot Components

Custom plots can be constructed by creating new plot components, plot renderers, and/or plot element renderers.

Plot Components

A plot component is an object that goes around a plot area (such as a label or axis), in front of it (such as a trend line), or behind it (such as a background). Custom plot components can be implemented by extending com.cibo.evilplot.plot.comonents.PlotComponent (or com.cibo.evilplot.plot.components.FacetedPlotComponent for components that need to render differently for each facet).

To add a custom component to a plot (or any component), use either the :+ or +: method on Plot, which will return an updated plot with the component. plot :+ component will insert the component furthest away from the plot area and component +: plot will insert the component closest to the plot area.

Plot Renderers

Custom plot renderers are created by extending com.cibo.evilplot.plot.renderers.PlotRenderer. Instances of these can then be used as an argument to Plot to create custom plots.

Plot Element Renderers

A plot element is an instance of com.cibo.evilplot.plot.renderers.PlotElementRenderer. These are used by PlotRenderer instances to render elements of a plot. For example, the PlotRenderer used for ScatterPlot uses a PointRenderer to render points. It is not necessary that a PlotRender use PlotElementRenderers, but doing so allows them to share common code.

The following PlotElementRenderers are provided:

Working on this Project

One-time setup: Install PhantomJS: On macOS, this is available from Homebrew: brew install phantomjs

To run the demo:

  1. open sbt console
  2. compile, then run fastOptJS listening for changes
    $ sbt
    > compile
    > ~ fastOptJS
  3. Open ./index.html in your browser

Running the unit tests requires PhantomJS. Unit tests must be run from sbt, not from within IntelliJ.