ararpy 0.1.199__py3-none-any.whl → 0.2.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. ararpy/Example - Check arr.py +52 -0
  2. ararpy/Example - Granite Cooling History.py +411 -0
  3. ararpy/Example - Plot temperature calibration.py +291 -0
  4. ararpy/Example - Show MDD results.py +561 -0
  5. ararpy/Example - Show all Kfs age spectra.py +344 -0
  6. ararpy/Example - Show random walk results.py +363 -0
  7. ararpy/Example - Tc calculation.py +437 -0
  8. ararpy/__init__.py +3 -4
  9. ararpy/calc/age.py +34 -36
  10. ararpy/calc/arr.py +0 -20
  11. ararpy/calc/basic.py +26 -3
  12. ararpy/calc/corr.py +131 -85
  13. ararpy/calc/jvalue.py +7 -5
  14. ararpy/calc/plot.py +1 -2
  15. ararpy/calc/raw_funcs.py +41 -2
  16. ararpy/calc/regression.py +224 -132
  17. ararpy/files/arr_file.py +2 -1
  18. ararpy/files/basic.py +0 -22
  19. ararpy/files/calc_file.py +107 -84
  20. ararpy/files/raw_file.py +242 -229
  21. ararpy/smp/basic.py +133 -34
  22. ararpy/smp/calculation.py +6 -6
  23. ararpy/smp/corr.py +339 -153
  24. ararpy/smp/diffusion_funcs.py +345 -36
  25. ararpy/smp/export.py +247 -129
  26. ararpy/smp/info.py +2 -2
  27. ararpy/smp/initial.py +93 -45
  28. ararpy/smp/json.py +2 -2
  29. ararpy/smp/plots.py +144 -164
  30. ararpy/smp/raw.py +11 -15
  31. ararpy/smp/sample.py +222 -181
  32. ararpy/smp/style.py +26 -7
  33. ararpy/smp/table.py +42 -33
  34. ararpy/thermo/atomic_level_random_walk.py +56 -48
  35. ararpy/thermo/basic.py +2 -2
  36. {ararpy-0.1.199.dist-info → ararpy-0.2.2.dist-info}/METADATA +10 -1
  37. ararpy-0.2.2.dist-info/RECORD +73 -0
  38. {ararpy-0.1.199.dist-info → ararpy-0.2.2.dist-info}/WHEEL +1 -1
  39. ararpy-0.1.199.dist-info/RECORD +0 -66
  40. {ararpy-0.1.199.dist-info → ararpy-0.2.2.dist-info}/licenses/LICENSE +0 -0
  41. {ararpy-0.1.199.dist-info → ararpy-0.2.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,561 @@
1
+ # Copyright (C) 2025 Yang. - All Rights Reserved
2
+
3
+ #!/usr/bin/env python
4
+ # -*- coding: UTF-8 -*-
5
+ """
6
+ # ==========================================
7
+ # Copyright 2025 Yang
8
+ # ararpy - Example - Show MDD results
9
+ # ==========================================
10
+ #
11
+ #
12
+ #
13
+ """
14
+ import ararpy as ap
15
+ import numpy as np
16
+ import pdf_maker as pm
17
+ import os
18
+
19
+ import matplotlib
20
+ from matplotlib.collections import PathCollection
21
+
22
+ matplotlib.use('TkAgg')
23
+ matplotlib.rc('font',family='Arial', size=10)
24
+ import matplotlib.pyplot as plt
25
+ # 设置全局字体,确保中文正常显示
26
+ # plt.rcParams["font.family"] = ["SimHei"] # 中文字体
27
+ # plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
28
+
29
+
30
+
31
+ def conf(input_x, input_y, num=None, using_binom=False, using_normal=False, start=None, end=None):
32
+ """
33
+ Calculate 90% confident interval of the given distribution of cooling histories.
34
+ Parameters
35
+ ----------
36
+ input_x: x, array like 2D
37
+ input_y: y, array like 2D
38
+ count:
39
+
40
+ Returns
41
+ -------
42
+
43
+ """
44
+
45
+ if len(input_x) != len(input_y):
46
+ raise ValueError("length of input x does not equal to that of input y")
47
+
48
+ ns = len(input_x)
49
+ if start is None:
50
+ start = min([min(i) for i in input_x])
51
+ if end is None:
52
+ end = max([max(i) for i in input_x])
53
+ nt = 18 if num is None else num
54
+
55
+ if not (using_normal or using_binom):
56
+ using_binom = True
57
+
58
+ x_conf = np.linspace(start, end, num=nt)
59
+ y_conf = np.zeros((nt, 4))
60
+ ytemp = np.zeros((nt, ns))
61
+ # 初始化数组
62
+ xmed = np.zeros(nt)
63
+ ave = np.zeros(nt)
64
+ adev = np.zeros(nt)
65
+ sdev = np.zeros(nt)
66
+ var = np.zeros(nt)
67
+ skew = np.zeros(nt)
68
+ curt = np.zeros(nt)
69
+
70
+ # 计算每个曲线的温度值
71
+ for k, out_x in enumerate(x_conf):
72
+ for i in range(ns):
73
+ xs = input_x[i]
74
+ ys = input_y[i]
75
+ for j in range(len(xs)-1):
76
+ if xs[j] >= out_x >= xs[j+1]:
77
+ ytemp[k, i] = (ys[j+1] - ys[j]) / (xs[j+1] - xs[j]) * (out_x - xs[j]) + ys[j]
78
+ break
79
+ # 排序
80
+ ytemp[k] = np.sort(ytemp[k])
81
+ # 计算均值、中位数
82
+ ave[k], adev[k], sdev[k], var[k], skew[k], curt[k], xmed[k] = stats = moment(ytemp[k])
83
+ # 计算置信区间索引
84
+ if using_binom:
85
+ j1, j2 = ap.smp.diffusion_funcs.binom(ns) #
86
+ j3, j4 = int(round(ns * 0.05)) - 1, int(ns - round(ns * 0.05)) - 1 # 95%
87
+ y1, y2, y3, y4 = ytemp[k][j1], ytemp[k][j2], ytemp[k][j3], ytemp[k][j4]
88
+ elif using_normal:
89
+ y1, y2, y3, y4 = ave[k] - sdev[k], ave[k] + sdev[k], ave[k] - 2 * sdev[k], ave[k] + 2 * sdev[k]
90
+ else:
91
+ raise KeyError("use binom or using normal")
92
+ y_conf[k] = [y1, y2, y3, y4]
93
+ return x_conf, y_conf
94
+
95
+
96
+ def moment(data):
97
+ """ 计算分布的统计矩阵:均值、平均偏差、标准差、方差、偏度、峰度、中位数 """
98
+ # 去除NaN值
99
+ data = data[~np.isnan(data)]
100
+ n = len(data)
101
+ if n == 0:
102
+ return [np.nan] * 7
103
+
104
+ mean = np.mean(data)
105
+ adev = np.mean(np.abs(data - mean)) # 平均偏差
106
+ sdev = np.std(data, ddof=1) # 样本标准差
107
+ var = sdev ** 2 # 方差
108
+ med = np.median(data) # 中位数
109
+
110
+ # 偏度 (三阶矩)
111
+ if sdev == 0:
112
+ skew = 0.0
113
+ else:
114
+ skew = np.sum(((data - mean) / sdev) ** 3) / n
115
+
116
+ # 峰度 (四阶矩)
117
+ if sdev == 0:
118
+ curt = 0.0
119
+ else:
120
+ curt = np.sum(((data - mean) / sdev) ** 4) / n - 3.0 # 减去3使正态分布峰度为0
121
+
122
+ return mean, adev, sdev, var, skew, curt, med
123
+
124
+
125
+ def is_number(s):
126
+ try:
127
+ float(s)
128
+ return True
129
+ except ValueError:
130
+ return False
131
+
132
+
133
+ def read_mages_in(file):
134
+ mf = np.zeros([1000, 200], dtype=np.float64)
135
+ mage = np.zeros([1000, 200], dtype=np.float64)
136
+
137
+ cyc_count = 0
138
+ max_step = 0
139
+ new_cyc = True
140
+ while new_cyc:
141
+ new_cyc = False
142
+ for step in range(200):
143
+ try:
144
+ line = file.readline().rstrip("\n")
145
+ # print(f"{step = }, {line = }")
146
+ if line == "":
147
+ break
148
+ if "&" in line:
149
+ raise KeyError
150
+ f, age = [float(l) for l in filter(lambda x: is_number(x), [m for k in line.split('\t') for m in str(k).split(' ')])]
151
+ except KeyError as e:
152
+ new_cyc = True
153
+ break
154
+ except (Exception, BaseException) as e:
155
+ break
156
+ else:
157
+ mf[cyc_count, step], mage[cyc_count, step] = f, age
158
+ max_step = [max_step, step+1][(step+1) > max_step]
159
+ cyc_count += 1
160
+ return mf, mage, cyc_count, max_step
161
+
162
+
163
+ def read_IN(file):
164
+ data = []
165
+ rows = []
166
+ go = True
167
+ while go:
168
+ go = False
169
+ group = np.zeros([200, 20], dtype=np.float64)
170
+ row = 0
171
+ while True:
172
+ try:
173
+ line = file.readline().rstrip("\n")
174
+ if line == "":
175
+ break
176
+ if "&" in line:
177
+ go = True
178
+ raise KeyError
179
+ for col, _ in enumerate([float(l) for l in filter(lambda x: is_number(x), [l for k in line.split('\t') for m in str(k).split(',') for l in str(m).split(' ')])]):
180
+ group[row][col] = _
181
+ except (Exception, BaseException) as e:
182
+ break
183
+ else:
184
+ row += 1
185
+ data.append(group)
186
+ rows.append(row)
187
+ return data, rows
188
+
189
+
190
+ def plot_MDD_res(loc, sname=None, title="", **params):
191
+
192
+
193
+ # file_agesd_in = open(os.path.join(loc, f"{sname}_ages-sd.samp"), "r")
194
+ # file_mages_in = open(os.path.join(loc, f"{sname}_mages-out.dat"), "r")
195
+ # file_mch_in = open(os.path.join(loc, f"{sname}_mch-out.dat"), "r")
196
+ # file_IN = open(os.path.join(loc, f"{sname}.IN"), "r")
197
+ # lab_arr = open(os.path.join(loc, f"{sname}.ar0"), "r")
198
+ # auto_arr = open(os.path.join(loc, f"{sname}.ar1"), "r")
199
+
200
+ initial_age = params.pop("initial_age", 0)
201
+ final_age = params.pop("final_age", 20)
202
+ x1_extent = params.pop("x1_extent", [0, 100])
203
+ y1_extent = params.pop("y1_extent", [0, final_age])
204
+ x2_extent = params.pop("x2_extent", [initial_age, final_age])
205
+ y2_extent = params.pop("y2_extent", [0, 500])
206
+ x3_extent = params.pop("x3_extent", [4, 16])
207
+ y3_extent = params.pop("y3_extent", [-10, 0])
208
+ x4_extent = params.pop("x4_extent", [0, 1000])
209
+ y4_extent = params.pop("y4_extent", [200, 1600])
210
+ autoscaling = params.pop("autoscaling", False)
211
+ export_PDF = params.pop("export_PDF", True)
212
+ index = params.pop("index", [])
213
+
214
+ main_color = ['#397DA1', '#BA5624', '#212121', '#6C5D1E', '#BC3D85', '#3C6933'] # blue red black
215
+ middle_color = ['#83CDFA', '#F1B595', '#737373', '#C0A737', '#E9CDE1', '#84B775']
216
+ shallow_color = ['#E0F1FE', '#FBEBE3', '#DDDDDD', '#F9E16F', '#CB73B0', '#B8F1A7']
217
+
218
+ if sname is None:
219
+ for root, dirs, files in os.walk(loc):
220
+ for file in files:
221
+ if file.lower().endswith('.ame'):
222
+ sname = file.split('.')[0]
223
+ if sname is None:
224
+ raise ValueError(f"{sname = }, is not allowed")
225
+
226
+ print(f"{sname = }, {title = }")
227
+
228
+ file_IN = open(os.path.join(loc, f"{sname}.IN"), "r")
229
+ [data], [nstep] = read_IN(file_IN)
230
+
231
+ fig, axs = plt.subplots(2, 2, figsize=(12, 8))
232
+
233
+ font_settings = {
234
+ # 'fontsize': 10,
235
+ # 'fontfamily': 'Arial'
236
+ }
237
+
238
+ try:
239
+ # file_agesd_in = open(os.path.join(loc, f"{sname}_ages-sd.samp"), "r")
240
+ # f, age, _, n2 = read_mages_in(file_agesd_in)
241
+ # axs[0, 0].plot(f[0][:n2], age[0][:n2], c='blue', linewidth=2, label='Lab. Age spectrum')
242
+ file_mages_in = open(os.path.join(loc, f"{sname}_mages-out.dat"), "r")
243
+ mf, mage, cyc_count, max_step = read_mages_in(file_mages_in)
244
+ axs[0, 0].set_xlim(*x1_extent, auto=autoscaling)
245
+ axs[0, 0].set_ylim(*y1_extent, auto=autoscaling)
246
+ for cyc in range(cyc_count):
247
+ if cyc == 0:
248
+ axs[0, 0].plot(mf[cyc][:max_step], mage[cyc][:max_step], c=main_color[1], label=f'MDD calculation (n={cyc_count})')
249
+ else:
250
+ axs[0, 0].plot(mf[cyc][:max_step], mage[cyc][:max_step], c=main_color[1])
251
+ k0, k1, k2 = ap.calc.spectra.get_data(y=data[:nstep,6], sy=data[:nstep,7], x=np.cumsum(data[:nstep,3]) / np.sum(data[:nstep,3]) * 100, cumulative=True)
252
+ axs[0, 0].plot(k0, k1, c=middle_color[2], linewidth=2, label='Lab. Age spectrum')
253
+ axs[0, 0].plot(k0, k2, c=middle_color[2], linewidth=2)
254
+ axs[0, 0].set_title(f'Age Spectra - {title}', loc='center', y=1, **font_settings)
255
+ axs[0, 0].set_xlabel(f'Cumulative 39Ar Released (%)', **font_settings)
256
+ axs[0, 0].set_ylabel(f'Apparent Age (Ma)', **font_settings)
257
+ axs[0, 0].legend(loc='lower right')
258
+ except FileNotFoundError:
259
+ pass
260
+
261
+ try:
262
+ time = np.cumsum(data[:nstep, 2])
263
+ # temp = data[:nstep, 1]
264
+ temp = data[:nstep, 5]
265
+ axs[1, 1].set_xlim(*x4_extent, auto=autoscaling)
266
+ axs[1, 1].set_ylim(*y4_extent, auto=autoscaling)
267
+ axs[1, 1].plot(time, temp, c=main_color[0], linewidth=2, marker="s", markerfacecolor=shallow_color[0])
268
+ axs[1, 1].set_title(f'Heating Schedule - {title}', loc='center', pad=-20, **font_settings)
269
+ axs[1, 1].set_xlabel(f'Time (min)', **font_settings)
270
+ axs[1, 1].set_ylabel(f'Temperature (°C)', **font_settings) #
271
+ except:
272
+ pass
273
+
274
+ try:
275
+ lab_arr = open(os.path.join(loc, f"{sname}.ar0"), "r")
276
+ auto_arr = open(os.path.join(loc, f"{sname}.ar1"), "r")
277
+ [lab_data], [lab_row] = read_IN(lab_arr)
278
+ axs[1, 0].set_xlim(*x3_extent, auto=autoscaling)
279
+ axs[1, 0].set_ylim(*y3_extent, auto=autoscaling)
280
+ axs[1, 0].scatter(lab_data[:lab_row, 0], lab_data[:lab_row, 1], c=middle_color[2], marker="s", label='Lab. Arrhenius')
281
+ data, rows = read_IN(auto_arr)
282
+ for i, row in enumerate(rows):
283
+ if i == 0:
284
+ axs[1, 0].scatter(data[i][:row, 0].flatten(), data[i][:row, 1].flatten(), c=main_color[1], marker="s", label='MDD calculation')
285
+ else:
286
+ axs[1, 0].scatter(data[i][:row, 0].flatten(), data[i][:row, 1].flatten(), c=main_color[1], marker="s")
287
+ if index:
288
+ index = np.s_[index]
289
+ axs[1, 0].scatter(lab_data[index, 0], lab_data[index, 1], c=main_color[0], marker="s", label='Lab. values used for linear fit')
290
+ b, sb, _, r2, mswd, [b, m], [sb, sm], _, _ = ap.calc.regression.linest(lab_data[index, 1], lab_data[index, 0])
291
+ d0r2 = 10 ** b * ap.thermo.basic.SEC2YEAR # k1: da2
292
+ e = -10 * m * ap.thermo.basic.GAS_CONSTANT * np.log(10) # activation energy, kJ
293
+ tc, _ = ap.thermo.basic.get_tc(da2=d0r2, sda2=0, E=e * 1000, sE=0, pho=0, cooling_rate=20, A=27) # plane
294
+ axs[1, 0].plot(axs[1, 0].get_xlim(), [axs[1, 0].get_xlim()[0] * m + b, axs[1, 0].get_xlim()[1] * m + b], c=main_color[0], linewidth=2)
295
+ axs[1, 0].text(11, -3, f"log(D0/r2) = {b:.2f}\nE = {e/4.184:.2f} kcal/mol\nTc = {tc:.2f} °C", **font_settings)
296
+ axs[1, 0].set_title(f'Arrhenius Plot - {title}', loc='center', pad=-20, **font_settings)
297
+ axs[1, 0].set_xlabel(f'10000 / T (10000/K)', **font_settings)
298
+ axs[1, 0].set_ylabel(f'log(D/r2)', **font_settings) #
299
+ axs[1, 0].legend(loc='lower left')
300
+ except FileNotFoundError:
301
+ pass
302
+
303
+ try:
304
+ start = initial_age
305
+ end = final_age
306
+ file_mch_in = open(os.path.join(loc, f"{sname}_mch-out.dat"), "r")
307
+ data, rows = read_IN(file_mch_in)
308
+ input_x = []
309
+ input_y = []
310
+ axs[0, 1].set_xlim(*x2_extent, auto=autoscaling)
311
+ axs[0, 1].set_ylim(*y2_extent, auto=autoscaling)
312
+ for i, row in enumerate(rows):
313
+ if row < 5:
314
+ continue
315
+ input_x.append(data[i][:row, 0].flatten())
316
+ input_y.append(data[i][:row, 1].flatten())
317
+ if i == 0:
318
+ axs[0, 1].plot(input_x[-1], input_y[-1], c=shallow_color[2], marker="none", label=f'Cooling history simulations (n={len(rows)})')
319
+ else:
320
+ axs[0, 1].plot(input_x[-1], input_y[-1], c=shallow_color[2], marker="none")
321
+ axs[0, 1].set_title(f'Cooling History - {title}', loc='center', **font_settings)
322
+ axs[0, 1].set_xlabel(f'Age (Ma)', **font_settings)
323
+ axs[0, 1].set_ylabel(f'Temperature (°C)', **font_settings) #
324
+ # confidence
325
+ x, y = conf(input_x, input_y, start=start, end=end, num=40, using_binom=True)
326
+ # file_mch_in = open(os.path.join(loc, f"confmed.dat"), "w")
327
+ # for i in range(len(x)):
328
+ # file_mch_in.writelines(f"{x[i]}\t{y[i][0]}\t{y[i][2]}\n")
329
+ # for i in range(len(x)):
330
+ # file_mch_in.writelines(f"{x[len(x) - i - 1]}\t{y[len(x) - i - 1][1]}\t{y[len(x) - i - 1][3]}\n")
331
+ # file_mch_in = open(os.path.join(loc, f"confmed.dat"), "r")
332
+ # [data], rows = read_IN(file_mch_in)
333
+ # axs[0, 1].plot(data[:rows[0], 0], data[:rows[0], 1], c='#333333', marker="none", label="90% conf. interval of distribution")
334
+ # axs[0, 1].plot(data[:rows[0], 0], data[:rows[0], 2], c='green', marker="none", label="90% conf. interval of mediam")
335
+ axs[0, 1].plot(x, y[:, 0], c=main_color[1], marker="none", label="90% conf. interval for median")
336
+ axs[0, 1].plot(x, y[:, 1], c=main_color[1], marker="none")
337
+ axs[0, 1].plot(x, y[:, 2], c=middle_color[1], marker="none", label="90% conf. interval of distribution")
338
+ axs[0, 1].plot(x, y[:, 3], c=middle_color[1], marker="none")
339
+ axs[0, 1].legend(loc='upper left')
340
+ except FileNotFoundError:
341
+ pass
342
+
343
+ fig.tight_layout()
344
+ plt.show()
345
+
346
+ if not export_PDF:
347
+ return
348
+
349
+ filename = f"{title}-matplotlib"
350
+
351
+ params_list = {
352
+ "page_size": 'a4', "ppi": 72, "width": 9.5, "height": 6,
353
+ "pt_width": 0.8, "pt_height": 0.8, "pt_left": 0.16, "pt_bottom": 0.18,
354
+ "offset_top": 0, "offset_right": 0, "offset_bottom": 20, "offset_left": 30,
355
+ "plot_together": False, "show_frame": False,
356
+ 'xlabel_offset': 8, 'ylabel_offset': 2
357
+ }
358
+
359
+ plot_data = {
360
+ "data": [
361
+ transform(axs[0, 0]), transform(axs[0, 1]), transform(axs[1, 0]), transform(axs[1, 1]),
362
+ ],
363
+ "file_name": filename,
364
+ "plot_names": [f"plotname"],
365
+ }
366
+
367
+ filepath = os.path.join(r"C:\Users\Young\Downloads", f"{filename}.pdf")
368
+ cvs = [[ap.smp.export.get_cv_from_dict(plot, **params_list) for plot in plot_data['data']]]
369
+ for i in range(len(cvs[0])):
370
+ pt = cvs[0][i]._plot_areas[0]
371
+ title = pt.get_comp(comp_name="title")
372
+ title._y -= 2
373
+ title._z_index = 999
374
+ pt.text(50, title._y, text=f"({['a', 'b', 'c', 'd'][i]})", coordinate='pt', clip=False, size=8, z_index=299, v_align='top')
375
+ for comp in pt._components:
376
+ if isinstance(comp, pm.Scatter):
377
+ comp._type = 'rec'
378
+ comp._size = 1.5
379
+ for index, legned in enumerate(list(filter(lambda cp: cp.name() == 'legend', pt._components))):
380
+ legned._size = 7
381
+ legned._z_index = 250
382
+ legned._h_align = "left"
383
+ legned._v_align = "center"
384
+ if i == 0: # age spectra
385
+ legned._x = 175
386
+ legned._y = 40 + index * 10
387
+ elif i == 1: # cooling history
388
+ legned._x = 65
389
+ legned._y = 135 - index * 10
390
+ elif i == 2: # arrhenius
391
+ legned._x = 75
392
+ legned._y = 40 + index * 10
393
+ else:
394
+ legned._x = 65
395
+ legned._y = 40 + index * 10
396
+ for comp in pt._components:
397
+ if legned._text in comp.name() and "legend" in comp.name():
398
+ comp._z_index = 250
399
+ if isinstance(comp, pm.Scatter):
400
+ comp._x = legned._x - 10
401
+ comp._y = legned._y
402
+ if isinstance(comp, pm.Line):
403
+ comp._start = [legned._x - 16, legned._y]
404
+ comp._end = [legned._x - 4, legned._y]
405
+
406
+
407
+ filepath = ap.smp.export.export_chart_to_pdf(cvs, filename, filepath)
408
+
409
+
410
+ def transform(ax: plt.Axes):
411
+ xlabels = [i.get_text().replace('−', '-') for i in ax.get_xticklabels()]
412
+ ylabels = [i.get_text().replace('−', '-') for i in ax.get_yticklabels()]
413
+ linestyles = {'-': 'solid', '--': 'dashed', '-.': 'dashdot', ':': 'dotted'}
414
+
415
+ series = []
416
+ for i, line in enumerate(ax.lines):
417
+ xy_data = line.get_xydata() # [[x1, y1], [x2, y2], ...]
418
+ line_style = linestyles.get(line.get_linestyle(), 'solid')
419
+ series.append({
420
+ 'type': 'series.line', 'id': f'line-{i}', 'name': f'line-{i}',
421
+ 'color': line.get_color(), 'line_width': 1, 'line_style': line_style,
422
+ 'data': xy_data, 'line_caps': 'none'
423
+ })
424
+ if bool(line._marker):
425
+ series.append({
426
+ 'type': 'series.scatter', 'id': f'line-marker-{i}', 'name': f'line-marker-{i}',
427
+ 'stroke_color': line.get_markeredgecolor(), 'fill_color': line.get_markerfacecolor(),
428
+ 'data': xy_data, 'size': 2,
429
+ # 'symbol': line._marker.markers.get(line.get_marker(), 'square'),
430
+ 'symbol': 'rec'
431
+ })
432
+ for i, collection in enumerate(ax.collections):
433
+ series.append({
434
+ 'type': 'series.scatter', 'id': f'scatter-{i}', 'name': f'{collection.get_label()}',
435
+ 'stroke_color': collection.get_edgecolor()[0][:3], 'fill_color': collection.get_edgecolor()[0][:3],
436
+ 'data': collection.get_offsets(), 'size': 2,
437
+ 'symbol': 'rec'
438
+ })
439
+
440
+ for i, text in enumerate(ax.texts):
441
+ xy_data = text.get_position() # [[x1, y1], [x2, y2], ...]
442
+ series.append({
443
+ 'type': 'series.text', 'id': f'text-{i}', 'name': f'text-{i}',
444
+ 'color': text.get_color(), 'data': [xy_data], 'text': text.get_text().replace('\n', '<r>'),
445
+ 'size': 8
446
+ })
447
+
448
+ series.append({
449
+ 'type': 'series.text', 'id': f'title', 'name': f'title',
450
+ 'color': 'black', 'data': [[sum(ax.get_xlim()) / 2, ax.get_ylim()[1]]],
451
+ 'h_align': "middle", 'v_align': "top",
452
+ 'text': ax.get_title(), 'size': 8
453
+ })
454
+
455
+ if ax.legend_ is not None:
456
+ for handle, text in zip(ax.legend_.legend_handles, ax.legend_.texts):
457
+ series.append({
458
+ 'type': 'series.text', 'id': f'legend', 'name': f'legend',
459
+ 'color': text.get_color(), 'data': [[ax.get_xlim()[0], ax.get_ylim()[0]]],
460
+ 'h_align': "left", 'v_align': "bottom",
461
+ 'text': text.get_text(), 'size': 8
462
+ })
463
+ if isinstance(handle, plt.Line2D):
464
+ series.append({
465
+ 'type': 'series.line', 'id': f'legend-line', 'name': f'legend-line-{text.get_text()}',
466
+ 'color': handle.get_color(), 'data':[[ax.get_xlim()[0], ax.get_ylim()[0]], [ax.get_xlim()[1], ax.get_ylim()[1]]],
467
+ 'line_width': 1, 'line_style': linestyles.get(handle.get_linestyle(), 'solid')
468
+ })
469
+ if isinstance(handle, PathCollection):
470
+ stroke_c = handle.get_edgecolor()[0][:3]
471
+ stroke_c = f"#{int(stroke_c[0]*255):02x}{int(stroke_c[1]*255):02x}{int(stroke_c[2]*255):02x}"
472
+ fill_c = handle.get_facecolor()[0][:3]
473
+ fill_c = f"#{int(fill_c[0]*255):02x}{int(fill_c[1]*255):02x}{int(fill_c[2]*255):02x}"
474
+ series.append({
475
+ 'type': 'series.scatter', 'id': f'legend-scatter', 'name': f'legend-scatter-{text.get_text()}',
476
+ 'stroke_color': stroke_c, 'fill_color': fill_c,
477
+ 'data': [[sum(ax.get_xlim()) / 2, sum(ax.get_ylim()) / 2]],
478
+ 'size': 2, 'symbol': 'rec'
479
+ })
480
+
481
+ data = {
482
+ 'xAxis': [{
483
+ 'extent': ax.get_xlim(), 'interval': xlabels, 'title': ax.get_xlabel(),
484
+ 'nameLocation': 'middle', 'show_frame': True, 'label_size': 8, 'title_size': 8,
485
+ }],
486
+ 'yAxis': [{
487
+ 'extent': ax.get_ylim(), 'interval': ylabels, 'title': ax.get_ylabel(),
488
+ 'nameLocation': 'middle', 'show_frame': True, 'label_size': 8, 'title_size': 8,
489
+ }],
490
+ 'series': series
491
+ }
492
+
493
+ # print(data)
494
+ return data
495
+
496
+
497
+
498
+ if __name__ == "__main__":
499
+
500
+ params = {
501
+ "initial_age": 0,
502
+ "final_age": 14,
503
+ "x1_extent": [0, 100],
504
+ "y1_extent": [0, 30],
505
+ "x2_extent": [0, 14],
506
+ "y2_extent": [0, 500],
507
+ "x3_extent": [4, 16],
508
+ "y3_extent": [-10, 0],
509
+ "x4_extent": [0, 2000],
510
+ "y4_extent": [0, 100],
511
+ "autoscaling": False,
512
+ # "autoscaling": True,
513
+ # "export_PDF": False,
514
+ "export_PDF": True,
515
+ "index": list(range(1, 12)),
516
+ }
517
+
518
+ s = ""
519
+ # s = "24FY51-remove 1st"
520
+ # s = "24FY49-remove 1st"
521
+ # s = "24FY49-smooth"
522
+ # s = "24FY55-smooth"
523
+ # s = "24FY50-smooth - Copy"
524
+ # s = "24FY07"
525
+ # s = "24FY07-smooth"
526
+ # s = "24FY49"
527
+ # s = "24FY50"
528
+ # s = "24FY51-900C"
529
+ # s = "24FY51"
530
+ # s = "24FY52"
531
+ # s = r"24FY53"
532
+ s = r"24FY53-smooth"
533
+ # s = "24FY54"
534
+ # s = "24FY55"
535
+ # s = "24FY55-smooth-2"
536
+ # s = "24FY55-remove 1st"
537
+ # s = "24FY56"
538
+ # s = "24FY62"
539
+ # s = "24FY64"
540
+ # s = r"24FY67"
541
+ # s = "24FY68"
542
+ # s = r"24FY70"
543
+ # s = r"24FY71"
544
+ # s = r"24FY72"
545
+ # s = "24FY86b"
546
+ # s = "24FY87"
547
+ # s = "24FY88"
548
+ # s = "24FY89"
549
+ # s = "24FY90"
550
+ # s = r"24FY92"
551
+ # s = r"24FY93"
552
+ # s = "WCG-2New"
553
+ # s = r"MDDprograms\WCG-2 - Copy"
554
+ # s = r"4908963"
555
+ # s = r"5096179"
556
+ # s = r"4412795"
557
+ s = r"6950150"
558
+
559
+ loc = os.path.join("D:\DjangoProjects\webarar\private\mdd", s)
560
+ plot_MDD_res(loc=loc, title=s + "release plot", **params)
561
+