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.
- kevin_toolbox/__init__.py +2 -2
- kevin_toolbox/computer_science/algorithm/statistician/__init__.py +2 -0
- kevin_toolbox/computer_science/algorithm/statistician/average_accumulator.py +1 -1
- kevin_toolbox/computer_science/algorithm/statistician/exponential_moving_average.py +1 -1
- kevin_toolbox/computer_science/algorithm/statistician/maximum_accumulator.py +80 -0
- kevin_toolbox/computer_science/algorithm/statistician/minimum_accumulator.py +34 -0
- kevin_toolbox/patches/for_matplotlib/common_charts/__init__.py +3 -0
- kevin_toolbox/patches/for_matplotlib/common_charts/plot_2d_matrix.py +128 -0
- kevin_toolbox/patches/for_matplotlib/common_charts/plot_3d.py +198 -0
- kevin_toolbox/patches/for_matplotlib/common_charts/plot_bars.py +7 -4
- kevin_toolbox/patches/for_matplotlib/common_charts/plot_confusion_matrix.py +11 -4
- kevin_toolbox/patches/for_matplotlib/common_charts/plot_contour.py +157 -0
- kevin_toolbox/patches/for_matplotlib/common_charts/plot_distribution.py +19 -8
- kevin_toolbox/patches/for_matplotlib/common_charts/plot_lines.py +65 -21
- kevin_toolbox/patches/for_matplotlib/common_charts/plot_scatters.py +9 -3
- kevin_toolbox/patches/for_matplotlib/common_charts/plot_scatters_matrix.py +9 -3
- kevin_toolbox/patches/for_matplotlib/common_charts/utils/__init__.py +1 -0
- kevin_toolbox/patches/for_matplotlib/common_charts/utils/log_scaling.py +62 -0
- kevin_toolbox/patches/for_matplotlib/common_charts/utils/save_plot.py +19 -3
- kevin_toolbox/patches/for_numpy/__init__.py +1 -0
- kevin_toolbox/patches/for_numpy/linalg/softmax.py +4 -1
- {kevin_toolbox_dev-1.4.11.dist-info → kevin_toolbox_dev-1.4.12.dist-info}/METADATA +9 -12
- {kevin_toolbox_dev-1.4.11.dist-info → kevin_toolbox_dev-1.4.12.dist-info}/RECORD +25 -19
- {kevin_toolbox_dev-1.4.11.dist-info → kevin_toolbox_dev-1.4.12.dist-info}/WHEEL +0 -0
- {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
|
-
|
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
|
-
|
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'],
|
113
|
-
|
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,
|
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
|
-
|
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
|
-
|
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
|
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,
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
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
|
-
|
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': [
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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__':
|
@@ -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
|
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
|
-
|
27
|
+
plt.close()
|
28
|
+
return output_path
|
@@ -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
|
-
|
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.
|
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.
|
55
|
-
|
56
|
-
|
57
|
-
- 【
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
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 feature】add 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
|
|