kandy 0.8.0-RC1 Help

Overview

What is Kandy?

Kandy preview

Kandy is an open-source data visualization library designed for Kotlin. It adopts a modern approach to data visualization, offering an idiomatic and flexible DSL. This DSL, integrating seamlessly with Kotlin's type safety, facilitates quick graph creation with fewer exceptions. Kandy also supports various popular engines, enhancing its versatility and performance for efficient chart-building.

Kandy utilizes the Lets-Plot library, which allows it to display in interactive notebooks, saved as standalone HTML files, and export in formats like PNG, SVG, and JPEG. This capability enables the use of Kandy in Kotlin projects.

Alongside kandy-lets-plot, there is an ongoing development of kandy-echarts, an experimental module utilizing echarts.js for rendering.

Features

  • Hierarchical DSL — Provides an intuitive and straightforward approach to constructing graphs.

  • Support for Kotlin notebooks — Facilitates working with Kandy on platforms like IntelliJ IDEA with the Kotlin Notebook logo Kotlin Notebook plugin, Datalore logo Datalore, and Jupyter Notebook logo Jupyter Notebook.

  • Swing rendering in Kotlin notebook — Available in IntelliJ IDEA.

  • Interactive tooltips — Offers dynamic tooltips during rendering in both Swing and HTML.

  • Kotlin collections support — Seamlessly works with Kotlin’s standard collections as data sources.

  • Kotlin DataFrame support — Integrates with Kotlin DataFrame, utilizing generated extension properties and hierarchical data for plot construction.

  • Type and null safety — Ensures type safety and Kotlin null safety.

DSL and Syntax

Kandy features a common API that facilitates the Plot Intermediate Representation (IR). Both kandy-lets-plot and kandy-echarts are developed to be compatible with this API.

Kandy's DSL offers an intuitive, hierarchical approach to creating data visualizations. Its flexible yet structured design is suitable for both beginners and experienced users. Here's a simplified overview of the Kandy DSL structure:

Kandy DSL Schema
  • Plot — the plot block forms the foundation of every visualization in Kandy, setting the stage for all other elements.

  • Data Manipulation — this block plays a key role in transforming the initial data utilized in plot.

    • Grouping — this method groups data according to specified keys, allowing for organized and structured visualization based on distinct data segments.

    • Statistical — this set of methods applies statistical operations to the data, producing new datasets derived from these computations.

  • Layout — this part deals with the graph's design, including elements like titles, subtitles, size, and thematic elements.

  • Layers — it introduces different types of visual elements, such as lines, points, bars, etc.

  • Aesthetic Mappings / Settings — This feature enables mapping data attributes to visual properties like color, shape, and size, offering extensive customization options.

  • Scale Specification — this aspect is crucial for translating data values into appropriate visual scales on the graph, including settings for color gradients, size ranges, and positioning.

Kandy's DSL offers a straightforward path for creating visualizations, combining clarity and aesthetic appeal. Its design focuses on ease of use, enabling the efficient crafting of complex charts.

Syntax

Kandy's API follows the structure outlined below:

  • Basic plotting with initial data:

plot(data) { // layer (geoms) line[bars | points | area | pie | ...] { ... // aesthetics } line[bars | points | area | pie | ...] { ... } ... }
  • Transforming data into plotting context:

plot(data) { // data manipulation groupBy(Strings| Columns) [statBin|statBoxplot|statDensity|...] { line[bars | points | area | pie | ...] { ... } line[bars | points | area | pie | ...] { ... } ... } }
  • Combining original and transformed data:

plot(data) { groupBy(Strings| Columns) [statBin|statBoxplot|statDensity|...] { line[bars | points | area | pie | ...] { ... } line[bars | points | area | pie | ...] { ... } ... } line[bars | points | area | pie | ...] { ... } line[bars | points | area | pie | ...] { ... } ... }
  • Modifying plot layout:

plot(data) { line[bars | points | area | pie | ...] { ... } ... layout { title subtitle ... theme { ... } legend { ... } grid { ... } ... } }

For mappings and settings, Kandy uses the following approach:

  • Mapping to a Collection or Column is done through function calls:

x("time") // map to the column `time` y(listOf(1, 2, 3)) // map to a list color(type) // map to the type column
  • Settings for positional aesthetics:

x.constant(3) yIntercept.constant(5.7)
  • Settings for other aesthetics:

color = Color.RED size = 4.5 type = LineType.DASHED

Now that we've covered Kandy's DSL components and structure, let's see how they work together in a practical example. This demonstrates the DSL's capability in crafting a visualization with ease and flexibility:

val weatherData = dataFrameOf( "time" to listOf(0, 1, 2, 4, 5, 7, 8, 9), "temperature" to listOf(12.0, 14.2, 15.1, 15.9, 17.9, 15.6, 14.2, 24.3), "humidity" to listOf(0.5, 0.32, 0.11, 0.89, 0.68, 0.57, 0.56, 0.5) ) weatherData.plot { // Begin plotting x(time) // Set x-axis with time data y(temperature) { // Set y-axis with temperature data // Define scale for temperature (y-axis) scale = continuous(0.0..25.5) } bars { // Add a bar layer fillColor(humidity) { // Customizing bar colors based on humidity // Setting the color range scale = continuous(range = Color.YELLOW..Color.RED) } borderLine.width = 0.0 // Define border line width } line { width = 3.0 // Set line width color = Color.hex("#6e5596") // Define line color type = LineType.DOTDASH // Specify the line type } layout { // Set plot layout title = "Simple plot with kandy-lets-plot" // Add title // Add caption caption = "See `examples` section for more\n complicated and interesting examples!" size = 700 to 450 // Plot dimension settings } }
val weatherData = mapOf( "time" to listOf(0, 1, 2, 4, 5, 7, 8, 9), "temperature" to listOf(12.0, 14.2, 15.1, 15.9, 17.9, 15.6, 14.2, 24.3), "humidity" to listOf(0.5, 0.32, 0.11, 0.89, 0.68, 0.57, 0.56, 0.5) ) // Combine data into a map plot(weatherData) { // Begin plotting x("time") // Set x-axis with time data y("temperature") { // Set y-axis with temperature data // Define scale for temperature (y-axis) scale = continuous(0.0..25.5) } bars { // Add a bar layer fillColor("humidity") { // Customizing bar colors based on humidity // Setting the color range scale = continuous(range = Color.YELLOW..Color.RED) } borderLine.width = 0.0 // Define border line width } line { width = 3.0 // Set line width color = Color.hex("#6e5596") // Define line color type = LineType.DOTDASH // Specify the line type } layout { // Set plot layout title = "Simple plot with kandy-lets-plot" // Add title // Add caption caption = "See `examples` section for more\n complicated and interesting examples!" size = 700 to 450 // Plot dimension settings } }
Simple plot with Kandy

More examples of working with the library can be found here.

Last modified: 15 December 2023