JFreeChart简单实现光滑曲线绘制

时间:2022-11-23 23:58:07

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

绘制图形:

 JFreeChart简单实现光滑曲线绘制

代码:

fittingcurve.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
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;
 }
 
}

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

原文链接:https://blog.csdn.net/jvl_jevy/article/details/5456232