kevin-toolbox-dev 1.4.11__py3-none-any.whl → 1.4.12__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 (25) hide show
  1. kevin_toolbox/__init__.py +2 -2
  2. kevin_toolbox/computer_science/algorithm/statistician/__init__.py +2 -0
  3. kevin_toolbox/computer_science/algorithm/statistician/average_accumulator.py +1 -1
  4. kevin_toolbox/computer_science/algorithm/statistician/exponential_moving_average.py +1 -1
  5. kevin_toolbox/computer_science/algorithm/statistician/maximum_accumulator.py +80 -0
  6. kevin_toolbox/computer_science/algorithm/statistician/minimum_accumulator.py +34 -0
  7. kevin_toolbox/patches/for_matplotlib/common_charts/__init__.py +3 -0
  8. kevin_toolbox/patches/for_matplotlib/common_charts/plot_2d_matrix.py +128 -0
  9. kevin_toolbox/patches/for_matplotlib/common_charts/plot_3d.py +198 -0
  10. kevin_toolbox/patches/for_matplotlib/common_charts/plot_bars.py +7 -4
  11. kevin_toolbox/patches/for_matplotlib/common_charts/plot_confusion_matrix.py +11 -4
  12. kevin_toolbox/patches/for_matplotlib/common_charts/plot_contour.py +157 -0
  13. kevin_toolbox/patches/for_matplotlib/common_charts/plot_distribution.py +19 -8
  14. kevin_toolbox/patches/for_matplotlib/common_charts/plot_lines.py +65 -21
  15. kevin_toolbox/patches/for_matplotlib/common_charts/plot_scatters.py +9 -3
  16. kevin_toolbox/patches/for_matplotlib/common_charts/plot_scatters_matrix.py +9 -3
  17. kevin_toolbox/patches/for_matplotlib/common_charts/utils/__init__.py +1 -0
  18. kevin_toolbox/patches/for_matplotlib/common_charts/utils/log_scaling.py +62 -0
  19. kevin_toolbox/patches/for_matplotlib/common_charts/utils/save_plot.py +19 -3
  20. kevin_toolbox/patches/for_numpy/__init__.py +1 -0
  21. kevin_toolbox/patches/for_numpy/linalg/softmax.py +4 -1
  22. {kevin_toolbox_dev-1.4.11.dist-info → kevin_toolbox_dev-1.4.12.dist-info}/METADATA +9 -12
  23. {kevin_toolbox_dev-1.4.11.dist-info → kevin_toolbox_dev-1.4.12.dist-info}/RECORD +25 -19
  24. {kevin_toolbox_dev-1.4.11.dist-info → kevin_toolbox_dev-1.4.12.dist-info}/WHEEL +0 -0
  25. {kevin_toolbox_dev-1.4.11.dist-info → kevin_toolbox_dev-1.4.12.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,157 @@
1
+ import numpy as np
2
+ import matplotlib.pyplot as plt
3
+ from kevin_toolbox.patches.for_matplotlib.common_charts.utils import save_plot, save_record, get_output_path, \
4
+ log_scaling
5
+ from kevin_toolbox.patches.for_matplotlib.variable import COMMON_CHARTS
6
+
7
+ __name = ":common_charts:plot_contour"
8
+
9
+
10
+ @COMMON_CHARTS.register(name=__name)
11
+ def plot_contour(data_s, title, x_name, y_name, z_name, type_=("contour", "contourf"),
12
+ output_dir=None, output_path=None, **kwargs):
13
+ """
14
+ 绘制等高线图
15
+
16
+
17
+ 参数:
18
+ data_s: <dict> 数据。
19
+ 形如 {<data_name>: <data list>, ...} 的字典
20
+ 需要包含 x、y、z 三个键值对,分别对应 x、y、z 轴的数据,值可以是 2D 的矩阵或者"" 1D 数据。 数组。
21
+ title: <str> 绘图标题。
22
+ x_name: <str> x 轴的数据键名。
23
+ y_name: <str> y 轴的数据键名。
24
+ z_name: <str> z 轴的数据键名。
25
+ type_: <str/list of str> 图表类型。
26
+ 目前支持以下取值,或者以下取值的列表:
27
+ - "contour" 等高线
28
+ - "contourf" 带颜色填充的等高线
29
+ 当指定列表时,将会绘制多个图表的混合。
30
+ output_dir: <str> 图片输出目录。
31
+ output_path: <str> 图片输出路径。
32
+ 以上两个只需指定一个即可,同时指定时以后者为准。
33
+ 当只有 output_dir 被指定时,将会以 title 作为图片名。
34
+ 若同时不指定,则直接以 np.ndarray 形式返回图片,不进行保存。
35
+ 在保存为文件时,若文件名中存在路径不适宜的非法字符将会被进行替换。
36
+
37
+ 其他可选参数:
38
+ dpi: <int> 保存图像的分辨率。
39
+ 默认为 200。
40
+ suffix: <str> 图片保存后缀。
41
+ 目前支持的取值有 ".png", ".jpg", ".bmp",默认为第一个。
42
+ b_generate_record: <boolean> 是否保存函数参数为档案。
43
+ 默认为 False,当设置为 True 时将会把函数参数保存成 [output_path].record.tar。
44
+ 后续可以使用 plot_from_record() 函数或者 Serializer_for_Registry_Execution 读取该档案,并进行修改和重新绘制。
45
+ 该参数仅在 output_dir 和 output_path 非 None 时起效。
46
+ b_show_plot: <boolean> 是否使用 plt.show() 展示图片。
47
+ 默认为 False
48
+ b_bgr_image: <boolean> 以 np.ndarray 形式返回图片时,图片的channel顺序是采用 bgr 还是 rgb。
49
+ 默认为 True
50
+ contourf_cmap: <str> 带颜色填充的等高线的颜色映射,默认 "viridis"。
51
+ contourf_alpha: <float> 颜色填充的透明度。
52
+ linestyles: <str> 等高线线形。
53
+ 可选值:
54
+ - 'solid' 实线
55
+ - 'dashed' 虚线(默认)
56
+ - 'dashdot' 点划线
57
+ - 'dotted' 点线
58
+ b_clabel: <boolean> 是否在等高线上显示数值。
59
+ x_log_scale,y_log_scale,z_log_scale: <int/float> 对 x,y,z 轴数据使用哪个底数进行对数显示。
60
+ 默认为 None,此时表示不使用对数显示。
61
+ x_ticks,...: <int/list of float or int> 在哪个数字下添加坐标记号。
62
+ 默认为 None,表示不添加记号。
63
+ 当设置为 int 时,表示自动根据 x,y,z 数据的范围,选取等间隔选取多少个坐标作为记号。
64
+ 特别地,可以通过 z_ticks 来指定等高线的数量和划分位置。
65
+ x_tick_labels,...: <int/list> 坐标记号的label。
66
+ """
67
+ # 默认参数设置
68
+ paras = {
69
+ "dpi": 200,
70
+ "suffix": ".png",
71
+ "b_generate_record": False,
72
+ "b_show_plot": False,
73
+ "b_bgr_image": True,
74
+ "contourf_cmap": "viridis",
75
+ "contourf_alpha": 0.5,
76
+ "linestyles": "dashed",
77
+ "b_clabel": True,
78
+ "x_log_scale": None, "x_ticks": None, "x_tick_labels": None,
79
+ "y_log_scale": None, "y_ticks": None, "y_tick_labels": None,
80
+ "z_log_scale": None, "z_ticks": None, "z_tick_labels": None,
81
+ }
82
+ paras.update(kwargs)
83
+ #
84
+ _output_path = get_output_path(output_path=output_path, output_dir=output_dir, title=title, **kwargs)
85
+ save_record(_func=plot_contour, _name=__name,
86
+ _output_path=_output_path if paras["b_generate_record"] else None,
87
+ **paras)
88
+ data_s = data_s.copy()
89
+ if isinstance(type_, str):
90
+ type_ = [type_]
91
+
92
+ d_s = dict()
93
+ ticks_s = dict()
94
+ tick_labels_s = dict()
95
+ for k in ("x", "y", "z"):
96
+ d_s[k], ticks_s[k], tick_labels_s[k] = log_scaling(
97
+ x_ls=data_s[eval(f'{k}_name')], log_scale=paras[f"{k}_log_scale"],
98
+ ticks=paras[f"{k}_ticks"], tick_labels=paras[f"{k}_tick_labels"]
99
+ )
100
+ X, Y, Z = [d_s[i] for i in ("x", "y", "z")]
101
+
102
+ plt.clf()
103
+ fig = plt.figure(figsize=(10, 8))
104
+ ax = fig.add_subplot(111)
105
+
106
+ # 等高线
107
+ if "contour" in type_:
108
+ if X.ndim == 1:
109
+ contour = ax.tricontour(X, Y, Z, colors='black', linestyles=paras["linestyles"], levels=ticks_s["z"])
110
+ elif X.ndim == 2:
111
+ contour = ax.contour(X, Y, Z, colors='black', linestyles=paras["linestyles"], levels=ticks_s["z"])
112
+ else:
113
+ raise ValueError("The dimension of X, Y, Z must be 1 or 2.")
114
+ if paras["b_clabel"]:
115
+ ax.clabel(contour, inline=True, fontsize=10, fmt={k: v for k, v in zip(ticks_s["z"], tick_labels_s["z"])})
116
+
117
+ # 等高线颜色填充
118
+ if "contourf" in type_:
119
+ if X.ndim == 1:
120
+ contourf = ax.tricontourf(X, Y, Z, cmap=paras["contourf_cmap"], alpha=paras["contourf_alpha"],
121
+ levels=ticks_s["z"])
122
+ elif X.ndim == 2:
123
+ contourf = ax.contourf(X, Y, Z, cmap=paras["contourf_cmap"], alpha=paras["contourf_alpha"],
124
+ levels=ticks_s["z"])
125
+ else:
126
+ raise ValueError("The dimension of X, Y, Z must be 1 or 2.")
127
+ # 添加颜色条以展示平滑曲面颜色与 z 值的对应关系
128
+ cbar = fig.colorbar(contourf, ax=ax, shrink=0.5, aspect=10)
129
+ cbar.set_label(z_name, fontsize=12)
130
+
131
+ # 设置坐标轴标签和图形标题
132
+ ax.set_xlabel(x_name, fontsize=12)
133
+ ax.set_ylabel(y_name, fontsize=12)
134
+ ax.set_title(title, fontsize=14)
135
+ for i in ("x", "y",):
136
+ if ticks_s[i] is not None:
137
+ getattr(ax, f'set_{i}ticks')(ticks_s[i])
138
+ getattr(ax, f'set_{i}ticklabels')(tick_labels_s[i])
139
+
140
+ return save_plot(plt=plt, output_path=_output_path, dpi=paras["dpi"], suffix=paras["suffix"],
141
+ b_bgr_image=paras["b_bgr_image"], b_show_plot=paras["b_show_plot"])
142
+
143
+
144
+ if __name__ == '__main__':
145
+ # 生成示例数据
146
+ x = np.linspace(1, 7, 100)
147
+ y = np.linspace(-3, 3, 100)
148
+ X, Y = np.meshgrid(x, y)
149
+ # 这里定义一个函数,使得 Z 值落在 0 到 1 之间
150
+ Z = np.exp(-(X ** 2 + Y ** 2))
151
+ data = {
152
+ 'x': X,
153
+ 'y': Y,
154
+ "z": Z,
155
+ }
156
+ plot_contour(data, x_name='x', y_name='y', z_name='z', title="Contour Plot", x_log_scale=None, z_ticks=10,
157
+ type_=("contour", "contourf"), output_dir="./temp")
@@ -32,7 +32,7 @@ def plot_distribution(data_s, title, x_name=None, x_name_ls=None, type_="hist",
32
32
  output_path: <str> 图片输出路径。
33
33
  以上两个只需指定一个即可,同时指定时以后者为准。
34
34
  当只有 output_dir 被指定时,将会以 title 作为图片名。
35
- 若同时不指定,则直接调用 plt.show() 显示图像,而不进行保存。
35
+ 若同时不指定,则直接以 np.ndarray 形式返回图片,不进行保存。
36
36
  在保存为文件时,若文件名中存在路径不适宜的非法字符将会被进行替换。
37
37
 
38
38
  其他可选参数:
@@ -43,6 +43,10 @@ def plot_distribution(data_s, title, x_name=None, x_name_ls=None, type_="hist",
43
43
  默认为 False,当设置为 True 时将会把函数参数保存成 [output_path].record.tar。
44
44
  后续可以使用 plot_from_record() 函数或者 Serializer_for_Registry_Execution 读取该档案,并进行修改和重新绘制。
45
45
  该参数仅在 output_dir 和 output_path 非 None 时起效。
46
+ b_show_plot: <boolean> 是否使用 plt.show() 展示图片。
47
+ 默认为 False
48
+ b_bgr_image: <boolean> 以 np.ndarray 形式返回图片时,图片的channel顺序是采用 bgr 还是 rgb。
49
+ 默认为 True
46
50
 
47
51
  返回值:
48
52
  <str> 图像保存的完整文件路径。如果 output_dir 或 output_path 被指定,
@@ -52,7 +56,9 @@ def plot_distribution(data_s, title, x_name=None, x_name_ls=None, type_="hist",
52
56
  paras = {
53
57
  "dpi": 200,
54
58
  "suffix": ".png",
55
- "b_generate_record": False
59
+ "b_generate_record": False,
60
+ "b_show_plot": False,
61
+ "b_bgr_image": True
56
62
  }
57
63
  paras.update(kwargs)
58
64
  #
@@ -98,17 +104,22 @@ def plot_distribution(data_s, title, x_name=None, x_name_ls=None, type_="hist",
98
104
  # 显示图例
99
105
  plt.legend()
100
106
 
101
- save_plot(plt=plt, output_path=_output_path, dpi=paras["dpi"], suffix=paras["suffix"])
102
- return _output_path
107
+ return save_plot(plt=plt, output_path=_output_path, dpi=paras["dpi"], suffix=paras["suffix"],
108
+ b_bgr_image=paras["b_bgr_image"], b_show_plot=paras["b_show_plot"])
103
109
 
104
110
 
105
111
  if __name__ == '__main__':
106
112
  import os
113
+ import cv2
107
114
 
108
- plot_distribution(
115
+ image_ = plot_distribution(
109
116
  data_s={
110
- 'a': [1, 2, 3, 4, 5, 3, 2, 1],
117
+ 'a': [0.1, 2, 3, 4, 5, 3, 2, 1],
111
118
  'c': [1, 2, 3, 4, 5, 0, 0, 0]},
112
- title='test_plot_distribution', x_name_ls=['a', 'c'], type_="category",
113
- output_dir=os.path.join(os.path.dirname(__file__), "temp")
119
+ title='test_plot_distribution', x_name_ls=['a', 'c'],
120
+ # type_="category",
121
+ # output_dir=os.path.join(os.path.dirname(__file__), "temp"),
122
+ # b_show_plot=True
123
+ type_="hist", steps=1,
114
124
  )
125
+ cv2.imwrite(os.path.join(os.path.dirname(__file__), "temp", "233.png"), image_)
@@ -1,13 +1,15 @@
1
+ import warnings
1
2
  import matplotlib.pyplot as plt
2
3
  from kevin_toolbox.patches.for_matplotlib.color import generate_color_list
3
- from kevin_toolbox.patches.for_matplotlib.common_charts.utils import save_plot, save_record, get_output_path
4
+ from kevin_toolbox.patches.for_matplotlib.common_charts.utils import save_plot, save_record, get_output_path, \
5
+ log_scaling
4
6
  from kevin_toolbox.patches.for_matplotlib.variable import COMMON_CHARTS
5
7
 
6
8
  __name = ":common_charts:plot_lines"
7
9
 
8
10
 
9
11
  @COMMON_CHARTS.register(name=__name)
10
- def plot_lines(data_s, title, x_name, x_ticklabels_name=None, output_dir=None, output_path=None, **kwargs):
12
+ def plot_lines(data_s, title, x_name,y_name_ls=None, output_dir=None, output_path=None, **kwargs):
11
13
  """
12
14
  绘制折线图
13
15
 
@@ -16,15 +18,15 @@ def plot_lines(data_s, title, x_name, x_ticklabels_name=None, output_dir=None, o
16
18
  形如 {<data_name>: <data list>, ...} 的字典
17
19
  title: <str> 绘图标题,同时用于保存图片的文件名。
18
20
  x_name: <str> 以哪个 data_name 作为 x 轴。
19
- 其余数据视为需要被绘制的数据点。
21
+ y_name_ls: <list of str> 哪些数据视为需要被绘制的数据点。
22
+ 默认为 None,表示除 x_name 以外的数据都是需要绘制的。
20
23
  例子: data_s={"step":[...], "acc_top1":[...], "acc_top3":[...]}
21
24
  当 x_name="step" 时,将会以 step 为 x 轴绘制 acc_top1 和 acc_top3 的 bar 图。
22
- x_ticklabels_name: <str or None> 若提供则表示 x 轴刻度标签对应的键名,用于替换默认的 x 轴刻度值。
23
25
  output_dir: <str> 图片输出目录。
24
26
  output_path: <str> 图片输出路径。
25
27
  以上两个只需指定一个即可,同时指定时以后者为准。
26
28
  当只有 output_dir 被指定时,将会以 title 作为图片名。
27
- 若同时不指定,则直接调用 plt.show() 显示图像,而不进行保存。
29
+ 若同时不指定,则直接以 np.ndarray 形式返回图片,不进行保存。
28
30
  在保存为文件时,若文件名中存在路径不适宜的非法字符将会被进行替换。
29
31
 
30
32
  其他可选参数:
@@ -36,44 +38,81 @@ def plot_lines(data_s, title, x_name, x_ticklabels_name=None, output_dir=None, o
36
38
  默认为 False,当设置为 True 时将会把函数参数保存成 [output_path].record.tar。
37
39
  后续可以使用 plot_from_record() 函数或者 Serializer_for_Registry_Execution 读取该档案,并进行修改和重新绘制。
38
40
  该参数仅在 output_dir 和 output_path 非 None 时起效。
41
+ b_show_plot: <boolean> 是否使用 plt.show() 展示图片。
42
+ 默认为 False
43
+ b_bgr_image: <boolean> 以 np.ndarray 形式返回图片时,图片的channel顺序是采用 bgr 还是 rgb。
44
+ 默认为 True
39
45
  color_ls: <list> 用于绘图的颜色列表,默认根据数据序列个数自动生成。
40
46
  marker_ls: <list of str> 折线图上各数据点的标记。
41
47
  linestyle_ls: <list of str> 线型。
42
48
  默认值为 '-',表示直线。
43
49
  """
44
- line_nums = len(data_s) - 1
50
+ y_names = y_name_ls if y_name_ls else list(i for i in data_s.keys() if i != x_name)
51
+ line_nums = len(y_names)
45
52
  paras = {
46
53
  "dpi": 200,
47
54
  "suffix": ".png",
48
55
  "b_generate_record": False,
56
+ "b_show_plot": False,
57
+ "b_bgr_image": True,
49
58
  "color_ls": generate_color_list(nums=line_nums),
50
59
  "marker_ls": None,
51
60
  "linestyle_ls": '-',
61
+ #
62
+ "x_log_scale": None,
63
+ "x_ticks": None,
64
+ "x_tick_labels": None,
65
+ "x_label_formatter": None,
66
+ "y_log_scale": None,
67
+ "y_ticks": None,
68
+ "y_tick_labels": None,
69
+ "y_label_formatter": None,
52
70
  }
53
71
  paras.update(kwargs)
54
72
  for k, v in paras.items():
55
73
  if k.endswith("_ls") and not isinstance(v, (list, tuple)):
56
74
  paras[k] = [v] * line_nums
57
75
  assert line_nums == len(paras["color_ls"]) == len(paras["marker_ls"]) == len(paras["linestyle_ls"])
76
+ if "x_ticklabels_name" in paras:
77
+ warnings.warn(f"{__name}: 'x_ticklabels_name' is deprecated, please use 'x_ticks' and 'x_tick_labels' instead.")
58
78
  #
59
79
  _output_path = get_output_path(output_path=output_path, output_dir=output_dir, title=title, **kwargs)
60
80
  save_record(_func=plot_lines, _name=__name,
61
81
  _output_path=_output_path if paras["b_generate_record"] else None,
62
82
  **paras)
63
83
  data_s = data_s.copy()
84
+ #
85
+ d_s = dict()
86
+ ticks_s = dict()
87
+ tick_labels_s = dict()
88
+ d_s["x"] = data_s.pop(x_name)
89
+ d_s["y"] = []
90
+ for k in y_names:
91
+ d_s["y"].extend(data_s[k])
92
+ for k in ("x", "y"):
93
+ d_s[k], ticks_s[k], tick_labels_s[k] = log_scaling(
94
+ x_ls=d_s[k], log_scale=paras[f"{k}_log_scale"],
95
+ ticks=paras[f"{k}_ticks"], tick_labels=paras[f"{k}_tick_labels"],
96
+ label_formatter=paras[f"{k}_label_formatter"]
97
+ )
98
+ temp = d_s.pop("y")
99
+ count = 0
100
+ for k in y_names:
101
+ data_s[k] = temp[count:count + len(data_s[k])]
102
+ count += len(data_s[k])
103
+ data_s[x_name] = d_s["x"]
64
104
 
65
105
  plt.clf()
106
+ fig = plt.figure(figsize=(10, 8))
107
+ ax = fig.add_subplot(111)
108
+
66
109
  #
67
110
  x_all_ls = data_s.pop(x_name)
68
- if x_ticklabels_name is not None:
69
- x_ticklabels = data_s.pop(x_ticklabels_name)
70
- assert len(x_all_ls) == len(x_ticklabels)
71
- plt.xticks(x_all_ls, x_ticklabels)
72
111
  data_s, temp = dict(), data_s
73
112
  for k, v_ls in temp.items():
74
113
  y_ls, x_ls = [], []
75
114
  for x, v in zip(x_all_ls, v_ls):
76
- if x is None or v is None:
115
+ if v is None:
77
116
  continue
78
117
  x_ls.append(x)
79
118
  y_ls.append(v)
@@ -81,17 +120,22 @@ def plot_lines(data_s, title, x_name, x_ticklabels_name=None, output_dir=None, o
81
120
  continue
82
121
  data_s[k] = (x_ls, y_ls)
83
122
  #
84
- for i, (k, (x_ls, y_ls)) in enumerate(data_s.items()):
85
- plt.plot(x_ls, y_ls, label=f'{k}', color=paras["color_ls"][i], marker=paras["marker_ls"][i],
86
- linestyle=paras["linestyle_ls"][i])
87
- plt.xlabel(f'{x_name}')
88
- plt.ylabel('value')
89
- plt.title(f'{title}')
123
+ for i, k in enumerate(y_names):
124
+ x_ls, y_ls = data_s[k]
125
+ ax.plot(x_ls, y_ls, label=f'{k}', color=paras["color_ls"][i], marker=paras["marker_ls"][i],
126
+ linestyle=paras["linestyle_ls"][i])
127
+ ax.set_xlabel(f'{x_name}')
128
+ ax.set_ylabel('value')
129
+ ax.set_title(f'{title}')
130
+ for i in ("x", "y",):
131
+ if ticks_s[i] is not None:
132
+ getattr(ax, f'set_{i}ticks')(ticks_s[i])
133
+ getattr(ax, f'set_{i}ticklabels')(tick_labels_s[i])
90
134
  # 显示图例
91
135
  plt.legend()
92
136
 
93
- save_plot(plt=plt, output_path=_output_path, dpi=paras["dpi"], suffix=paras["suffix"])
94
- return _output_path
137
+ return save_plot(plt=plt, output_path=_output_path, dpi=paras["dpi"], suffix=paras["suffix"],
138
+ b_bgr_image=paras["b_bgr_image"], b_show_plot=paras["b_show_plot"])
95
139
 
96
140
 
97
141
  if __name__ == '__main__':
@@ -99,9 +143,9 @@ if __name__ == '__main__':
99
143
 
100
144
  plot_lines(
101
145
  data_s={
102
- 'a': [1, 2, 3, 4, 5],
146
+ 'a': [0, 2, 3, 4, 5],
103
147
  'b': [5, 4, 3, 2, 1],
104
148
  'c': [1, 2, 3, 4, 5]},
105
- title='test_plot_lines',
149
+ title='test_plot_lines', y_log_scale=2,
106
150
  x_name='a', output_dir=os.path.join(os.path.dirname(__file__), "temp")
107
151
  )
@@ -25,7 +25,7 @@ def plot_scatters(data_s, title, x_name, y_name, cate_name=None, output_dir=None
25
25
  output_path: <str or None> 图片输出路径。
26
26
  以上两个只需指定一个即可,同时指定时以后者为准。
27
27
  当只有 output_dir 被指定时,将会以 title 作为图片名。
28
- 若同时不指定,则直接调用 plt.show() 显示图像,而不进行保存。
28
+ 若同时不指定,则直接以 np.ndarray 形式返回图片,不进行保存。
29
29
  在保存为文件时,若文件名中存在路径不适宜的非法字符将会被进行替换。
30
30
 
31
31
  其他可选参数:
@@ -37,6 +37,10 @@ def plot_scatters(data_s, title, x_name, y_name, cate_name=None, output_dir=None
37
37
  默认为 False,当设置为 True 时将会把函数参数保存成 [output_path].record.tar。
38
38
  后续可以使用 plot_from_record() 函数或者 Serializer_for_Registry_Execution 读取该档案,并进行修改和重新绘制。
39
39
  该参数仅在 output_dir 和 output_path 非 None 时起效。
40
+ b_show_plot: <boolean> 是否使用 plt.show() 展示图片。
41
+ 默认为 False
42
+ b_bgr_image: <boolean> 以 np.ndarray 形式返回图片时,图片的channel顺序是采用 bgr 还是 rgb。
43
+ 默认为 True
40
44
  scatter_size: <int> 散点的大小。
41
45
  默认 5。
42
46
 
@@ -52,6 +56,8 @@ def plot_scatters(data_s, title, x_name, y_name, cate_name=None, output_dir=None
52
56
  "dpi": 200,
53
57
  "suffix": ".png",
54
58
  "b_generate_record": False,
59
+ "b_show_plot": False,
60
+ "b_bgr_image": True,
55
61
  "scatter_size": 5
56
62
  }
57
63
  paras.update(kwargs)
@@ -83,8 +89,8 @@ def plot_scatters(data_s, title, x_name, y_name, cate_name=None, output_dir=None
83
89
  markersize=min(paras["scatter_size"], 5)) for i, j in color_s.items()
84
90
  ])
85
91
 
86
- save_plot(plt=plt, output_path=_output_path, dpi=paras["dpi"], suffix=paras["suffix"])
87
- return _output_path
92
+ return save_plot(plt=plt, output_path=_output_path, dpi=paras["dpi"], suffix=paras["suffix"],
93
+ b_bgr_image=paras["b_bgr_image"], b_show_plot=paras["b_show_plot"])
88
94
 
89
95
 
90
96
  if __name__ == '__main__':
@@ -25,7 +25,7 @@ def plot_scatters_matrix(data_s, title, x_name_ls, cate_name=None, output_dir=No
25
25
  output_path: <str or None> 图片输出路径。
26
26
  以上两个只需指定一个即可,同时指定时以后者为准。
27
27
  当只有 output_dir 被指定时,将会以 title 作为图片名。
28
- 若同时不指定,则直接调用 plt.show() 显示图像,而不进行保存。
28
+ 若同时不指定,则直接以 np.ndarray 形式返回图片,不进行保存。
29
29
  在保存为文件时,若文件名中存在路径不适宜的非法字符将会被进行替换。
30
30
  cate_color_s: <dict or None> 类别-颜色映射字典,将 cate_name 中的每个类别映射到具体颜色。
31
31
  默认为 None,自动生成颜色列表。
@@ -39,6 +39,10 @@ def plot_scatters_matrix(data_s, title, x_name_ls, cate_name=None, output_dir=No
39
39
  默认为 False,当设置为 True 时将会把函数参数保存成 [output_path].record.tar。
40
40
  后续可以使用 plot_from_record() 函数或者 Serializer_for_Registry_Execution 读取该档案,并进行修改和重新绘制。
41
41
  该参数仅在 output_dir 和 output_path 非 None 时起效。
42
+ b_show_plot: <boolean> 是否使用 plt.show() 展示图片。
43
+ 默认为 False
44
+ b_bgr_image: <boolean> 以 np.ndarray 形式返回图片时,图片的channel顺序是采用 bgr 还是 rgb。
45
+ 默认为 True
42
46
  diag_kind: <str> 对角线图表的类型。
43
47
  支持:
44
48
  - "hist"(直方图)
@@ -49,6 +53,8 @@ def plot_scatters_matrix(data_s, title, x_name_ls, cate_name=None, output_dir=No
49
53
  "dpi": 200,
50
54
  "suffix": ".png",
51
55
  "b_generate_record": False,
56
+ "b_show_plot": False,
57
+ "b_bgr_image": True,
52
58
  "diag_kind": "kde" # 设置对角线图直方图/密度图 {‘hist’, ‘kde’}
53
59
  }
54
60
  assert cate_name in data_s and len(set(x_name_ls).difference(set(data_s.keys()))) == 0
@@ -75,8 +81,8 @@ def plot_scatters_matrix(data_s, title, x_name_ls, cate_name=None, output_dir=No
75
81
  plt.subplots_adjust(top=0.95)
76
82
  plt.suptitle(f'{title}', y=0.98, x=0.47)
77
83
 
78
- save_plot(plt=plt, output_path=_output_path, dpi=paras["dpi"], suffix=paras["suffix"])
79
- return _output_path
84
+ return save_plot(plt=plt, output_path=_output_path, dpi=paras["dpi"], suffix=paras["suffix"],
85
+ b_bgr_image=paras["b_bgr_image"], b_show_plot=paras["b_show_plot"])
80
86
 
81
87
 
82
88
  if __name__ == '__main__':
@@ -1,3 +1,4 @@
1
1
  from .get_output_path import get_output_path
2
2
  from .save_plot import save_plot
3
3
  from .save_record import save_record
4
+ from .log_scaling import log_scaling
@@ -0,0 +1,62 @@
1
+ import numpy as np
2
+
3
+
4
+ def log_scaling(x_ls, log_scale=None, ticks=None, tick_labels=None, b_replace_nan_inf_with_none=True, label_formatter=None):
5
+ label_formatter = label_formatter or (lambda x: f"{x:.2e}")
6
+ raw_x_ls, x_ls = x_ls, []
7
+ none_idx_ls = []
8
+ for idx, i in enumerate(raw_x_ls):
9
+ if i is None or np.isnan(i) or np.isinf(i):
10
+ none_idx_ls.append(idx)
11
+ else:
12
+ x_ls.append(i)
13
+ x_ls = np.asarray(x_ls)
14
+ if isinstance(ticks, int):
15
+ ticks = np.linspace(np.min(x_ls), np.max(x_ls), ticks
16
+ ) if log_scale is None else np.logspace(
17
+ np.log(np.min(x_ls)) / np.log(log_scale), np.log(np.max(x_ls)) / np.log(log_scale), ticks, base=log_scale)
18
+ #
19
+ if log_scale is not None:
20
+ assert log_scale > 0 and np.min(x_ls) > 0
21
+ if ticks is None:
22
+ ticks = sorted(list(set(x_ls.reshape(-1).tolist())))
23
+ if tick_labels is None:
24
+ tick_labels = [label_formatter(j) for j in ticks]
25
+ assert len(ticks) == len(tick_labels)
26
+ ticks = [np.log(j) / np.log(log_scale) for j in ticks]
27
+ x_ls = np.log(x_ls) / np.log(log_scale)
28
+ else:
29
+ if ticks is None:
30
+ from matplotlib.ticker import MaxNLocator
31
+ locator = MaxNLocator()
32
+ ticks = locator.tick_values(np.min(x_ls), np.max(x_ls))
33
+ if ticks is not None and tick_labels is None:
34
+ tick_labels = [label_formatter(j) for j in ticks]
35
+
36
+ if none_idx_ls:
37
+ x_ls = x_ls.tolist()
38
+ for idx in none_idx_ls:
39
+ if b_replace_nan_inf_with_none:
40
+ x_ls.insert(idx, None)
41
+ else:
42
+ x_ls.insert(idx, raw_x_ls[idx])
43
+
44
+ return x_ls, ticks, tick_labels
45
+
46
+
47
+ if __name__ == "__main__":
48
+ x_ls_ = np.linspace(0.1, 100, 10)
49
+
50
+ out_ls_, ticks_, tick_labels_ = log_scaling(x_ls_, log_scale=10, ticks=5)
51
+ print(out_ls_)
52
+ print(ticks_)
53
+ print(tick_labels_)
54
+
55
+ x_ls_[2] = np.inf
56
+ x_ls_[3] = -np.inf
57
+ x_ls_[4] = -np.nan
58
+ print(x_ls_)
59
+ out_ls_, ticks_, tick_labels_ = log_scaling(x_ls_, log_scale=10, ticks=5)
60
+ print(out_ls_)
61
+ print(ticks_)
62
+ print(tick_labels_)
@@ -1,12 +1,28 @@
1
1
  import os
2
+ import io
3
+ import numpy as np
4
+ from PIL import Image
2
5
 
3
6
 
4
- def save_plot(plt, output_path, dpi=200, suffix=".png", **kwargs):
7
+ def save_plot(plt, output_path, dpi=200, suffix=".png", b_bgr_image=False, b_show_plot=False, **kwargs):
5
8
  assert suffix in [".png", ".jpg", ".bmp"]
6
9
 
7
- if output_path is None:
10
+ if b_show_plot:
8
11
  plt.show()
12
+
13
+ if output_path is None:
14
+ buf = io.BytesIO()
15
+ plt.savefig(buf, format=suffix.split(".")[-1].lower(), dpi=dpi)
16
+ buf.seek(0)
17
+ image = Image.open(buf).convert("RGB")
18
+ image = np.array(image)
19
+ buf.close()
20
+ plt.close()
21
+ if b_bgr_image:
22
+ image = image[..., ::-1]
23
+ return image
9
24
  else:
10
25
  os.makedirs(os.path.dirname(output_path), exist_ok=True)
11
26
  plt.savefig(output_path, dpi=dpi)
12
- plt.close()
27
+ plt.close()
28
+ return output_path
@@ -1 +1,2 @@
1
1
  from . import linalg
2
+ from . import random
@@ -26,7 +26,10 @@ def softmax(x, axis=-1, temperature=None, b_use_log_over_x=False):
26
26
  res = np.where(x == np.max(x, axis=axis), 1, res)
27
27
  elif b_use_log_over_x:
28
28
  # softmax(log(x))
29
- res = x ** (1 / temperature)
29
+ if temperature is not None:
30
+ res = x ** (1 / temperature)
31
+ else:
32
+ res = x
30
33
  else:
31
34
  # softmax(x)
32
35
  # 为了数值稳定,减去最大值
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kevin-toolbox-dev
3
- Version: 1.4.11
3
+ Version: 1.4.12
4
4
  Summary: 一个常用的工具代码包集合
5
5
  Home-page: https://github.com/cantbeblank96/kevin_toolbox
6
6
  Download-URL: https://github.com/username/your-package/archive/refs/tags/v1.0.0.tar.gz
@@ -51,17 +51,14 @@ pip install kevin-toolbox --no-dependencies
51
51
 
52
52
  [版本更新记录](./notes/Release_Record.md):
53
53
 
54
- - v 1.4.11 (2025-04-16)【bug fix】
55
-
56
- - nested_dict_list
57
- - 【bug fixfix bug in value_parser.replace_identical_with_reference()
58
- - bug 描述:该函数的 _forward 中是通过 get_nodes 来获取各层节点,并记录节点的 id 和 level,这就导致某些节点由于其下具有不同长度的到叶节点的路径,因此节点会同时属于多个 level,最终导致其在 id_to_height_s 中被记录为有多个高度,这进一步导致其无法通过后面“具有相同 id 的节点所处的高度应该相同”的检验条件。
59
- - 解决:
60
- - 修复了 replace_identical_with_reference() 中的 _forward 部分,仅记录每个节点的最大高度。
61
- - 去除了“具有相同 id 的节点所处的高度应该相同”的检验条件。
62
- - computer_science.algorithm.redirector
63
- - 【bug fix】fix bug in Redirectable_Sequence_Fetcher,将 _randomly_idx_redirector 中的 rng.choices 改为 rng.choice
64
- - 添加了对应的测试用例。
54
+ - v 1.4.12 (2025-05-28)【bug fix】【new feature
55
+ - computer_science.algorithm.statistician
56
+ - 【new feature】add Maximum_Accumulator,用于计算最大值的累积器。
57
+ - 【new featureadd Minimum_Accumulator,用于计算最小值的累积器。
58
+
59
+ - patches.for_numpy.linalg
60
+ - 【bug fix】fix bug in softmax,修复了在 b_use_log_over_x=True 时 temperature 设为 None 导致计算失败的问题。
61
+
65
62
 
66
63
 
67
64