JetBrains / lets-plot-kotlin

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

`LinearBreaksHelper$Companion.computeNiceBreaks` out of memory error #105

Closed a-glapinski closed 2 years ago

a-glapinski commented 2 years ago

Hi, I've created a plot using following code:

val data = mapOf(
    "Task interval coefficient of variation" to listOf(1.17546, 1.19216, 1.20941, 1.22708, 1.24521, 1.26378, 1.28274, 1.30207, 1.32178, 1.34187, 1.3623, 1.383, 1.40404, 1.42535, 1.44695, 1.46884, 1.49097, 1.51339, 1.53597, 1.55886),
    "Average processing time" to listOf(41.1325, 41.1325, 41.1325, 41.1325, 41.1325, 41.1325, 41.1325, 41.1325, 41.1325, 41.1325, 41.1325, 41.1325, 41.1325, 41.1325, 41.1325, 41.1325, 41.1325, 41.1325, 41.1325, 41.1325)
)

val plot = ggplot(data) { x = "Task interval coefficient of variation"; y = "Average processing time" } + geomPoint() + geomSmooth()

Unfortunately, when trying to save it to PNG file using following code:

ggsave(plot, "p1.png")

I've got following error:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.base/java.lang.Double.valueOf(Double.java:537)
    at jetbrains.datalore.plot.base.scale.breaks.LinearBreaksHelper$Companion.computeNiceBreaks(LinearBreaksHelper.kt:82)
    at jetbrains.datalore.plot.base.scale.breaks.LinearBreaksHelper$Companion.access$computeNiceBreaks(LinearBreaksHelper.kt:42)
    at jetbrains.datalore.plot.base.scale.breaks.LinearBreaksHelper.<init>(LinearBreaksHelper.kt:30)
    at jetbrains.datalore.plot.base.scale.breaks.LinearBreaksHelper.<init>(LinearBreaksHelper.kt:10)
    at jetbrains.datalore.plot.base.scale.transform.LinearBreaksGen$Companion.generateBreakValues$plot_base_portable(LinearBreaksGen.kt:37)
    at jetbrains.datalore.plot.base.scale.transform.LinearBreaksGen.generateBreaks(LinearBreaksGen.kt:21)
    at jetbrains.datalore.plot.base.scale.transform.Transforms$BreaksGeneratorForTransformedDomain.generateBreaks(Transforms.kt:70)
    at jetbrains.datalore.plot.builder.layout.axis.AdaptableAxisBreaksProvider.getBreaks(AdaptableAxisBreaksProvider.kt:25)
    at jetbrains.datalore.plot.builder.layout.axis.label.BreakLabelsLayoutUtil.getFlexBreaks(BreakLabelsLayoutUtil.kt:24)
    at jetbrains.datalore.plot.builder.layout.axis.label.VerticalFlexBreaksLabelsLayout.getBreaks(VerticalFlexBreaksLabelsLayout.kt:53)
    at jetbrains.datalore.plot.builder.layout.axis.label.VerticalFlexBreaksLabelsLayout.doLayout(VerticalFlexBreaksLabelsLayout.kt:42)
    at jetbrains.datalore.plot.builder.layout.axis.AxisLayouter.doLayout(AxisLayouter.kt:22)
    at jetbrains.datalore.plot.builder.layout.PlotAxisLayout.doLayout(PlotAxisLayout.kt:42)
    at jetbrains.datalore.plot.builder.layout.XYPlotTileLayout$Companion.computeVAxisInfo(XYPlotTileLayout.kt:203)
    at jetbrains.datalore.plot.builder.layout.XYPlotTileLayout$Companion.computeAxisInfos(XYPlotTileLayout.kt:134)
    at jetbrains.datalore.plot.builder.layout.XYPlotTileLayout$Companion.access$computeAxisInfos(XYPlotTileLayout.kt:103)
    at jetbrains.datalore.plot.builder.layout.XYPlotTileLayout.doLayout(XYPlotTileLayout.kt:27)
    at jetbrains.datalore.plot.builder.layout.SingleTilePlotLayout.doLayout(SingleTilePlotLayout.kt:27)
    at jetbrains.datalore.plot.builder.PlotSvgComponent.buildPlotComponents(PlotSvgComponent.kt:182)
    at jetbrains.datalore.plot.builder.PlotSvgComponent.buildPlot(PlotSvgComponent.kt:111)
    at jetbrains.datalore.plot.builder.PlotSvgComponent.buildComponent(PlotSvgComponent.kt:86)
    at jetbrains.datalore.plot.base.render.svg.SvgComponent.buildComponentIntern(SvgComponent.kt:46)
    at jetbrains.datalore.plot.base.render.svg.SvgComponent.ensureBuilt(SvgComponent.kt:39)
    at jetbrains.datalore.plot.base.render.svg.SvgComponent.getRootGroup(SvgComponent.kt:33)
    at jetbrains.datalore.plot.builder.PlotContainerPortable.buildContent(PlotContainerPortable.kt:87)
    at jetbrains.datalore.plot.builder.PlotContainerPortable.ensureContentBuilt(PlotContainerPortable.kt:44)
    at jetbrains.datalore.plot.MonolithicCommon.buildSvgImagesFromRawSpecs(MonolithicCommon.kt:51)
    at jetbrains.datalore.plot.PlotSvgExportPortable.buildSvgImageFromRawSpecs(PlotSvgExportPortable.kt:42)
    at jetbrains.datalore.plot.PlotSvgExport.buildSvgImageFromRawSpecs(PlotSvgExport.kt:25)
    at jetbrains.datalore.plot.PlotSvgExport.buildSvgImageFromRawSpecs$default(PlotSvgExport.kt:21)
    at jetbrains.datalore.plot.PlotImageExport.buildImageFromRawSpecs(PlotImageExport.kt:90)

Process finished with exit code 1

The direct reason of error is probably the fact that in LinearBreaksHelper$Companion.computeNiceBreaks function step has such a small value that ticks value is never getting higher, so the program never exits the while loop. image

a-glapinski commented 2 years ago

I think I posted issue in the wrong repo (it probably should be posted in https://github.com/JetBrains/lets-plot repo) 😅 Please move it if you can.

alshan commented 2 years ago

Yes, we run into limits of double precision here ( Thanks for reporting this. Unfortunately I don't see what else to suggest you now apart from not to use geomSmooth in such marginal cases.

alshan commented 2 years ago

I posted issue in the wrong repo

No, this is fine.

alshan commented 2 years ago

Fixed in v3.2.0