lets-plot-kotlin icon indicating copy to clipboard operation
lets-plot-kotlin copied to clipboard

does lets-plot support embeded in java and scala

Open mullerhai opened this issue 1 year ago • 9 comments

lets-plot is very powerful, but I write scala code almost ,so I wanna know does lets-plot is support kotlin/scala mixed code project

mullerhai avatar Dec 20 '24 06:12 mullerhai

Hi, since both Kotlin and Scala run on the JVM and have good interoperability, you can, technically, use it in mixed projects.

However, some of Kotlin's DSL-style syntax will be lost in scale (like the "+" operator). So a simple plot in Kotlin:

letsPlot(data) + geomPoint {
    x = "hwy"
    y = "cty"
    color = "make"
}

Becomes more verbose in Scala:

letsPlot(data).plus(new geomPoint(
  mapping = { mapping =>  // In Kotlin this would be a function with receiver: PointMapping.() -> Unit.
        // Not even sure Scala will pickup the receiver type form Kotlin's functional type with receiver.
    mapping.x = "hwy"      
    mapping.y = "cty"
    mapping.color = "make"
  }
))

alshan avatar Dec 27 '24 21:12 alshan

Hi, since both Kotlin and Scala run on the JVM and have good interoperability, you can, technically, use it in mixed projects.

However, some of Kotlin's DSL-style syntax will be lost in scale (like the "+" operator). So a simple plot in Kotlin:

letsPlot(data) + geomPoint {
    x = "hwy"
    y = "cty"
    color = "make"
}

Becomes more verbose in Scala:

letsPlot(data).plus(new geomPoint(
  mapping = { mapping =>  // In Kotlin this would be a function with receiver: PointMapping.() -> Unit.
        // Not even sure Scala will pickup the receiver type form Kotlin's functional type with receiver.
    mapping.x = "hwy"      
    mapping.y = "cty"
    mapping.color = "make"
  }
))

thanks ,if I use lets-plot in scala-sbt project, could you tell me which lets-plot module package dependencies should use ,because to many module

mullerhai avatar Dec 28 '24 05:12 mullerhai

You will need to add lets-plot-kotlin-jvm and lets-plot-batik dependencies as shown here: https://github.com/JetBrains/lets-plot-kotlin/blob/master/USAGE_BATIK_JFX_JS.md#jvm-swing-batik .

To get started, it might be a good idea to check out the lets-plot-mini-apps and try running a simple app here: https://github.com/alshan/lets-plot-mini-apps/blob/main/jvm-swing-batik-app/build.gradle.kts .

alshan avatar Dec 28 '24 17:12 alshan

You will need to add lets-plot-kotlin-jvm and lets-plot-batik dependencies as shown here: https://github.com/JetBrains/lets-plot-kotlin/blob/master/USAGE_BATIK_JFX_JS.md#jvm-swing-batik .

To get started, it might be a good idea to check out the lets-plot-mini-apps and try running a simple app here: https://github.com/alshan/lets-plot-mini-apps/blob/main/jvm-swing-batik-app/build.gradle.kts .

Ok ,Very thanks, I will try it

mullerhai avatar Dec 29 '24 02:12 mullerhai

You will need to add lets-plot-kotlin-jvm and lets-plot-batik dependencies as shown here: https://github.com/JetBrains/lets-plot-kotlin/blob/master/USAGE_BATIK_JFX_JS.md#jvm-swing-batik .

To get started, it might be a good idea to check out the lets-plot-mini-apps and try running a simple app here: https://github.com/alshan/lets-plot-mini-apps/blob/main/jvm-swing-batik-app/build.gradle.kts .

now I had try some times write scala to use kotlin letsplot, but in scala maybe cannot straight import kotlin package func method,the letsplot is func in kotlin ,but can not recognazi by scala

import org.jetbrains.letsPlot.core.plot.base.geom.DensityGeom
import org.jetbrains.letsPlot.geom.geomDensity
import org.jetbrains.letsPlot.letsPlot
import scala.collection.JavaConverters._

object Draw {
  def main(args: Array[String]): Unit = {
    val rand = new java.util.Random()
    val n = 200
    // 使用Map来存储数据,类似于Kotlin中的mapOf
    val data = Map("x" -> (1 to n).map(_ => rand.nextGaussian()).toList)

    // 构建密度图
    val p = letsPlot(data) +
      geomDensity(
        color = "dark-green",
        fill = "green",
        alpha = 0.3,
        size = 2.0
      ) { x = "x" }

    // 显示图表
    p.show()
  }
}

mullerhai avatar Jan 15 '25 06:01 mullerhai

Image

mullerhai avatar Jan 15 '25 06:01 mullerhai

···

import org.jetbrains.letsPlot.core.plot.base.geom.DensityGeom import org.jetbrains.letsPlot.geom.geomDensity //import org.jetbrains.letsPlot.letsPlot import scala.collection.JavaConverters._ import org.jetbrains.letsPlot.intern.GenericAesMapping import org.jetbrains.letsPlot.intern.Plot import org.jetbrains.letsPlot.LetsPlot object Draw { def main(args: Array[String]): Unit = { val rand = new java.util.Random() val n = 200 val geo = geomDensity( color = "dark-green", fill = "green", alpha = 0.3, size = 2.0 ) { x = "x" } // 使用Map来存储数据,类似于Kotlin中的mapOf val data = Map("x" -> (1 to n).map(_ => rand.nextGaussian()).toList) val ps = new Plot(data=data.asJava, mapping = GenericAesMapping().apply(mapping).seal(), features = listOfNotNull(LetsPlot.theme))

val p = ps.plus(geo)
p.show()

} } ··· this code also can not work

mullerhai avatar Jan 15 '25 06:01 mullerhai

for geomDensity the constructor default param also can not recognize by scala

E:\code\Storch_Test\src\main\scala\temp_1736922020754.scala:12:15
None of the overloaded alternatives of constructor geomDensity in class geomDensity with types
 (): org.jetbrains.letsPlot.geom.geomDensity
 (x$0: java.util.Map[?, ?],
  x$1: org.jetbrains.letsPlot.intern.layer.StatOptions,
  x$2: org.jetbrains.letsPlot.intern.layer.PosOptions, x$3: Boolean,
  x$4: Boolean², x$5: Object,
  x$6: org.jetbrains.letsPlot.intern.layer.SamplingOptions,
  x$7: org.jetbrains.letsPlot.tooltips.layerTooltips, x$8: String, x$9: Number,
  x$10: Number, x$11: Number, x$12: Object, x$13: Object, x$14: Object,
  x$15: Number, x$16: Object, x$17: Object, x$18: String, x$19: Integer,
  x$20: Boolean², x$21: Number, x$22: Integer, x$23: java.util.List[?],
  x$24: Boolean², x$25: String, x$26: String,
  x$27: kotlin.jvm.functions.Function1[?, ?], x$28: Int, x$29:
  kotlin.jvm.internal.DefaultConstructorMarker):
  org.jetbrains.letsPlot.geom.geomDensity
 (x$0: java.util.Map[?, ?],
  x$1: org.jetbrains.letsPlot.intern.layer.StatOptions,
  x$2: org.jetbrains.letsPlot.intern.layer.PosOptions, x$3: Boolean,
  x$4: Boolean², x$5: Object,
  x$6: org.jetbrains.letsPlot.intern.layer.SamplingOptions,
  x$7: org.jetbrains.letsPlot.tooltips.layerTooltips, x$8: String, x$9: Number,
  x$10: Number, x$11: Number, x$12: Object, x$13: Object, x$14: Object,
  x$15: Number, x$16: Object, x$17: Object, x$18: String, x$19: Integer,
  x$20: Boolean², x$21: Number, x$22: Integer,
  x$23: java.util.List[? <: Number], x$24: Boolean², x$25: String,
  x$26: String, x$27:
  kotlin.jvm.functions.Function1[
    ? >: org.jetbrains.letsPlot.intern.layer.geom².DensityMapping, kotlin.Unit]
): org.jetbrains.letsPlot.geom.geomDensity
match arguments (("dark-green" : String), ("green" : String), (0.3d : Double), (2.0d : Double))

where:    Boolean  is a class in package scala
          Boolean² is a class in package java.lang
          geom     is a package in package org.jetbrains.letsPlot
          geom²    is a package in package org.jetbrains.letsPlot.intern.layer

    val geo = geomDensity(

mullerhai avatar Jan 15 '25 06:01 mullerhai

val geo = geomDensity(

Hi, geomDensity is a class actually so you will need

val geo = new geomDensity(

alshan avatar Jan 15 '25 15:01 alshan