Yet another library for integration between Plotly and Scala.
tmmScalaPlotlyVersion = 0.0.2 libraryDependencies += "au.id.tmm.tmm-scala-plotly" %% "tmm-scala-plotly-core" % tmmScalaPlotlyVersion
There are already at least two other libraries that provide Scala integration for Plotly:
facultyai/scala-plotly-clientis an older library that is documented on the Plotly website. It does not appear to be under active development.
alexarchambault/plotly-scala, which is a modern and mature offering.
My advice would be that if you are looking for a library to use Plotly from Scala, you should use
It is more mature and better tested than this library, and I've had a lot of success with it.
This library has a couple of key philosophical differences with
alexarchambault/plotly-scala, which is why I decided
to write it:
- Self-documenting: This library makes extensive use of value classes and algebraic data types to attempt to clarify the meaning of fields within the Plotly API. Implicit conversions are opt-in and are intended only for ease-of-use (see below).
- Incorrect: This library does not (yet) use the power of the Scala type system to ensure valid use of Plotly. For
example, you can provide
- No ScalaJS support: I don't use ScalaJS, so I haven't provided support for it.
- Circe as a first-class citizen: This project uses
circeto encode the model to Json. The
circeintegrations are deliberately exposed by the main library to give clients as much flexibility as possible when encoding.
Note that I've hand-written this interface over Plotly but have done almost no thorough testing. Many of the corners of this library are unlikely to have seen any use. Caveat emptor.
To draw a pie chart:
import au.id.tmm.plotly._ import au.id.tmm.plotly.model._ import au.id.tmm.plotly.model.utilities._ val (labels, values, colours) = List( ("Coalition", 5_906_875, Color("blue")), ("Labor", 4_752_160, Color("red")), ("Greens", 1_482_923, Color("green")), ("Other", 2_111_435, Color("grey")), ).unzip3 val plot = Plot( data = List( Trace( `type` = OptArg.Of(Trace.Type.Pie), labels = OptArg.Of(DataArray.OfStrings(labels)), values = OptArg.Of(DataArray.OfInts(values)), marker = OptArg.Of( PlotMarker( colors = OptArg.Of(colours), ), ), ), ), layout = OptArg.Of( Layout( title = OptArg.Of( Layout.Title( text = OptArg.Of("2019 primary votes"), ), ), width = OptArg.Of(300d), height = OptArg.Of(300d), ), ), ) Plotting.openInBrowser(plot)
Implicit conversions for ergonomics
In the above you should note that we make use of types like
DataArray. These allow us to have explicit
and type-safe representations of optional parameters and the different types of data array respectively. Using these
everywhere gets tiring, so we can import
au.id.tmm.plotly.syntax._ to make things a little less verbose
while retaining type safety. With this import, the above becomes:
import au.id.tmm.plotly._ import au.id.tmm.plotly.model._ import au.id.tmm.plotly.syntax._ val (labels, values, colours) = List( ("Coalition", 5_906_875, Color("blue")), ("Labor", 4_752_160, Color("red")), ("Greens", 1_482_923, Color("green")), ("Other", 2_111_435, Color("grey")), ).unzip3 val plot = Plot( data = List( Trace( `type` = Trace.Type.Pie, labels = labels, values = values, marker = PlotMarker(colors = colours), ), ), layout = Layout( title = Layout.Title(text = "2019 primary votes"), width = 300, height = 300, ), ) Plotting.openInBrowser(plot)
Dedicated trace interfaces
As discussed in the Rationale section above, the
of the features of Plotly, it also allows us to provide useless or invalid parameters. For example, we could provide the
z co-ordinates for a two-dimensional scatter plot.
As a partial solution to this, the project includes some dedicated constructors for traces based on the trace type.
These are available in the
package. For example, an interface is provided for sunburst plots and is demoed in the examples project.