JetBrains / lets-plot-kotlin

Grammar of Graphics for Kotlin
https://lets-plot.org/kotlin/
MIT License
419 stars 36 forks source link

Documentation for using Maven artifacts #5

Closed breandan closed 4 years ago

breandan commented 4 years ago

Hi Igor et al., nice work here! Are you planning to support consumers of this API outside a Jupyter notebook? If so, it would be nice to have some documentation on which dependencies are necessary. Based on the build.gradle file, I was able to locate the Bintray artifacts, and noticed you have written some demos, so it looks like a few use cases are already supported. Specifically, it would be nice to have a quick section in the readme for how to configure Maven/Gradle and output plots to a file or JFX window.

Also, what is the difference between this repository and JetBrains/lets-plot, and where is the appropriate place to file issues? Thanks!

breandan commented 4 years ago

Running git clone git@github.com:JetBrains/lets-plot-kotlin.git && cd lets-plot-kotlin && ./gradlew build --stacktrace fails with the following exception:


FAILURE: Build failed with an exception.

* Where:
Build file '/Users/breandan/IdeaProjects/lets-plot-kotlin/build.gradle' line: 32

* What went wrong:
A problem occurred evaluating root project 'lets-plot-kotlin'.
> Couldn't read build_settings.yml

* Try:
Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Exception is:
org.gradle.api.GradleScriptException: A problem occurred evaluating root project 'lets-plot-kotlin'.
        at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:92)
        at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl$2.run(DefaultScriptPluginFactory.java:206)
        at org.gradle.configuration.ProjectScriptTarget.addConfiguration(ProjectScriptTarget.java:77)
...
Caused by: org.gradle.api.GradleException: Couldn't read build_settings.yml
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at build_2j11st2qfzdjuvy31gxgq1fjd.run(/Users/breandan/IdeaProjects/lets-plot-kotlin/build.gradle:32)
        at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:90)
        ... 127 more

* Get more help at https://help.gradle.org

BUILD FAILED in 0s
alshan commented 4 years ago

Hi Brendan, build_settings.yml holds private keys needed for deployment. For just building the project you can copy https://github.com/JetBrains/lets-plot-kotlin/blob/master/build_settings.template.yml to build_settings.yml in the same location (project root).

alshan commented 4 years ago

You are right, there are few demos in https://github.com/JetBrains/lets-plot-kotlin/tree/master/demo/jvm-javafx/src/main/kotlin/plotDemo/scripts.

Each of them you can run as a normal java app right in IDEA. We didn't have immediate plans to release JVM artifacts mostly because besides Jupyter Kotlin kernel we didn't have other use-cases for JVM-based plots.

Are you looking to embed plots into JVM app? We can relatively easily support JFX graphics or, alternatively AWT+Batik.

alshan commented 4 years ago

JetBrains/lets-plot repo contains Lets-Plot implementation and build scrips to build and publish artifacts like

org.jetbrains.lets-plot:lets-plot-common:1.0.1-SNAPSHOT
org.jetbrains.lets-plot:lets-plot-jfx:1.0.1-SNAPSHOT

This repo (lets-plot-kotlin) only contains Kotlin API (or DSL) to Lets-Plot library and uses said artifacts.

There is also Python API to the same library: https://pypi.org/project/lets-plot/

alshan commented 4 years ago

Please file issues/proposals to the main project - https://github.com/JetBrains/lets-plot unless they concerned exclusively Kotlin API, in which case feel free to file them here.

tpgillam commented 4 years ago

Just wanted to add a use-case :)

I'm interested in the ability to plot within the JVM, so it's exciting to come across this project (via the KotlinConf talk). I currently am working on a small project that uses Kotlin for running simulations, some outputs of which I'm plotting. Adding Jupyter to the mix would make for a clunkier workflow - it really is nice just to create a quick script in IDEA, press run, and have some plots appear a few seconds later... then change some library code and repeat without having to mess around with manual interpreter restarts etc! (Right now we achieve this with a small Kotlin-based DSL that pipes data & commands into a Python interpreter to use matplotlib...)

I've used Python + matplotlib for this kind of work a lot in the past. Bringing the plots up visually is great for fast iteration & debugging, but it's also useful that matplotlib can work headless when writing images directly to files... that way you can dump lots of results, e.g. after doing some kind of parameter sweep, and browse later, or include them in a paper.

For me, the benefits of the type system, coroutines, and fantastic tooling are already enough to make Kotlin attractive cf. Python + Cython/C++ for this project, despite the sitll-nascent math/stats/etc. libraries. Easy-to-use visualisation tools would make it even more appealing!

alshan commented 4 years ago

@tpgillam As the use-cases are building up ) I've just added MonolithicAwt util which makes it really easy to try plots in JVM (currently, JavaFX graphics only). Please check out the example at "kotlin/minimalDemo/Main.kt".

To use this code in your own project you will need to configure another maven repo: https://jetbrains.bintray.com/lets-plot-maven And add the following dependencies:

org.jetbrains.lets-plot:lets-plot-jfx:1.1.1-SNAPSHOT
org.jetbrains.lets-plot:lets-plot-kotlin-api:0.0.8-SNAPSHOT
org.jetbrains.lets-plot:kotlin-frontend-api:0.0.8-SNAPSHOT

The headless mode sounds like an important feature, doesn't it?

tpgillam commented 4 years ago

@alshan Thanks very much, this looks great! Afraid I won't have time to check this out properly before Christmas; but will have a play soon I hope.

Yes, having a renderer that isn't tied to a GUI would certainly be valuable - I'm guessing the design of lets-plot can support multiple backends already, in principle at least?

alshan commented 4 years ago

@tpgillam lets-plot has mappers layer between plot model and actual graphics. Perhaps this can do for headless image rendering as well. May be you can find time to briefly describe the desired headless workflow in a separate issue?

breandan commented 4 years ago

Thanks! After some trial and error, I was able to get the demo working in the Gradle Kotlin DSL on JDK 13. These are the essential parts of the build.gradle.kts file:

plugins {
  id("org.openjfx.javafxplugin") version "0.0.8"
}

repositories {
  mavenCentral()
  maven("https://jetbrains.bintray.com/lets-plot-maven")
}

dependencies {
  implementation("org.openjfx:javafx-swing:13")
  implementation("org.openjfx:javafx:13")
  implementation("org.jetbrains.lets-plot:lets-plot-jfx:1.1.1-SNAPSHOT")
  implementation("org.jetbrains.lets-plot:lets-plot-common:1.1.1-SNAPSHOT")
  implementation("org.jetbrains.lets-plot:lets-plot-kotlin-api:0.0.8-SNAPSHOT")
  implementation("org.jetbrains.lets-plot:kotlin-frontend-api:0.0.8-SNAPSHOT")
}

javafx {
  modules("javafx.controls" ,"javafx.swing")
}

Is it possible to save the plot as an SVG file and is there an example of this somewhere?

alshan commented 4 years ago

Looks impressive) Currently there is no simple converter to SVG string. But this is not difficult, I'll add when back from vacations.

PHPirates commented 4 years ago

Awesome! Adding that build.gradle.kts in some form to the documentation or an example project would be very helpful (the build.gradle in demo/jvm-javafx is useful but was slightly too minimal to be readily usable for me).

alshan commented 4 years ago

Hi @breandan et al, I've added this doc: https://github.com/JetBrains/lets-plot-kotlin/blob/master/README_DEV.md and done some improvements in demos etc.

In particular, kotlin-frontend-api artifact is not any longer needed and SceneMapperJfxPanel has moved: jetbrains.datalore.vis.demoUtils.jfx -> jetbrains.datalore.vis.swing.

Please, try these new snapshots:

org.jetbrains.lets-plot:lets-plot-common:1.1.2-SNAPSHOT
org.jetbrains.lets-plot:lets-plot-jfx:1.1.2-SNAPSHOT
org.jetbrains.lets-plot:lets-plot-kotlin-api:0.0.9-SNAPSHOT

Also I've added export to SVG - see demos in: lets-plot-kotlin/demo/browser/src/main/kotlin/plotSvgDemo.

breandan commented 4 years ago

Works great, thanks Igor! Does lets-plot plan to support any smooth interpolation schemes, e.g. cubic splines? I noticed when using geom_line, if the sample count is low the plot quality looks jagged. I guess this is a problem (feature?) with most plotting libraries.

image

alshan commented 4 years ago

It's not in the original ggplot2 specs (we're prioritizing these specs) but to have stat_spline/geom_spline like in ggformula sounds like a good idea to me. Could you create an issue in the main lets-plot? Or may be even ☆ミ contribute ?

breandan commented 4 years ago

Okay, just curious, thanks. BTW GitHub does not seem to render the generated SVG out of the box. When using the SVG generated by MonolithicAwt.buildSvgImagesFromRawSpecs, I see the following:

After manually adding the attribute xmlns="http://www.w3.org/2000/svg" to the parent svg tag, i.e. so that:

<svg class="plt-container" width="1000.0" height="500.0">

instead becomes:

<svg xmlns="http://www.w3.org/2000/svg" width="1000.0" height="500.0">

Then GitHub is able to render the SVG generated by lets-plot-kotlin:

alshan commented 4 years ago

@breandan , thanks for the find. I've included the fix to 1.2.1-SNAPSHOT. Please, try new jars.