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