Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

does lets-plot support embeded in java and scala #267

Open
mullerhai opened this issue Dec 20, 2024 · 9 comments
Open

does lets-plot support embeded in java and scala #267

mullerhai opened this issue Dec 20, 2024 · 9 comments

Comments

@mullerhai
Copy link

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

@alshan
Copy link
Collaborator

alshan commented Dec 27, 2024

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"
  }
))

@mullerhai
Copy link
Author

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

@alshan
Copy link
Collaborator

alshan commented Dec 28, 2024

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 .

@mullerhai
Copy link
Author

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

@alshan alshan transferred this issue from JetBrains/lets-plot Dec 30, 2024
@mullerhai
Copy link
Author

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
Copy link
Author

Image

@mullerhai
Copy link
Author

···

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
Copy link
Author

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(

@alshan
Copy link
Collaborator

alshan commented Jan 15, 2025

val geo = geomDensity(

Hi, geomDensity is a class actually so you will need

val geo = new geomDensity(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants