{"id":21187662,"url":"https://github.com/holgerbrandl/kravis","last_synced_at":"2026-03-03T00:09:21.204Z","repository":{"id":41086579,"uuid":"110351220","full_name":"holgerbrandl/kravis","owner":"holgerbrandl","description":"A {K}otlin g{ra}mmar for data {vis}ualization","archived":false,"fork":false,"pushed_at":"2024-12-13T09:17:30.000Z","size":25095,"stargazers_count":184,"open_issues_count":10,"forks_count":12,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-28T09:06:34.580Z","etag":null,"topics":["data-visualization","datascience","ggplot2","kotlin","krangl"],"latest_commit_sha":null,"homepage":"","language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/holgerbrandl.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-11-11T14:19:57.000Z","updated_at":"2025-02-10T02:24:57.000Z","dependencies_parsed_at":"2023-12-25T08:47:09.339Z","dependency_job_id":"37d6698a-3a1e-4905-953d-bc5b6a8e2edb","html_url":"https://github.com/holgerbrandl/kravis","commit_stats":{"total_commits":219,"total_committers":3,"mean_commits":73.0,"dds":"0.21461187214611877","last_synced_commit":"14bb0a15a1f48451a79c6c52e511150521a953e6"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/holgerbrandl%2Fkravis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/holgerbrandl%2Fkravis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/holgerbrandl%2Fkravis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/holgerbrandl%2Fkravis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/holgerbrandl","download_url":"https://codeload.github.com/holgerbrandl/kravis/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247157108,"owners_count":20893215,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["data-visualization","datascience","ggplot2","kotlin","krangl"],"created_at":"2024-11-20T18:39:45.103Z","updated_at":"2026-03-03T00:09:21.195Z","avatar_url":"https://github.com/holgerbrandl.png","language":"Jupyter Notebook","funding_links":[],"categories":["数据科学"],"sub_categories":[],"readme":"# `kravis` - A {k}otlin {gra}mmar for data {vis}ualization\n\n [ ![Download](https://img.shields.io/badge/Maven%20Central-1.1-orange) ](https://mvnrepository.com/artifact/com.github.holgerbrandl/kravis)\n\n[//]: # ([![Build Status]\u0026#40;https://travis-ci.org/holgerbrandl/kravis.svg?branch=master\u0026#41;]\u0026#40;https://travis-ci.org/holgerbrandl/kravis\u0026#41;)\n\nVisualizing tabular and relational data is the core of data-science. `kravis` implements a grammar to create a wide range of plots using a standardized set of verbs.\n\n\nThe grammar implemented by `kravis` is inspired from [`ggplot2`](http://ggplot2.org/). In fact, all it provides is a more typesafe wrapper around it.  Internally, `ggplot2` is used as rendering engine. The API of `kravis` is highly similar to allow even reusing their excellent [cheatsheet](https://www.rstudio.com/resources/cheatsheets/#ggplot2).\n\nR is required to use `ggplot`. However, `kravis` works with various integration backend ranging such as docker or remote webservices.\n\n\n[TOC]: # \" \"\n\n- [`kravis` - A {k}otlin {gra}mmar for data {vis}ualization](#kravis---a-kotlin-grammar-for-data-visualization)\n  - [Jupyter](#jupyter)\n  - [Setup](#setup)\n  - [First Example](#first-example)\n  - [The Grammar of Graphics](#the-grammar-of-graphics)\n  - [Module Architecture](#module-architecture)\n  - [Supported Data Input Formats](#supported-data-input-formats)\n    - [Iterators](#iterators)\n    - [Tables](#tables)\n  - [Output Devices](#output-devices)\n  - [Rendering](#rendering)\n    - [(1) Local R](#1-local-r)\n    - [(2) Dockerized R.](#2-dockerized-r)\n    - [(3) Rserve](#3-rserve)\n  - [Plot Immutability](#plot-immutability)\n  - [API Coverage](#api-coverage)\n    - [How to use missing API elements from ggplot2?](#how-to-use-missing-api-elements-from-ggplot2)\n  - [References](#references)\n  - [Acknowledgements](#acknowledgements)\n\n\n---\n\n**This is an experimental API and is subject to breaking changes until a first major release**\n\n---\n\n## Jupyter\n\nAn easy way to get started with `kravis` is with jupyter, you simply need to install the [kotlin-jupyter](https://github.com/Kotlin/kotlin-jupyter) kernel.\n\nSee [here](https://github.com/holgerbrandl/kalasim/blob/master/simulations/notebooks/kravis_test.ipynb) for a notebook example.\n\n\n## Setup\n\n\nAdd the following artifact to your `gradle.build`\n\n```\ncompile \"com.github.holgerbrandl:kravis:1.0.3\"\n```\n\nYou can also use [JitPack with Maven or Gradle](https://jitpack.io/#holgerbrandl/kravis/-SNAPSHOT) to build the latest snapshot as a dependency in your project.\n\n```groovy\nrepositories {\n    maven { url 'https://jitpack.io' }\n}\ndependencies {\n        compile 'com.github.holgerbrandl:kravis:-SNAPSHOT'\n}\n```\n\nTo build and install it into your local maven cache, simply clone the repo and run\n```bash\n./gradlew install\n```\n\n\n## First Example\n\nLet's start by analyzing mamalian [sleep patterns](https://ggplot2.tidyverse.org/reference/msleep.html)\n```kotlin\nimport kravis.*\nimport org.jetbrains.kotlinx.dataframe.datasets.sleepData\n\n\nsleepData\n    .add(\"rem_proportion\") { \"sleep_rem\"\u003cDouble\u003e() / \"sleep_total\"\u003cDouble\u003e() }\n    // Analyze correlation\n    .plot(x = \"sleep_total\", y = \"rem_proportion\", color = \"vore\", size = \"brainwt\")\n        .geomPoint(alpha = 0.7)\n        .guides(size = LegendType.none)\n        .title(\"Correlation between dream and total sleep time\")\n```\n\n\n![](.README_images/sleep_correlation.png)\n\nFind more examples in our gallery **{comding soon}**.\n\n\n## The Grammar of Graphics\n\n`ggplot2` and thus `kravis` implement a **grammar for graphics** to build plots with\n\n\u003e `aesthetics` + `layers`  + `coordinates system` + `transformations` + ` facets`\n\nWhich reads as `map variables from data space to visual space` + `add one or more layers`  + `configure the coordinates system` + ` optionally apply statistical transformations` + `optionally add facets`. That's the way!\n\n\n## Module Architecture\n\n![](.README_images/module_architecture.jpg)\n\n## Supported Data Input Formats\n\n### Iterators\n\nEvery `Iterable\u003cT\u003e` is a valid data source for `kravis`, which allows to create plots using a type-save builder DSL. Essentially we first digest it into a table and use it as data source for visualization. Here's an example:\n\n```kotlin\n//  deparse records using property references (which will allow to infer variable names via reflection)\nval basePlot = sleepPatterns.plot(\n        x = SleepPattern::sleep_rem,\n        y = SleepPattern::sleep_total,\n        color = SleepPattern::vore,\n        size = SleepPattern::brainwt\n    )\n            \nbasePlot\n    .geomPoint()\n    .title(\"Correlation of total sleep and and rem sleep by food preference\")\n    .show()\n```\n\n![](.README_images/scatter_example.png)\n\nIn the previous example  we have used property references. `kravis` also supports an extractor lambda function syntax, which allow for on-the-fly data transformations when deparsing an `Iterable\u003cT\u003e`. The ([not yet](https://github.com/holgerbrandl/kravis/issues/14) solved) disadvantage is that we need to assign axis labels manually\n\n```kotlin\nsleepPatterns\n    .plot(x = { sleep_total/60 })\n    .geomHistogram()\n    .xLabel(\"sleep[h]\")\n```\n![](.README_images/extractor_histogram.png)\n\nAnd here's another example using a custom [data class](https://kotlinlang.org/docs/reference/data-classes.html):\n\n\n```kotlin\nenum class Gender { male, female }\n\ndata class Person(val name: String, val gender: Gender, val heightCm: Int, val weightKg: Double)\n\n// define some persons\nval persons = listOf(\n    Person(\"Max\", Gender.male, 192, 80.3),\n    Person(\"Anna\", Gender.female, 162, 56.3),\n    Person(\"Maria\", Gender.female, 172, 66.3)\n)\n\n// visualize sizes by gender\npersons.plot(x = {name}, y = { weightKg }, fill = { gender.toString() })\n    .geomCol()\n    .xLabel(\"height [m]\")\n    .yLabel(\"weight [kg]\")\n    .title(\"Body Size Distribution\")\n```\n\n![](.README_images/persons.png)\n\n### Tables\n\n`kravis` can handle any kind of tabular data via [data-frames](https://kotlin.github.io/dataframe)\n\n```kotlin\nimport kravis.*\nimport org.jetbrains.kotlinx.dataframe.datasets.irisData\n\nirisData.plot(x=\"Species\" , y=\"Petal.Length\" )\n    .geomBoxplot()\n    .geomPoint(position = PositionJitter(width = 0.1), alpha = 0.3)\n    .title(\"Petal Length by Species\")\n```\n\n![](.README_images/boxplot.png)\n\n\n## Output Devices\n\n\n`kravis` auto-detects the environment, and will try to guess the most reasonable output device to show your plots. The following output devices are available.\n\n1. A swing graphics device for rendering when running in interactive mode.\n1. A javaFX  graphics device for rendering when running in interactive mode.\n3. It can render directly into files\n4. will render directly into jupyter notebooks.\n\nBy default `kravis` will render as `png` on all devices, but it also supports vector rendering using `svg` as output format.\n\n\nThe preferred output can be configured using the `SessionPrefs` object\n\n```kotlin\nSessionPrefs.OUTPUT_DEVICE = SwingPlottingDevice()\n```\n\n## Rendering\n\nCurrently `kravis` provided 3 different options to bind an R engine which is required to render plots.\n\n### (1) Local R\n\nThis is the default mode which can be configured by using\n\n```kotlin\nSessionPrefs.RENDER_BACKEND = LocalR()\n```\n\n### (2) Dockerized R.\n\n\n```kotlin\nSessionPrefs.RENDER_BACKEND = Docker()\n```\n\nThis will pull and use by default the container [`rocker/tidyverse:3.5.1`](https://hub.docker.com/r/rocker/tidyverse/), but can be configured to use more custom images as needed.\n\n### (3) Rserve\n\nAn (optionally) remote backend based using [Rserve](https://www.rforge.net/Rserve/)\n\nSimply install the corresponding R package and start the daemon with\n\n```bash\nR -e \"install.packages('Rserve',,'http://rforge.net/',type='source')\"\nR CMD Rserve\n```\n\nFor configuration details see https://www.rforge.net/Rserve/doc.html\n\nAlternatively, in case you don't have or want a local R installation, you can also run it dockerized locally or remotly with\n```\n# docker run -p \u003cpublic_port\u003e:\u003cprivate_port\u003e -d \u003cimage\u003e  \ndocker run -dp 6311:6311 holgerbrandl/kravis_rserve \n```\nSee [Dockerfile](misc/docker/kravis_core/Dockerfile) for the spec of this image.\n\nTo use the Rserve backend, configure the kravis `SessionPrefs` accordingly by pointing to the correct host and port.\n```kotlin\nSessionPrefs.RENDER_BACKEND = RserveEngine(host=\"localhost\", port=6302)\n```\n\n## Plot Immutability\n\nPlots are -- similar to [`dataframe`](https://kotlin.github.io/dataframe) data-frames -- immutable.\n\n```kotlin\nval basePlot = mpgData.plot(\"displ\" to x, \"hwy\" to y).geomPoint()\n\n// create one version with adjusted axis text size\nbasePlot.theme(axisText = ElementText(size = 20.0, color = RColor.red))\n\n// create another version with unchanged axis labels but using a log scale instead\nbasePlot.scaleXLog10()\n\n```\n\n## API Coverage\n\nCurrently we just map a subset of the `ggplot2` API.\n\n![](docs/data-visualization-2.1_p1.jpg)\n![](docs/data-visualization-2.1_p2.jpg)\n\n* Checks - implemented already\n* Crosses - Planned but not yet done\n\nFeel welcome to submit a ticket or PR if some important usecase is missing.\n\n\n### How to use missing API elements from ggplot2?\n\nSince `kravis` just mimics some parts of `ggplot2`, and because user may want to create more custom plots we do support preambles (e.g. to define new geoms) and custom layer specs.\n\nExample\n\n```kotlin\nirisData.plot(x = \"Species\", y = \"Sepal.Length\", fill = \"Species\")\n    .addPreamble(\"\"\"devtools::source_url(\"https://git.io/fAiQN\")\"\"\")\n    .addCustom(\"\"\"geom_flat_violin(scale = \"count\", trim = FALSE)\"\"\")\n    .geomDotplot(binaxis = \"y\", dotsize = 0.5, stackdir = \"down\", binwidth = 0.1, position = PositionNudge(-0.025))\n    .theme(legendPosition = \"none\")\n    .labs(x = \"Species\", y = \"Sepal length (cm)\")\n```\n\n![](.README_images/dot_violin.png)\n\n## How to run tests on your local machine\n\nRun the following commands.\n\n    cd misc/docker/kravis_test/ \u0026\u0026 docker build --progress=plain -t kravis_test .\n    ./gradlew test\n\n## References\n\nYou don't like it? Here are some other projects which may better suit your purpose. Before you leave, consider dropping us a [ticket](https://github.com/holgerbrandl/kravis/issues/ticket) with some comments about whats missing, badly designed or simply broken in `kravis`.\n\nGGplot Wrappers\n\n* [gg4clj](https://github.com/JonyEpsilon/gg4clj) Another ggplot2 wrapper written in java\n\n\nOther JVM visualization libraries ordered by -- personally biased -- usefullness\n\n* [SmilePlot](https://github.com/haifengl/smile#smileplot) provides data visualization tools such as plots and maps for researchers to understand information more easily and quickly.\n* [XChart](https://github.com/timmolter/XChart) is a light-weight Java library for plotting data\n* [data2viz](https://github.com/data2viz/data2viz) is a multi platform data visualization library with comprehensive DSL\n* [Kubed](https://github.com/hudsonb/kubed/) is a Kotlin library for manipulating the JavaFX scenegraph based on data.\n* [TornadoFX](https://github.com/edvin/tornadofx/wiki/Charts) provides some Kotlin wrappers around JavaFX\n* [plotly-scala](https://github.com/alexarchambault/plotly-scala) which provides scala bindings for plotly.js and works within jupyter\n* [breeze-viz](https://github.com/scalanlp/breeze/tree/master/viz) which is a\nVisualization library backed by Breeze and JFreeChart\n* [grafana](https://grafana.com/) is an open platform for beautiful analytics and monitoring\n* [Jzy3d](http://www.jzy3d.org/) is an open source java library that allows to easily draw 3d scientific data: surfaces, scatter plots, bar charts\n\nOther\n* https://github.com/bloomberg/bqplot is a plotting library for IPython/Jupyter Notebooks\n\n\nVega-lite based\n* [Vegas](https://github.com/vegas-viz/Vegas) aims to be the missing MatPlotLib for Scala + Spark\n* [altair](https://github.com/altair-viz/altair) provides declarative statistical visualization library for Python\n* [vega-embed](https://github.com/vega/vega-embed) allows to publish Vega visualizations as embedded web components with interactive parameters.\n* [hrbrmstr/vegalite](https://github.com/hrbrmstr/vegalite) provides R ggplot2 \"bindings\" for Vega-Lite\n\n\n\n## Acknowledgements\n\nThanks to vega-lite team for making this project possible.\n\nThanks to the ggplot2 team for providing the best data vis API to date.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fholgerbrandl%2Fkravis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fholgerbrandl%2Fkravis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fholgerbrandl%2Fkravis/lists"}