SciProgCentre / plotly.kt

An interactive Kotlin wrapper for plotly visualization tools
https://sciprogcentre.github.io/plotly.kt/
Apache License 2.0
147 stars 21 forks source link

3d charts support #68

Open ValeryNo opened 3 years ago

ValeryNo commented 3 years ago

Are there any plans to support 3d charts? If they are not officially supported yet are there any "not perfect but kinda works" examples or workarounds of how to use them with the current library? :) Perhaps substituting Trace with my own raw json or something like that.

Thank you in advance!

PS. I can see some types commented in TraceType enum surface, scatter3d etc.

altavir commented 3 years ago

Scatter plots are easy to do. Actually, this example works fine on the dev build:

fun main() {
    val plot = Plotly.plot {
        trace {
            set("type","scatter3d") // bypassing type safety here
            x(1,2,3)
            y(1,2,3)
            z(1,2,3)
        }
    }
    plot.makeFile()
}

newplot

The surface is more tricky because it requires some tweaks to trace values to allow for meshes. You still can use it via unsupoorted like this:

private fun l(vararg numbers: Number) = numbers.map { it.asValue() }.asValue()

fun main() {
    val plot = Plotly.plot {
        trace {
            z.value = listOf(
                l(8.83, 8.89, 8.81, 8.87, 8.9, 8.87),
                l(8.89, 8.94, 8.85, 8.94, 8.96, 8.92),
                l(8.84, 8.9, 8.82, 8.92, 8.93, 8.91),
                l(8.79, 8.85, 8.79, 8.9, 8.94, 8.92),
                l(8.79, 8.88, 8.81, 8.9, 8.95, 8.92),
                l(8.8, 8.82, 8.78, 8.91, 8.94, 8.92),
                l(8.75, 8.78, 8.77, 8.91, 8.95, 8.92),
                l(8.8, 8.8, 8.77, 8.91, 8.95, 8.94),
                l(8.74, 8.81, 8.76, 8.93, 8.98, 8.99),
                l(8.89, 8.99, 8.92, 9.1, 9.13, 9.11),
                l(8.97, 8.97, 8.91, 9.09, 9.11, 9.11),
                l(9.04, 9.08, 9.05, 9.25, 9.28, 9.27),
                l(9, 9.01, 9, 9.2, 9.23, 9.2),
                l(8.99, 8.99, 8.98, 9.18, 9.2, 9.19),
                l(8.93, 8.97, 8.97, 9.18, 9.2, 9.18)
            ).asValue()
            set("type", "surface")
        }
    }
    plot.makeFile()
}

newplot (1)

But it is not quite elegant. Some design and testing are needed here and we would welcome external contributions. Also, we need to check if those plots are in the core JS bundle. Because we want to load different bundles separately in the future to minimize the JS size. Currently makeFile directive uses the all-included bundle.

ValeryNo commented 3 years ago

That's more than enough for now, thank you!

While it is not fully supported, I really appreciate that you have thoughtfully provided a way to do things the original library allows without waiting for the wrapper code to be updated every time or falling back to string concatenation of some sort :)

altavir commented 3 years ago

I actually will leave this open. I personally do not have time right now, but it is not hard to implement, so it should wait for a hero.