针对一些离散的点,使用最小二乘法对该离散点进行直线拟合
效果图
源代码
import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.labels.StandardXYToolTipGenerator;
import org.jfree.chart.plot.DatasetRenderingOrder;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYDotRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.DefaultXYDataset;
public class LineOP {
public static void Draw() {
//数据我不能泄露,论文要用到滴。。
float[] pmv_x = {/*data*/};
float[] pmv_y = { /*data*/};
float[] mts_x = {/*data*/};
float[] mts_y = { /*data*/};
ArrayList<Float> x_pmv = new ArrayList<Float>();
ArrayList<Float> y_pmv = new ArrayList<Float>();
ArrayList<Float> x_mts = new ArrayList<Float>();
ArrayList<Float> y_mts = new ArrayList<Float>();
for (int i = 0; i < mts_y.length; i++) {
if (mts_y[i] != 0) {
x_mts.add(mts_x[i]);
y_mts.add(mts_y[i]);
}
if (pmv_y[i] != 0) {
x_pmv.add(pmv_x[i]);
y_pmv.add(pmv_y[i]);
}
}
int pmv_point = x_pmv.size();
int mts_point = x_mts.size();
float SumX = 0;
float SumX2 = 0;
for (int i = 0; i < pmv_point; i++) {
SumX += x_pmv.get(i);
SumX2 += (x_pmv.get(i) * x_pmv.get(i));
}
float SumY = 0;
for (int i = 0; i < pmv_point; i++) {
SumY += y_pmv.get(i);
}
float SumXY = 0;
for (int i = 0; i < pmv_point; i++) {
SumXY += (x_pmv.get(i) * y_pmv.get(i));
}
float b_pmv = ((SumX2 * SumY - SumX * SumXY) / (pmv_point * SumX2 - SumX
* SumX));
float k_pmv = ((pmv_point * SumXY - SumX * SumY) / (pmv_point * SumX2 - SumX
* SumX));
// 算冷感直线斜率、截距
SumX = 0;
SumX2 = 0;
for (int i = 0; i < mts_point; i++) {
SumX += x_mts.get(i);
SumX2 += (x_mts.get(i) * x_mts.get(i));
}
SumY = 0;
for (int i = 0; i < mts_point; i++) {
SumY += y_mts.get(i);
}
SumXY = 0;
for (int i = 0; i < mts_point; i++) {
SumXY += (x_mts.get(i) * y_mts.get(i));
}
float b_mts = ((SumX2 * SumY - SumX * SumXY) / (mts_point * SumX2 - SumX
* SumX));
float k_mts = ((mts_point * SumXY - SumX * SumY) / (mts_point * SumX2 - SumX
* SumX));
// 构造图
double[][] ScatterDatas_pmv = new double[2][pmv_point];
double[][] LineDatas_pmv = new double[2][2];
double[][] ScatterDatas_mts = new double[2][mts_point];
double[][] LineDatas_mts = new double[2][2];
DefaultXYDataset LineDataset_pmv = new DefaultXYDataset();
DefaultXYDataset ScatterDataset_pmv = new DefaultXYDataset();
DefaultXYDataset LineDataset_mts = new DefaultXYDataset();
DefaultXYDataset ScatterDataset_mts = new DefaultXYDataset();
for (int i = 0; i < mts_point; i++) {
ScatterDatas_mts[0][i] = x_mts.get(i);
ScatterDatas_mts[1][i] = y_mts.get(i);
}
for (int i = 0; i < pmv_point; i++) {
ScatterDatas_pmv[0][i] = x_pmv.get(i);
ScatterDatas_pmv[1][i] = y_pmv.get(i);
}
float LineXMax_pmv = x_pmv.get(0);
float LineXMin_pmv = x_pmv.get(0);
float LineXMax_mts = x_mts.get(0);
float LineXMin_mts = x_mts.get(0);
for (int i = 0; i < pmv_point; i++) {
if (LineXMax_pmv < x_pmv.get(i))
LineXMax_pmv = x_pmv.get(i);
if (LineXMin_pmv > x_pmv.get(i))
LineXMin_pmv = x_pmv.get(i);
}
float LineYMax_pmv = LineXMax_pmv * k_pmv + b_pmv;
for (int i = 0; i < mts_point; i++) {
if (LineXMax_mts < x_mts.get(i))
LineXMax_mts = x_mts.get(i);
if (LineXMin_mts > x_mts.get(i))
LineXMin_mts = x_mts.get(i);
}
float LineYMax_mts = LineXMax_mts * k_mts + b_mts;
// 最大值点
// 算最小值
float LineYMin_pmv = LineXMin_pmv * k_pmv + b_pmv;
float LineYMin_mts = LineXMin_mts * k_mts + b_mts;
LineDatas_pmv[0][0] = LineXMin_pmv;
LineDatas_pmv[1][0] = LineYMin_pmv;
LineDatas_pmv[0][1] = LineXMax_pmv;
LineDatas_pmv[1][1] = LineYMax_pmv;
LineDatas_mts[0][0] = LineXMin_mts;
LineDatas_mts[1][0] = LineYMin_mts;
LineDatas_mts[0][1] = LineXMax_mts;
LineDatas_mts[1][1] = LineYMax_mts;
// 加载数据集
ScatterDataset_pmv.addSeries("AAAAA", ScatterDatas_pmv);
ScatterDataset_mts.addSeries("BBBBB", ScatterDatas_mts);
LineDataset_pmv.addSeries("线性(AAAAA)", LineDatas_pmv);
LineDataset_mts.addSeries("线性(AAAAA)", LineDatas_mts);
// pmv
JFreeChart chart = ChartFactory.createScatterPlot("ABABABABAB",
"qqqqqqqqq", "AAAAA", ScatterDataset_pmv, PlotOrientation.VERTICAL,
true, false, false);
XYPlot xyplot = chart.getXYPlot();// 图本身
xyplot.setDataset(1, ScatterDataset_pmv);
xyplot.setDataset(2, LineDataset_pmv);// 放折线图数据
// plot.getRenderer().setSeriesPaint(0, Color.black) ;
XYDotRenderer xydotrenderer1 = new XYDotRenderer();
xydotrenderer1
.setBaseToolTipGenerator(new StandardXYToolTipGenerator());
xyplot.setRenderer(1, xydotrenderer1);
XYLineAndShapeRenderer xylineandshaperenderer1 = new XYLineAndShapeRenderer();
xylineandshaperenderer1
.setBaseToolTipGenerator(new StandardXYToolTipGenerator());
xylineandshaperenderer1.setSeriesPaint(0, Color.BLUE);
//xyplot.getRenderer(0).setSeriesPaint(0, Color.BLUE);//设置点颜色
xyplot.setRenderer(2, xylineandshaperenderer1);
xyplot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);
ChartFrame chartFrame = new ChartFrame("AAAAA", chart);
// chart要放在Java容器组件中,ChartFrame继承自java的Jframe类。
//该第一个参数的数据是放在窗口左上角的,不是正中间的标题。
chartFrame.pack(); // 以合适的大小展现图形
chartFrame.setVisible(true);// 图形是否可见
// 依据mts画图
JFreeChart chartmts = ChartFactory.createScatterPlot(
"ABABABABAB", "qqqqqqqqq", "BBBBB", ScatterDataset_mts,
PlotOrientation.VERTICAL, true, false, false);
XYPlot xyplotmts = chartmts.getXYPlot();// 图本身
xyplotmts.setDataset(1, ScatterDataset_mts);
xyplotmts.setDataset(2, LineDataset_mts);
XYDotRenderer xydotrenderermts1 = new XYDotRenderer();
xydotrenderermts1
.setBaseToolTipGenerator(new StandardXYToolTipGenerator());
xyplotmts.setRenderer(1, xydotrenderermts1);
XYLineAndShapeRenderer xylineandshaperenderermts1 = new XYLineAndShapeRenderer();
xylineandshaperenderermts1
.setBaseToolTipGenerator(new StandardXYToolTipGenerator());
xylineandshaperenderermts1.setSeriesPaint(0, Color.RED);
xyplotmts.setRenderer(2, xylineandshaperenderermts1);
xyplotmts.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);
ChartFrame chartFramemts = new ChartFrame("BBBBB", chartmts);
// chart要放在Java容器组件中,ChartFrame继承自java的Jframe类。
//该第一个参数的数据是放在窗口左上角的,不是正中间的标题。
chartFramemts.pack(); // 以合适的大小展现图形
chartFramemts.setVisible(true);// 图形是否可见
try {
ChartUtilities.saveChartAsPNG(new File("E:/chart/chart1.png"),
chart, 800, 500);
ChartUtilities.saveChartAsPNG(new File("E:/chart/chart2.png"),
chartmts, 800, 500);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
参考资料
用JFreeChart绘制光滑曲线(二) 简单实现
JFreeChart设置点的颜色
Jfree API
JFreechart 折线图 折线大小、颜色设置、图标大小设置