近日使用 matplotlib 绘制图形较多,遂总结一些 matplotlib 的使用技巧

  1. 绘制 散点图,并统计散点密度

效果图:

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
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap, LogNorm

def calculate_density(data, x_divided = 100, y_divided = 100):
X_min, X_max = data[:,0].min(), data[:,0].max()
Y_min, Y_max = data[:,1].min(), data[:,1].max()

# X_min, X_max, Y_min, Y_max = 0, 1, 0, 1
x_window = (X_max - X_min) / x_divided
y_window = (Y_max - Y_min) / y_divided
# print(X_min, X_max)
x_position = np.arange(X_min, X_max, x_window)
y_position = np.arange(Y_min, Y_max, y_window)

# x_position = [1,2,3]
# y_position = [3,4,5]

x,y = np.array(np.meshgrid(x_position, y_position, indexing='ij'))
position = np.column_stack((x.ravel(), y.ravel()))

print("pos:",position.shape, len(position))
print(position)
density = np.zeros(len(position))

for i in range(len(position)):
x_min, x_max = position[i][0] - x_window/2, position[i][0] + x_window/2
y_min, y_max = position[i][1] - y_window/2, position[i][1] + y_window/2
mask = (data[:, 0] >= x_min) & (data[:, 0] <= x_max) & \
(data[:, 1] >= y_min) & (data[:, 1] <= y_max)
density[i] = np.sum(mask)
return position, density

def scatter(data, x_divided = 100, y_divided = 100, s = 5, save = ""):
# 创建颜色映射
plt.cla()
position, density = calculate_density(data, x_divided, y_divided)
norm_density = density / np.max(density)
cmap = plt.cm.viridis # 选择一个颜色映射

# 绘制散点图

mask = norm_density==0
position = position[~mask]
norm_density = norm_density[~mask]

plt.scatter(position[:, 0], position[:, 1], c=norm_density, cmap=cmap, alpha=1,s=s)

# 添加颜色条
sm = plt.cm.ScalarMappable(cmap=cmap, norm=LogNorm(vmin = 1, vmax = np.max(density)))
cb = plt.colorbar(sm)

cb.ax.tick_params(labelsize=12)

# plt.xlim(0,1)
# plt.ylim(0,1)

plt.xticks(fontsize=12)
plt.yticks(fontsize=12)

plt.tight_layout()

if save != "":
print("save_path:", save)
plt.savefig(save)
plt.show()

  1. 绘制 box_plot 并两两比较

效果图:

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
Data = []
for i in range(4):
mean = np.random.uniform(0.3,0.5)
std = np.random.uniform(0.2,0.3)
lent = int(10000*np.random.rand())
data = np.random.normal(mean, std, lent)


dmin = np.random.uniform(0.0, 0.15)
dmax = np.random.uniform(0.5, 0.75)
data = data[data>dmin]
data = data[data<dmax]

print(mean, std, data.shape)
print(data.mean(), data.std())

Data.append(data)

fig, ax = plt.subplots()

for i, data in enumerate(Data):
ax.boxplot(data, positions=[i], widths=0.3,
showfliers=False,
medianprops={'color': f'C{i}', 'linewidth': 2},
whiskerprops={'color': f'C{i}', 'linewidth': 2},
capprops={'color': f'C{i}', 'linewidth': 2},
boxprops={'color': f'C{i}', 'linewidth': 2})


# # 绘制连接线
x = [(0,3),(0,2),(1,3),(1,2),(2,3)]
print(len(x))
y = np.linspace(0.98, 0.75, len(x))


for i in range(len(x)):
x1, x2 = x[i]
ax.plot([x1, x2], [y[i], y[i]], color = 'black', linewidth=1)
ax.plot([x1, x1], [y[i]-0.02, y[i]], color = 'black', linewidth=1)
ax.plot([x2, x2], [y[i]-0.02, y[i]], color = 'black', linewidth=1)
ax.text((x1+x2)/2, y[i], "***", horizontalalignment='center')

ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

plt.xticks(fontsize=10)
plt.yticks(fontsize=12)
plt.ylim(-0.05, 1.00)

plt.tight_layout()


plt.savefig("box_plot.png")

plt.show()

  1. 小知识点
    1. plt.tight_layout () 生成紧缩的图片
    2. fontsize 参数
    3. ax.spines ['top'].set_visible (False) 设置 上边框线 不可见
    4. 保存图片前需要目录存在,可利用 os.path.exists 和 os.makedirs
    5. ipynb 中保存图片要在 plt.show () 之前,否则保存会出现空白图片