首页 > 解决方案 > 如何在 ScalaFX/JavaFX 中有效地绘制连续函数

问题描述

我正在研究回归模型可视化工具,我目前的瓶颈与绘制连续函数有关。该程序的工作原理是它从包含 (x, y) 值的文件中加载数据,使用矩阵对回归模型进行数学运算,然后为回归模型提供点以ScatterChart进行绘图。回归模型的单个绘图点由模型的系数和step充当两个原始数据点之间的 dx 的系数确定。

本质上,如果 dx 设置为 0.1 并且 x1 = 0,x2 = 10,我们将在 x1 和 x2 之间有 98 个模型点。如果您有兴趣,这里是模型的数学:https ://newonlinecourses.science.psu.edu/stat501/node/382/

代码中PolynomialGraph显示的本质上是一个回归模型。它知道如何给出原始数据点直到最大值,以及如何计算模型绘制点到最大值。所有的值都是(Double, Double)元组。

我的问题与以下事实有关,即根据我计算的绘图点数,绘制的绘图可能不会一直连续。这是因为单个绘图点具有恒定的大小(在 CSS 中确定),因此如果ScatterChart具有较大width且两个绘图点 (x1, y1) 和 (x2, y2) 之间的 dx 相对于x 轴的端点在图中会有可见的空间。原始点和模型点的大小和形状在下面的 CSS 代码中。

例如,(x1, y1) = (0, 10) 和 (x2, y2) = (100, 110) 和 dx = 100。现在在 (x1, y1) 和 (x2, y2) 之间绘制零点.

有没有合理的方法来解决这个问题?我已经尽力使用 ScalaFX 和 JavaFX API。但我想相信有一个更好的解决方法,而不是以某种方式计算一个像素中大约有多少个绘图点,然后确定需要绘制多少个点。

其他方法可能是找到 dy 最大的区间,并以某种方式确定需要多少点。

除此之外,我真的不知道动态解决这个问题。我总是可以将 dx 设置在附近10E-9,但这根本不能很好地扩展。如果 x 轴的值范围很大,我们可以轻松地将 dx 设置为 100。而如果最大值恰好是 1,我们可能需要 dx 在10E-9.

package regression

import scalafx.scene.chart.ScatterChart
import scalafx.collections.ObservableBuffer
import scalafx.scene.chart.XYChart
import scalafx.scene.chart.NumberAxis

object Plotter {

  def drawGraph(xName: String, yName: String, graph: PolynomialGraph): ScatterChart[Number, Number] = {
    val xAxis = NumberAxis()
    val yAxis = NumberAxis()
    val pData = XYChart.Series[Number, Number](
      xName,
      ObservableBuffer(graph.dataPointsUntilMaxX().map(z => XYChart.Data[Number, Number](z._2, z._1)): _*)) //Values have to be in order x, y
    val model = XYChart.Series[Number, Number](
      yName,
      ObservableBuffer(graph.calculatePlotPoints().map(z => XYChart.Data[Number, Number](z._1, z._2)): _*))
    val temp = new ScatterChart(xAxis, yAxis, ObservableBuffer(model, pData))
    temp
  }

}
.default-color0.chart-symbol {
    -fx-background-color: blue;
    -fx-background-radius: 0.5px;
    -fx-opacity: 1.0;
    -fx-padding: 1px;
}

.default-color1.chart-symbol {
    -fx-background-color: red, white;
    -fx-background-insets: 0, 2;
    -fx-background-radius: 2px;
    -fx-padding: 3px;
}

原始数据的最大 x 值为 23.5

显示的第一张图像的 dx 为 0.001,这意味着为模型图计算了 23500 个点。 在此处输入图像描述

显示的第二张图像的 dx 为 0.1。现在该图只计算了 235 个点,曲线中任意两点之间都有可见空间。 在此处输入图像描述

标签: javascalajavafxscalafx

解决方案


推荐阅读