JavaFX扩展图

JavaFX扩展图,java,javafx,Java,Javafx,如何使用JavaFX库在散点图上绘制最佳拟合直线和乘积矩相关系数?我试过用谷歌搜索一些例子,但没有一个是精确的,甚至与我正在尝试做的相似。我是JavaFX新手,因此非常感谢您的帮助。互联网上有一些例子,但都是针对完全不同的图书馆,这对我没有帮助 我有以下显示散点图的代码(只是一个示例): 导入javafx.application.application; 导入javafx.scene.scene; 导入javafx.scene.chart.NumberAxis; 导入javafx.scene.c

如何使用JavaFX库在散点图上绘制最佳拟合直线和乘积矩相关系数?我试过用谷歌搜索一些例子,但没有一个是精确的,甚至与我正在尝试做的相似。我是JavaFX新手,因此非常感谢您的帮助。互联网上有一些例子,但都是针对完全不同的图书馆,这对我没有帮助

我有以下显示散点图的代码(只是一个示例):

导入javafx.application.application;
导入javafx.scene.scene;
导入javafx.scene.chart.NumberAxis;
导入javafx.scene.chart.ScatterChart;
导入javafx.scene.chart.XYChart;
导入javafx.stage.stage;
公共类分散扩展应用程序{
@凌驾
公众假期开始(阶段){
最终数字xis xAxis=新数字xis(0,100,20);
最终数字xis yAxis=新数字xis(0,100,20);
最终散射图sc=新
散点图(xAxis,yAxis);
xAxis.setLabel(“所有考试的平均值”);
yAxis.setLabel(“春季学期测试标记”);
sc.setTitle(“学生分数”);
XYChart.Series plots=新的XYChart.Series();
plots.getData().add(新的XYChart.Data(10,15));
plots.getData().add(新的XYChart.Data(15,20));
plots.getData().add(新的XYChart.Data(77,77));
plots.getData().add(新的XYChart.Data(55,13));
plots.getData().add(新的XYChart.Data(44,22));
plots.getData().add(新的XYChart.Data(45,43));
sc.getData().add(绘图);
场景=新场景(sc,600600);
舞台场景;
stage.show();
}
公共静态void main(字符串[]args){
发射(args);
}
}

最佳拟合线和相关系数的实际公式计算在别处很容易找到(听起来有点像家庭作业问题),因此我将省略这些公式;听起来您只是想知道如何将节点(例如,实际的线)添加到图表中

其基本思想是子类化
散点图
并重写
layoutPlotChildren
方法。您可以使用CSS为每个最佳拟合行添加与相应系列中的数据相同的颜色,方法是参考
N=1…8的查找颜色
CHART\u color\N

下面是一个示例(我只使用虚拟值作为直线的公式,您可以用实际计算替换):

还有一个演示:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.stage.Stage;

public class ScatterPlotTest extends Application {

    @Override
    public void start(Stage primaryStage) {
        ScatterPlotWithBestFitLine plot = new ScatterPlotWithBestFitLine(new NumberAxis(), new NumberAxis());

        plot.getData().add(createSeries("Data", new double[] {
                {10,15},
                {15,20},
                {77,77},
                {55,13},
                {44,22},
                {45,43}
        }));


        Scene scene = new Scene(plot, 600, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private Series<Number, Number> createSeries(String name, double[][] values) {
        Series<Number, Number> series = new Series<>();
        series.setName("Data");
        for (double[] point : values) {
            series.getData().add(new Data<>(point[0],point[1]));
        }
        return series ;
    }            

    public static void main(String[] args) {
        launch(args);
    }
}

你是个救生员。你的代码在散点图上生成了一条线,这是我真正需要的——其他的例子都非常糟糕,而且非常容易移动,因为他们将一条线图放在散点图的顶部,并改变了梯度,使一条线不那么显眼,这是荒谬和可笑的效率低下。我已经编写了一个计算值的方法,并使用您的类在计算出的x和y值上绘制了线。现在一切都很好。再次感谢:)
import java.util.ArrayList;
import java.util.List;

import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.ScatterChart;
import javafx.scene.shape.Line;

public class ScatterPlotWithBestFitLine extends ScatterChart<Number, Number> {

    private final NumberAxis xAxis ;
    private final NumberAxis yAxis ;

    private final List<Line> lines = new ArrayList<>();


    public ScatterPlotWithBestFitLine(NumberAxis xAxis, NumberAxis yAxis) {
        super(xAxis, yAxis);
        this.xAxis = xAxis ;
        this.yAxis = yAxis ;

        getStylesheets().add("best-fit-line.css");
    }

    @Override
    protected void layoutPlotChildren() {

        getPlotChildren().removeAll(lines);
        lines.clear();

        super.layoutPlotChildren();

        int index = 0 ;
        for (Series<Number, Number> series : getData()) {

            Line line = new Line();
            line.setStartX(xAxis.getDisplayPosition(xAxis.getLowerBound()));
            line.setEndX(xAxis.getDisplayPosition(xAxis.getUpperBound()));

            int count = (index % 8) + 1 ;
            line.getStyleClass().add("best-fit-line");
            line.getStyleClass().add("best-fit-line-"+count);

            // TODO compute actual line of best fit...
            // can iterate through values with:

            // for (Data<Number, Number> d : series.getData()) {
            //     double x = d.getXValue().doubleValue();
            //     double y = d.getYValue().doubleValue();
            // }

            // just dummy values:
            double m = 0 ;
            double b = (getData().size() - index) * yAxis.getLowerBound() + (index + 1) * yAxis.getUpperBound() / 2 ;

            line.setStartY(yAxis.getDisplayPosition(m * xAxis.getLowerBound() + b));
            line.setEndY(yAxis.getDisplayPosition(m * xAxis.getUpperBound() + b));

            getPlotChildren().add(line);
            lines.add(line);

            index++ ;
        }
    }


}
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.stage.Stage;

public class ScatterPlotTest extends Application {

    @Override
    public void start(Stage primaryStage) {
        ScatterPlotWithBestFitLine plot = new ScatterPlotWithBestFitLine(new NumberAxis(), new NumberAxis());

        plot.getData().add(createSeries("Data", new double[] {
                {10,15},
                {15,20},
                {77,77},
                {55,13},
                {44,22},
                {45,43}
        }));


        Scene scene = new Scene(plot, 600, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private Series<Number, Number> createSeries(String name, double[][] values) {
        Series<Number, Number> series = new Series<>();
        series.setName("Data");
        for (double[] point : values) {
            series.getData().add(new Data<>(point[0],point[1]));
        }
        return series ;
    }            

    public static void main(String[] args) {
        launch(args);
    }
}
    private Series<Number, Number> createSeries(String name, double[][] values) {
        Series<Number, Number> series = new Series<>();
        ObservableList<Data<Number, Number>> data = FXCollections.observableArrayList(
            d -> new Observable[] {d.XValueProperty(), d.YValueProperty()});

        for (double[] point : values) {
            series.getData().add(new Data<>(point[0],point[1]));
        }

        series.nameProperty().bind(Bindings.createStringBinding(() -> 
            String.format("%s (r=%.3f)", name, computeCorrelation(data)),
            data);

        return series ;
    }   

    private double computeCorrelation(List<Data<Number, Number>> data) {
        //TODO compute correlation from data...
        return 0 ;
    }