JFreeChart简单实现光滑曲线绘制
时间:2019-04-20
本文章向大家介绍JFreeChart简单实现光滑曲线绘制,主要包括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; } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
- iBatis.Net(4):DataMapper API
- PHP开发过程的那些坑(四) ——PDO bindParam函数
- iBatis.Net(3):创建SqlMapper实例
- PHP开发过程的那些坑(五) ——PHP的empty()
- iBatis.Net(2):基本概念与配置
- ASP.NET Web API中的依赖注入什么是依赖注入ASP.NET Web API依赖解析器使用Unity解析依赖配置依赖解析
- 解决Entity Framework查询匿名对象后的跨域访问的一种方式
- WebSocket在ASP.NET MVC4中的简单实现
- 在ASP.NET MVC中使用Unity进行依赖注入的三种方式第一种方法第二种方法第三种方法
- Unity Container中的几种注册方式与示例1.实例注册2.简单类型注册
- 使用Unity创建依赖注入依赖注入生命周期:注册、解析、销毁 注册解析销毁
- 使用WCF进行跨平台开发之三(JAVA调用WCF服务)1.开发必备2.生成WCF客户端3.开发程序4.结束语
- 使用WCF进行跨平台开发之二(IIS托管WCF服务并使用php平台调用)1.系统必备2.在IIS中托管WCF服务3.使用PHP调用托管在IIS中的WCF服务
- 使用WCF进行跨平台开发之一(WCF的实现、控制台托管与.net平台的调用)1.创建项目结构2.契约的设计3.实现服务4.控制台托管服务5.在.net平台中调用WCF
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Python+selenium 技术篇-浏览器后台运行
- Python 基础篇-python3安装pyHook和pywin32库
- 漫画:如何螺旋遍历二维数组?(修订版)
- 一文快速入门分库分表(必修课)
- 写出漂亮 Python 代码的 20条准则
- 简单red5+obs推流实现直播系统开发,具体设置介绍
- 使用pandas进行数据快捷加载
- 关于 JavaScript 中 null 的一切
- 总结 | DataFrame、Series、array、tensor的创建及相互转化
- 这就是你日日夜夜想要的docker!!!---------Harbor私有仓库
- Go by Example 中文版: 写文件
- PWN:House Of Force
- Windwos10下使用VS2017搭建cocos2d-x 4.0开发环境
- JavaScript 中的函数式编程:函数,组合和柯里化
- 如何设置一个生产级别的高可用etcd集群