欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JFreeChart简单实现光滑曲线绘制

程序员文章站 2023-12-18 20:16:52
用jfreechart绘制光滑曲线,利用最小二乘法数学原理计算,供大家参考,具体内容如下 绘制图形:   代码: fittingcurve.java...

用jfreechart绘制光滑曲线,利用最小二乘法数学原理计算,供大家参考,具体内容如下

绘制图形:

 JFreeChart简单实现光滑曲线绘制

代码:

fittingcurve.java

package org.jevy; 
import java.util.arraylist; 
import java.util.list; 
import org.jfree.chart.chartfactory; 
import org.jfree.chart.chartpanel; 
import org.jfree.chart.jfreechart; 
import org.jfree.chart.axis.valueaxis; 
import org.jfree.chart.plot.plotorientation; 
import org.jfree.chart.plot.xyplot; 
import org.jfree.chart.renderer.xy.xyitemrenderer; 
import org.jfree.chart.renderer.xy.xylineandshaperenderer; 
import org.jfree.data.xy.xydataset; 
import org.jfree.data.xy.xyseries; 
import org.jfree.data.xy.xyseriescollection; 
import org.jfree.ui.applicationframe; 
import org.jfree.ui.refineryutilities; 
public class fittingcurve extends applicationframe{ 
 list<double> equation = null; 
 //设置多项式的次数 
 int times = 2; 
 
 public fittingcurve(string title) { 
 super(title); 
 //使用最小二乘法计算拟合多项式中各项前的系数。 
/* 
请注意: 多项式曲线参数计算 与 chart图表生成 是分开处理的。 
多项式曲线参数计算: 负责计算多项式系数, 返回多项式系数list。 
chart图表生成: 仅仅负责按照给定的数据绘图。 比如对给定的点进行连线。 
  本实例中,光滑的曲线是用密度很高的点连线绘制出来的。 由于我们计算出了多项式的系数,所以我们让x轴数据按照很小的步长增大,针对每一个x值,使用多项式计算出y值, 从而得出点众多的(x,y)组。 把这些(x, y)组成的点连线绘制出来,则显示出光滑的曲线。 
xyseries为jfreechart绘图数据集, 用于绘制一组有关系的数据。 xyseries对应于x,y坐标轴数据集, 添加数据方式为: xyseries s.add(x,y); 
xyseriescollection 为xyseries的集合, 当需要在一个chart上绘制多条曲线的时候,需要把多条曲线对应的xyseries添加到xyseriescollection 
 添加方法:dataset.addseries(s1); 
dataset.addseries(s2); 
*/ 
 //多项式的次数从高到低,该函数需要的参数:x轴数据<list>,y轴数据<list>,多项式的次数<2> 
 this.equation = this.getcurveequation(this.getdata().get(0),this.getdata().get(1),this.times); 
 
//生成chart 
 jfreechart chart = this.getchart(); 
 chartpanel chartpanel = new chartpanel(chart); 
 chartpanel.setpreferredsize(new java.awt.dimension(500, 270)); 
 chartpanel.setmousezoomable(true, false); 
 setcontentpane(chartpanel); 
 } 
 
 public static void main(string[] args) { 
 // todo auto-generated method stub 
 fittingcurve demo = new fittingcurve("xyfittingcurve"); 
 demo.pack(); 
 refineryutilities.centerframeonscreen(demo); 
 demo.setvisible(true); 
 
 } 
 
 //生成chart 
public jfreechart getchart(){ 
 //获取x和y轴数据集 
 xydataset xydataset = this.getxydataset(); 
 //创建用坐标表示的折线图 
 jfreechart xychart = chartfactory.createxylinechart( 
 "二次多项式拟合光滑曲线", "x轴", "y轴", xydataset, plotorientation.vertical, true, true, false); 
 //生成坐标点点的形状 
 xyplot plot = (xyplot) xychart.getplot(); 
 
 xyitemrenderer r = plot.getrenderer(); 
 if (r instanceof xylineandshaperenderer) { 
  xylineandshaperenderer renderer = (xylineandshaperenderer) r; 
  renderer.setbaseshapesvisible(false);//坐标点的形状是否可见 
  renderer.setbaseshapesfilled(false); 
  } 
 valueaxis yaxis = plot.getrangeaxis(); 
 yaxis.setlowermargin(2); 
 return xychart; 
 } 
 
//数据集按照逻辑关系添加到对应的集合 
 public xydataset getxydataset() { 
 //预设数据点数据集 
 xyseries s2 = new xyseries("点点连线"); 
 for(int i=0; i<data.get(0).size(); i++){ 
 s2.add(data.get(0).get(i),data.get(1).get(i)); 
 } 
// 拟合曲线绘制 数据集 xyseries s1 = new xyseries("拟合曲线"); 
 //获取拟合多项式系数,equation在构造方法中已经实例化 
 list<double> list = this.equation; 
 //获取预设的点数据 
 list<list<double>> data = this.getdata(); 
 
 //get max and min of x; 
 list<double> xlist = data.get(0); 
 double max =this.getmax(xlist); 
 double min = this.getmin(xlist); 
 double step = max - min; 
 double x = min; 
 double step2 = step/800.0; 
 //按照多项式的形式 还原多项式,并利用多项式计算给定x时y的值 
 for(int i=0; i<800; i++){ 
 x = x + step2; 
 int num = list.size()-1; 
 double temp = 0.0; 
 for(int j=0; j<list.size(); j++){ 
 temp = temp + math.pow(x, (num-j))*list.get(j); 
 } 
 s1.add(x, temp); 
 } 
 
 //把预设数据集合拟合数据集添加到xyseriescollection 
 xyseriescollection dataset = new xyseriescollection(); 
 dataset.addseries(s1); 
 dataset.addseries(s2); 
 return dataset; 
 
 } 
 //模拟设置绘图数据(点) 
 public list<list<double>> getdata(){ 
 //x为x轴坐标 
 list<double> x = new arraylist<double>(); 
 list<double> y = new arraylist<double>(); 
 for(int i=0; i<10; i++){ 
 x.add(-5.0+i); 
 } 
 y.add(26.0); 
 y.add(17.1); 
 y.add(10.01); 
 y.add(5.0); 
 y.add(2.01); 
 
 y.add(1.0); 
 
 y.add(2.0); 
 y.add(5.01); 
 y.add(10.1); 
 y.add(17.001); 
 
 list<list<double>> list = new arraylist<list<double>>(); 
 list.add(x); 
 list.add(y); 
 return list; 
 
 } 
 
//以下代码为最小二乘法计算多项式系数 
//最小二乘法多项式拟合 
 public list<double> getcurveequation(list<double> x, list<double> y, int m){ 
 if(x.size() != y.size() || x.size() <= m+1){ 
 return new arraylist<double>(); 
 } 
 list<double> result = new arraylist<double>(); 
 list<double> s = new arraylist<double>(); 
 list<double> t = new arraylist<double>(); 
 //计算s0 s1 …… s2m 
 for(int i=0; i<=2*m; i++){ 
 double si = 0.0; 
 for(double xx:x){ 
 si = si + math.pow(xx, i); 
 } 
 s.add(si); 
 } 
 //计算t0 t1 …… tm 
 for(int j=0; j<=m; j++){ 
 double ti = 0.0; 
 for(int k=0; k<y.size(); k++){ 
 ti = ti + y.get(k)*math.pow(x.get(k), j); 
 } 
 t.add(ti); 
 } 
 
 //把s和t 放入二维数组,作为矩阵 
 double[][] matrix = new double[m+1][m+2]; 
 for(int k=0; k<m+1; k++){ 
 double[] matrixi = matrix[k]; 
 for(int q=0; q<m+1; q++){ 
 matrixi[q] = s.get(k+q); 
 } 
 matrixi[m+1] = t.get(k); 
 } 
 for(int p=0; p<matrix.length; p++){ 
 for(int pp=0; pp<matrix[p].length; pp++){ 
 system.out.print(" matrix["+p+"]["+pp+"]="+matrix[p][pp]); 
 } 
 system.out.println(); 
 } 
 //把矩阵转化为三角矩阵 
 matrix = this.matrixconvert(matrix); 
 //计算多项式系数,多项式从高到低排列 
 result = this.matrixcalcu(matrix); 
 return result; 
 } 
 //矩阵转换为三角矩阵 
 public double[][] matrixconvert(double[][] d){ 
 for(int i=0; i<d.length-1; i++){ 
 double[] dd1 = d[i]; 
 double num1 = dd1[i]; 
 
 for(int j=i; j<d.length-1;j++ ){ 
 double[] dd2 = d[j+1]; 
 double num2 = dd2[i]; 
 
 for(int k=0; k<dd2.length; k++){ 
 dd2[k] = (dd2[k]*num1 - dd1[k]*num2); 
 } 
 } 
 } 
 for(int ii=0; ii<d.length; ii++){ 
 for(int kk=0; kk<d[ii].length; kk++) 
 system.out.print(d[ii][kk]+" "); 
 system.out.println(); 
 } 
 return d; 
 } 
 
 //计算一元多次方程前面的系数, 其排列为 xm xm-1 …… x0(多项式次数从高到低排列) 
 public list<double> matrixcalcu(double[][] d){ 
 
 int i = d.length -1; 
 int j = d[0].length -1; 
 list<double> list = new arraylist<double>(); 
 double res = d[i][j]/d[i][j-1]; 
 list.add(res); 
 
 for(int k=i-1; k>=0; k--){ 
 double num = d[k][j]; 
 for(int q=j-1; q>k; q--){ 
 num = num - d[k][q]*list.get(j-1-q); 
 } 
 res = num/d[k][k]; 
 list.add(res); 
 } 
 return list; 
 } 
 
 //获取list中double数据的最大最小值 
 public double getmax(list<double> data){ 
 double res = data.get(0); 
 for(int i=0; i<data.size()-1; i++){ 
 if(res<data.get(i+1)){ 
 res = data.get(i+1); 
 } 
 } 
 return res; 
 } 
 public double getmin(list<double> data){ 
 double res = data.get(0); 
 for(int i=0; i<data.size()-1; i++){ 
 if(res>data.get(i+1)){ 
 res = data.get(i+1); 
 } 
 } 
 return res; 
 } 
 
} 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

上一篇:

下一篇: