Soil Acidification Iterative Evolution.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. import * as echarts from '../../components/ec-canvas/echarts';
  2. Page({
  3. data: {
  4. ecLine: {
  5. onInit: function (canvas, width, height, dpr) {
  6. const lineChart = echarts.init(canvas, null, {
  7. width: width,
  8. height: height,
  9. devicePixelRatio: dpr // new
  10. });
  11. canvas.setChart(lineChart);
  12. lineChart.setOption(getLineOption());
  13. return lineChart;
  14. }
  15. },
  16. ecInitScatter: {
  17. onInit: function (canvas, width, height, dpr) {
  18. const initScatter = echarts.init(canvas, null, {
  19. width: width,
  20. height: height,
  21. devicePixelRatio: dpr // new
  22. });
  23. canvas.setChart(initScatter);
  24. initScatter.setOption(getInitScatterOption());
  25. return initScatter;
  26. }
  27. },
  28. ecMidScatter: {
  29. onInit: function (canvas, width, height, dpr) {
  30. const midScatter = echarts.init(canvas, null, {
  31. width: width,
  32. height: height,
  33. devicePixelRatio: dpr // new
  34. });
  35. canvas.setChart(midScatter);
  36. midScatter.setOption(getMidScatterOption());
  37. return midScatter;
  38. }
  39. },
  40. ecFinalScatter: {
  41. onInit: function (canvas, width, height, dpr) {
  42. const finalScatter = echarts.init(canvas, null, {
  43. width: width,
  44. height: height,
  45. devicePixelRatio: dpr // new
  46. });
  47. canvas.setChart(finalScatter);
  48. finalScatter.setOption(getFinalScatterOption());
  49. return finalScatter;
  50. }
  51. },
  52. },
  53. onReady() {
  54. // You can add any additional logic here if needed
  55. }
  56. });
  57. // 反酸模型 初代 散点图
  58. function getInitScatterOption() {
  59. /**
  60. * 计算数据的最大最小值
  61. * @param {Array} data - 散点数据数组
  62. * @returns {Object} 包含 xMin, xMax, yMin, yMax 的对象
  63. */
  64. const calculateDataRange = (data) => {
  65. let xValues = data.map(item => item[0]);
  66. let yValues = data.map(item => item[1]);
  67. return {
  68. xMin: Math.min(...xValues),
  69. xMax: Math.max(...xValues),
  70. yMin: Math.min(...yValues),
  71. yMax: Math.max(...yValues)
  72. };
  73. };
  74. const scatterData = [[-0.003333333333333854, -0.4181333333333324], [-0.1733333333333329, -0.26733333333333265], [-0.6233333333333331, -0.3718666666666661], [-0.7088888888888892, -0.3854666666666661], [-0.3366666666666669, -0.3998666666666657], [-0.8888888888888887, -0.36439999999999934], [-0.5633333333333326, -0.6207999999999997], [-0.7333333333333325, -0.36026666666666607], [-0.3366666666666663, -0.29213333333333275], [-1.176666666666666, -0.6095999999999993], [-0.7122222222222225, -0.3807999999999989], [-0.7699999999999996, -0.3718666666666661]];
  75. const range = calculateDataRange(scatterData);
  76. const padding = 0.1;
  77. const xMin = range.xMin - Math.abs(range.xMin * padding);
  78. const xMax = range.xMax + Math.abs(range.xMax * padding);
  79. const yMin = range.yMin - Math.abs(range.yMin * padding);
  80. const yMax = range.yMax + Math.abs(range.yMax * padding);
  81. const min = Math.min(xMin, yMin)
  82. const max = Math.max(xMax, yMax)
  83. return {
  84. tooltip: {
  85. trigger: 'axis',
  86. axisPointer: {
  87. type: 'cross'
  88. }
  89. },
  90. legend: {
  91. data: ['True vs Predicted']
  92. },
  93. grid: {
  94. left: '3%',
  95. right: '22%',
  96. bottom: '3%',
  97. containLabel: true
  98. },
  99. xAxis: {
  100. name: 'True Values',
  101. type: 'value',
  102. min: min,
  103. max: max
  104. },
  105. yAxis: {
  106. name: 'Predicted Values',
  107. type: 'value',
  108. min: parseFloat(min).toFixed(2),
  109. max: parseFloat(max).toFixed(2)
  110. },
  111. series: [
  112. {
  113. name: 'True vs Predicted',
  114. type: 'scatter',
  115. data: scatterData,
  116. symbolSize: 10,
  117. itemStyle: {
  118. color: '#1f77b4',
  119. opacity: 0.7
  120. }
  121. },
  122. {
  123. name: 'Trendline',
  124. type: 'line',
  125. data: [
  126. [min, min],
  127. [max, max]
  128. ],
  129. lineStyle: {
  130. type: 'dashed',
  131. color: '#ff7f0e',
  132. width: 2
  133. }
  134. }
  135. ]
  136. };
  137. }
  138. // 反酸模型 中间代 散点图
  139. function getMidScatterOption() {
  140. /**
  141. * 计算数据的最大最小值
  142. * @param {Array} data - 散点数据数组
  143. * @returns {Object} 包含 xMin, xMax, yMin, yMax 的对象
  144. */
  145. const calculateDataRange = (data) => {
  146. let xValues = data.map(item => item[0]);
  147. let yValues = data.map(item => item[1]);
  148. return {
  149. xMin: Math.min(...xValues),
  150. xMax: Math.max(...xValues),
  151. yMin: Math.min(...yValues),
  152. yMax: Math.max(...yValues)
  153. };
  154. };
  155. const scatterData = [[-0.003333333333333854, -0.5483999999999993], [-0.1733333333333329, -0.2093333333333331], [-0.6233333333333331, -0.5090000000000002], [-0.7088888888888892, -0.4281333333333331], [-0.3366666666666669, -0.4691333333333336], [-0.8888888888888887, -0.49643333333333267], [-0.5633333333333326, -0.7191999999999996], [-0.7333333333333325, -0.5024666666666666], [-0.3366666666666663, -0.37796666666666623], [-1.176666666666666, -0.6415666666666656], [-0.7122222222222225, -0.43299999999999966], [-0.7699999999999996, -0.499966666666667]];
  156. const range = calculateDataRange(scatterData);
  157. const padding = 0.1;
  158. const xMin = range.xMin - Math.abs(range.xMin * padding);
  159. const xMax = range.xMax + Math.abs(range.xMax * padding);
  160. const yMin = range.yMin - Math.abs(range.yMin * padding);
  161. const yMax = range.yMax + Math.abs(range.yMax * padding);
  162. const min = Math.min(xMin, yMin)
  163. const max = Math.max(xMax, yMax)
  164. return {
  165. tooltip: {
  166. trigger: 'axis',
  167. axisPointer: {
  168. type: 'cross'
  169. }
  170. },
  171. legend: {
  172. data: ['True vs Predicted']
  173. },
  174. grid: {
  175. left: '3%',
  176. right: '22%',
  177. bottom: '3%',
  178. containLabel: true
  179. },
  180. xAxis: {
  181. name: 'True Values',
  182. type: 'value',
  183. min: min,
  184. max: max
  185. },
  186. yAxis: {
  187. name: 'Predicted Values',
  188. type: 'value',
  189. min: parseFloat(min).toFixed(2),
  190. max: parseFloat(max).toFixed(2)
  191. },
  192. series: [
  193. {
  194. name: 'True vs Predicted',
  195. type: 'scatter',
  196. data: scatterData,
  197. symbolSize: 10,
  198. itemStyle: {
  199. color: '#1f77b4',
  200. opacity: 0.7
  201. }
  202. },
  203. {
  204. name: 'Trendline',
  205. type: 'line',
  206. data: [
  207. [min, min],
  208. [max, max]
  209. ],
  210. lineStyle: {
  211. type: 'dashed',
  212. color: '#ff7f0e',
  213. width: 2
  214. }
  215. }
  216. ]
  217. };
  218. }
  219. // 反酸模型 最终代 散点图
  220. function getFinalScatterOption() {
  221. /**
  222. * 计算数据的最大最小值
  223. * @param {Array} data - 散点数据数组
  224. * @returns {Object} 包含 xMin, xMax, yMin, yMax 的对象
  225. */
  226. const calculateDataRange = (data) => {
  227. let xValues = data.map(item => item[0]);
  228. let yValues = data.map(item => item[1]);
  229. return {
  230. xMin: Math.min(...xValues),
  231. xMax: Math.max(...xValues),
  232. yMin: Math.min(...yValues),
  233. yMax: Math.max(...yValues)
  234. };
  235. };
  236. const scatterData = [[-0.003333333333333854, -0.45726666666666654], [-0.1733333333333329, -0.1726333333333331],
  237. [-0.6233333333333331, -0.5226666666666667], [-0.7088888888888892, -0.4791888888888889],
  238. [-0.3366666666666669, -0.3630666666666673], [-0.8888888888888887, -0.48272222222222183],
  239. [-0.5633333333333326, -0.7492444444444444], [-0.7333333333333325, -0.5572666666666672],
  240. [-0.3366666666666663, -0.29379999999999984], [-1.176666666666666, -0.8544111111111106],
  241. [-0.7122222222222225, -0.4959777777777775], [-0.7699999999999996, -0.6149666666666669]];
  242. const range = calculateDataRange(scatterData);
  243. const padding = 0.1;
  244. const xMin = range.xMin - Math.abs(range.xMin * padding);
  245. const xMax = range.xMax + Math.abs(range.xMax * padding);
  246. const yMin = range.yMin - Math.abs(range.yMin * padding);
  247. const yMax = range.yMax + Math.abs(range.yMax * padding);
  248. const min = Math.min(xMin, yMin)
  249. const max = Math.max(xMax, yMax)
  250. return {
  251. tooltip: {
  252. trigger: 'axis',
  253. axisPointer: {
  254. type: 'cross'
  255. }
  256. },
  257. legend: {
  258. data: ['True vs Predicted']
  259. },
  260. grid: {
  261. left: '3%',
  262. right: '22%',
  263. bottom: '3%',
  264. containLabel: true
  265. },
  266. xAxis: {
  267. name: 'True Values',
  268. type: 'value',
  269. min: min,
  270. max: max
  271. },
  272. yAxis: {
  273. name: 'Predicted Values',
  274. type: 'value',
  275. min: parseFloat(min).toFixed(2),
  276. max: parseFloat(max).toFixed(2)
  277. },
  278. series: [
  279. {
  280. name: 'True vs Predicted',
  281. type: 'scatter',
  282. data: scatterData,
  283. symbolSize: 10,
  284. itemStyle: {
  285. color: '#1f77b4',
  286. opacity: 0.7
  287. }
  288. },
  289. {
  290. name: 'Trendline',
  291. type: 'line',
  292. data: [
  293. [min, min],
  294. [max, max]
  295. ],
  296. lineStyle: {
  297. type: 'dashed',
  298. color: '#ff7f0e',
  299. width: 2
  300. }
  301. }
  302. ]
  303. };
  304. }
  305. function getLineOption() {
  306. return {
  307. tooltip: {
  308. trigger: 'axis'
  309. },
  310. legend: {
  311. data: ['Random Forest', 'XGBoost', 'Gradient Boosting'] // 模型名称
  312. },
  313. grid: {
  314. left: '3%',
  315. right: '17%',
  316. bottom: '3%',
  317. containLabel: true
  318. },
  319. xAxis: {
  320. name: '模型迭代',
  321. type: 'category',
  322. boundaryGap: false,
  323. data: ['1代','2代','3代','4代','5代','6代','7代','8代','9代'] // train_sizes按10%递增
  324. },
  325. yAxis: {
  326. name: 'Score (R^2)',
  327. type: 'value'
  328. },
  329. series: [
  330. {
  331. name: 'Random Forest',
  332. type: 'line',
  333. data: [-0.17101591951095463, -0.556719360354051, -0.04083550751401055, -0.20858221504075436, 0.07297292282221035, 0.19857845644421734, 0.28407131176770184, 0.27979356883596496, 0.36904808817286416, 0.4183018571701477] // 使用您的实际R2分数数据
  334. },
  335. {
  336. name: 'XGBoost',
  337. type: 'line',
  338. data: [-1.1811781145886937, -1.5645641005612534, -0.12619079632263497, 0.03324096120721032, 0.06969290639267578, 0.12375262461601955, 0.5331670468884062, 0.49454793164801647, 0.31904329339597803, 0.2712670704381914]
  339. },
  340. {
  341. name: 'Gradient Boosting',
  342. type: 'line',
  343. data: [-0.8583039298789095, -1.073316171952042, 0.09659300885027666, 0.06097833957434784, 0.191975498544109, 0.3718334600546489, 0.3948098332187753, 0.4398778520728397, 0.452609022210963, 0.41484634172723023]
  344. }
  345. ]
  346. };
  347. }