java 如何在JFreeChart散点图上找到输入值的最佳拟合线的梯度

ct2axkht  于 2022-10-30  发布在  Java
关注(0)|答案(1)|浏览(188)

基于该example,下面的代码绘制了一个散点图,可以将双值输入到一个微调器中,并绘制在散点图上。我想在散点图上绘制一条最佳拟合线,以便计算梯度,并找到梯度值的平均值。当按下按钮时,我会将梯度值输出到文本框中。如有帮助,将不胜感激。谢谢

public class ScatterAdd extends Application {
    private final XYSeries series = new XYSeries("Voltage");

    ChoiceBox<String> domainLabels = new ChoiceBox<>();
    ChoiceBox<String> rangeLabels = new ChoiceBox<>();

    private JFreeChart createChart() {
        XYSeriesCollection dataset = new XYSeriesCollection();
        dataset.addSeries(series);

        return ChartFactory.createScatterPlot("VI Characteristics", "Current", "Voltage", dataset);
    }

    @Override
    public void start(Stage stage) {

        Image image = new Image("Grava.logo.png");
        stage.getIcons().add(image);

        ChoiceBox<String> domainLabels = new ChoiceBox<>();
        ChoiceBox<String> rangeLabels = new ChoiceBox<>();

        JFreeChart chart = createChart();
        domainLabels.getSelectionModel().selectedItemProperty().addListener((ov, s0, s1) -> {
            chart.getXYPlot().getDomainAxis().setLabel(s1);
        });
        rangeLabels.getSelectionModel().selectedItemProperty().addListener((ov, s0, s1) -> {
            chart.getXYPlot().getRangeAxis().setLabel(s1);
        });

        domainLabels.getItems().addAll("Current", "Seconds");
        domainLabels.setValue("Current");

        rangeLabels.getItems().addAll("Voltage", "Metres");
        rangeLabels.setValue("Voltage");

        var xSpin = new Spinner<Double>(-10000.000, 10000.000, 0,0.1);
        xSpin.setEditable(true);
        xSpin.setPromptText("Xvalue");

        var ySpin = new Spinner<Double>(-10000.000, 10000.000, 0,0.1);
        ySpin.setEditable(true);
        ySpin.setPromptText("Yvalue");

        var button = new Button("Add");
        button.setOnAction(ae -> series.add(xSpin.getValue(), ySpin.getValue()));

        HBox xBox = new HBox();
        xBox.getChildren().addAll(domainLabels);

        HBox yBox = new HBox();
        yBox.getChildren().addAll(rangeLabels);

        var enter = new ToolBar(xBox, xSpin, yBox, ySpin, button);
        BorderPane.setAlignment(enter, Pos.CENTER);

        BorderPane root = new BorderPane();
        root.setCenter(new ChartViewer(chart));
        root.setBottom(enter);

        stage.setTitle("ScatterAdd");
        stage.setScene(new Scene(root, 640, 480));
        stage.show();

    }

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

6pp0gazn1#

here所示,调用Regression.getOLSRegression()并显示结果。您可以在Add按钮处理程序中执行此操作,如您的问题中所建议的,或者在SeriesChangeListener中执行此操作,如下所示。此片段只打印行的等式,但您可以根据需要更新显示。

private final XYSeries series = new XYSeries("Voltage");
private final XYSeriesCollection dataset = new XYSeriesCollection(series);
…
// https://stackoverflow.com/a/61398612/230513
series.addChangeListener((event) -> {
    double[] coefficients = Regression.getOLSRegression(dataset, 0);
    double b = coefficients[0]; // intercept
    double m = coefficients[1]; // slope
    System.out.println("y = " + m + " x + " + b);
});

请注意,series至少需要两个值,而且应该只将它加入集合一次。

相关问题