Python科学绘图

Python科学绘图

Python科学绘图

常见python主流绘图工具库

matplotlib

seraborn

proplot

SciencePlots

matplotlib

安装

1
2
3
4
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
from matplotlib.ticker import ScalarFormatter
import pandas as pd

散点图

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# 输入文件位置,红点坐标,输出图
def sandian1(file_path: str,
red_point_por: float,
red_point_K: float,
red_point_name: str,
):
df = pd.read_csv(file_path, header=None, names=['img_name', 'por', 'K'])

df['por'] = pd.to_numeric(df['por'], errors='coerce')
df['por'] = df['por'] * 100
df['K'] = pd.to_numeric(df['K'], errors='coerce')
por = df['por']
K = df['K']
por2 = red_point_por
K2 = red_point_K
name2 = red_point_name

# 创建图形和坐标轴 1in=2.54 figsize=(宽度, 高度) 10 , 7
fig, ax = plt.subplots(figsize=(3.9, 2.7), dpi=300)

# 设置全局字体为 Times New Roman
plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.serif'] = ['Times New Roman'] + plt.rcParams['font.serif']

# 绘制数据组1(黑色方块)
ax.scatter(por, K, marker='s', color='black', facecolors='none', s=50, label=img_name)
# 绘制数据组2(红色圆点)
ax.scatter(por2, K2, marker='o', color='red', s=80, label=name2)

# 设置为对数y轴
ax.set_yscale('log')
# 取消 y 轴的科学计数法
formatter = ScalarFormatter(useOffset=False, useMathText=False)
ax.yaxis.set_major_formatter(formatter)
# 设置坐标轴范围
ax.set_xlim(10, 30)
ax.set_ylim(1, 1000)
# 设置主刻度和次刻度的位置和格式
ax.xaxis.set_major_locator(ticker.MultipleLocator(5)) # 主刻度间隔为5
#ax.xaxis.set_minor_locator(ticker.MultipleLocator(1)) # 次刻度间隔为1

# 分别设置 x 轴和 y 轴的刻度标签大小
ax.tick_params(axis='x', labelsize=10) # 设置 x 轴刻度标签大小
ax.tick_params(axis='y', labelsize=10) # 设置 y 轴刻度标签大小
# 获取当前刻度标签
x_labels = ax.get_xticklabels()
y_labels = ax.get_yticklabels()
# 设置字体属性
for label in x_labels:
label.set_fontname('Times New Roman') # 设置字体
label.set_fontweight('bold') # 设置粗体
for label in y_labels:
label.set_fontname('Times New Roman') # 设置字体
label.set_fontweight('bold') # 设置粗体

# 设置刻度长度和宽度方向
ax.tick_params(axis='x', which='major', length=4, width=1, direction='in')
ax.tick_params(axis='x', which='minor', length=3, width=1, direction='in')
ax.tick_params(axis='y', which='major', length=4, width=1, direction='in')
ax.tick_params(axis='y', which='minor', length=3, width=1, direction='in')

# 设置坐标轴线条样式
ax.spines['bottom'].set_linewidth(1) # 底部轴线宽度
ax.spines['left'].set_linewidth(1) # 左侧轴线宽度
ax.spines['top'].set_linewidth(1) # 顶部轴线宽度
ax.spines['right'].set_linewidth(1) # 右侧轴线宽度

# 坐标轴标题
ax.set_xlabel('POR(%)', fontsize=11, fontname='Times New Roman', fontweight='bold')
ax.set_ylabel('Permeability(mD)', fontsize=11, fontname='Times New Roman', fontweight='bold')

# 添加图例
legend = ax.legend(fontsize=8)
# 去掉框线和背景
legend.get_frame().set_linewidth(0.0) # 设置框线宽度为0
legend.get_frame().set_facecolor('none') # 设置背景为透明

# 添加网格
ax.grid(True, which='both', linestyle='-', linewidth=0.5, alpha=0.5)

# 调整布局
plt.tight_layout()

return plt

箱线图

Boxplots

Box plots with custom fill colors

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
def xiangxiantu_one_por(file_path: str,
img_name: str,
key_point_value: float
):
df = pd.read_csv(file_path, header=None, names=['img_name', 'por', 'K'])

df['por'] = pd.to_numeric(df['por'], errors='coerce')
df['por'] = df['por'] * 100
por = df['por'].dropna()

# 创建图形和坐标轴 1in=2.54 figsize=(宽度, 高度) 5 , 7
fig, ax = plt.subplots(figsize=(3, 2.7), dpi=300)

# 设置全局字体为 Times New Roman
plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.serif'] = ['Times New Roman'] + plt.rcParams['font.serif']

# 基础框体
data = [por]
labels = [img_name]
boxplot = ax.boxplot(data, notch=True, patch_artist=True, tick_labels=labels)

# y轴范围
ax.set_ylim(10, 30)

# 设置箱体颜色
colors = ['lightgreen']
for box, color in zip(boxplot['boxes'], colors):
box.set(facecolor=color)

# 在第一组数据上标记点
ax.scatter(1, key_point_value, color='red', s=50, zorder=5, marker='o')

# 添加网格
ax.grid(True, which='both', linestyle='-', linewidth=0.5, alpha=0.5)

# 设置主刻度和次刻度的位置和格式
ax.yaxis.set_major_locator(ticker.MultipleLocator(5)) # 主刻度间隔为5
# ax.xaxis.set_minor_locator(ticker.MultipleLocator(1)) # 次刻度间隔为1

# 分别设置 x 轴和 y 轴的刻度标签大小
ax.tick_params(axis='x', labelsize=7) # 设置 x 轴刻度标签大小
ax.tick_params(axis='y', labelsize=8) # 设置 y 轴刻度标签大小

# 设置刻度长度和宽度方向
ax.tick_params(axis='x', which='major', length=4, width=1, direction='in')
ax.tick_params(axis='x', which='minor', length=3, width=1, direction='in')
ax.tick_params(axis='y', which='major', length=4, width=1, direction='in')
ax.tick_params(axis='y', which='minor', length=3, width=1, direction='in')

# 设置坐标轴线条样式
ax.spines['bottom'].set_linewidth(1) # 底部轴线宽度
ax.spines['left'].set_linewidth(1) # 左侧轴线宽度
ax.spines['top'].set_linewidth(1) # 顶部轴线宽度
ax.spines['right'].set_linewidth(1) # 右侧轴线宽度

# 坐标轴标题
ax.set_ylabel('POR(%)', fontsize=10, fontname='Times New Roman', fontweight='bold')

plt.tight_layout()
return plt

def xiangxiantu_one_K(file_path: str,
img_name: str,
key_point_value: float
):
df = pd.read_csv(file_path, header=None, names=['img_name', 'por', 'K'])
df['K'] = pd.to_numeric(df['K'], errors='coerce')
K = df['K'].dropna()

# 创建图形和坐标轴 1in=2.54 figsize=(宽度, 高度) 5 , 7
fig, ax = plt.subplots(figsize=(3, 2.7), dpi=300)

# 设置全局字体为 Times New Roman
plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.serif'] = ['Times New Roman'] + plt.rcParams['font.serif']

# 基础框体
data = [K]
labels = [img_name]
boxplot = ax.boxplot(data, notch=True, patch_artist=True, tick_labels=labels)

# 设置箱体颜色
colors = ['lightgreen']
for box, color in zip(boxplot['boxes'], colors):
box.set(facecolor=color)

# 在第一组数据上标记点
ax.scatter(1, key_point_value, color='red', s=50, zorder=5, marker='o')

# 添加网格
ax.grid(True, which='both', linestyle='-', linewidth=0.5, alpha=0.5)

# 设置为对数y轴
ax.set_yscale('log')
# 取消 y 轴的科学计数法
formatter = ScalarFormatter(useOffset=False, useMathText=False)
ax.yaxis.set_major_formatter(formatter)
# 设置坐标轴范围
ax.set_ylim(1, 1000)

# 分别设置 x 轴和 y 轴的刻度标签大小
ax.tick_params(axis='x', labelsize=7) # 设置 x 轴刻度标签大小
ax.tick_params(axis='y', labelsize=8) # 设置 y 轴刻度标签大小

# 设置刻度长度和宽度方向
ax.tick_params(axis='x', which='major', length=4, width=1, direction='in')
ax.tick_params(axis='x', which='minor', length=3, width=1, direction='in')
ax.tick_params(axis='y', which='major', length=4, width=1, direction='in')
ax.tick_params(axis='y', which='minor', length=3, width=1, direction='in')

# 设置坐标轴线条样式
ax.spines['bottom'].set_linewidth(1) # 底部轴线宽度
ax.spines['left'].set_linewidth(1) # 左侧轴线宽度
ax.spines['top'].set_linewidth(1) # 顶部轴线宽度
ax.spines['right'].set_linewidth(1) # 右侧轴线宽度

# 坐标轴标题
ax.set_ylabel('Permeability(mD)', fontsize=10, fontname='Times New Roman', fontweight='bold')

plt.tight_layout()
return plt

小提琴图

Box plot vs. violin plot comparison

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
def xiaotiqintu_one_por(file_path: str,
img_name: str,
key_point_value: float
):
df = pd.read_csv(file_path, header=None, names=['img_name', 'por', 'K'])

df['por'] = pd.to_numeric(df['por'], errors='coerce')
df['por'] = df['por'] * 100
por = df['por'].dropna()

# 创建图形和坐标轴 1in=2.54 figsize=(宽度, 高度) 5 , 7
fig, ax = plt.subplots(figsize=(3, 2.7), dpi=300)

# 设置全局字体为 Times New Roman
plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.serif'] = ['Times New Roman'] + plt.rcParams['font.serif']

# 基础框体
data = [por]
labels = [img_name]
boxplot = ax.violinplot(data, showmeans=False, showmedians=True)

# 设置填充区域颜色
for pc in boxplot['bodies']:
pc.set_facecolor('lightblue') # 设置填充颜色
pc.set_edgecolor('lightblue') # 设置边缘线颜色
pc.set_alpha(0.5) # 设置透明度

# 设置其他线条颜色
boxplot['cmedians'].set_color('black') # 设置中位数线颜色
boxplot['cmins'].set_color('black') # 设置小提琴下届线颜色
boxplot['cmaxes'].set_color('black') # 设置小提琴上届线颜色
boxplot['cbars'].set_color('black') # 设置小提琴竖线颜色

# y轴范围
ax.set_xlim(0, 2)
ax.set_ylim(10, 30)

# X轴标记
ax.set_xticks([1])
ax.set_xticklabels(labels)

# 在第一组数据上标记点
ax.scatter(1, key_point_value, color='red', s=50, zorder=5, marker='o')

# 添加网格
ax.grid(True, which='both', linestyle='-', linewidth=0.5, alpha=0.5)

# 设置主刻度和次刻度的位置和格式
ax.yaxis.set_major_locator(ticker.MultipleLocator(5)) # 主刻度间隔为5
ax.xaxis.set_minor_locator(ticker.MultipleLocator(1)) # 次刻度间隔为1

# 分别设置 x 轴和 y 轴的刻度标签大小
ax.tick_params(axis='x', labelsize=7) # 设置 x 轴刻度标签大小
ax.tick_params(axis='y', labelsize=8) # 设置 y 轴刻度标签大小

# 设置刻度长度和宽度方向
ax.tick_params(axis='x', which='major', length=4, width=1, direction='in')
ax.tick_params(axis='x', which='minor', length=3, width=1, direction='in')
ax.tick_params(axis='y', which='major', length=4, width=1, direction='in')
ax.tick_params(axis='y', which='minor', length=3, width=1, direction='in')

# 设置坐标轴线条样式
ax.spines['bottom'].set_linewidth(1) # 底部轴线宽度
ax.spines['left'].set_linewidth(1) # 左侧轴线宽度
ax.spines['top'].set_linewidth(1) # 顶部轴线宽度
ax.spines['right'].set_linewidth(1) # 右侧轴线宽度

# 坐标轴标题
ax.set_ylabel('POR(%)', fontsize=10, fontname='Times New Roman', fontweight='bold')

plt.tight_layout()
return plt

# 小提琴图
def xiaotiqintu_one_K(file_path: str,
img_name: str,
key_point_value: float
):
df = pd.read_csv(file_path, header=None, names=['img_name', 'por', 'K'])
df['K'] = pd.to_numeric(df['K'], errors='coerce')
K = df['K'].dropna()

# 创建图形和坐标轴 1in=2.54 figsize=(宽度, 高度) 5 , 7
fig, ax = plt.subplots(figsize=(3, 2.7), dpi=300)

# 设置全局字体为 Times New Roman
plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.serif'] = ['Times New Roman'] + plt.rcParams['font.serif']

# 基础框体
data = [K]
labels = [img_name]
boxplot = ax.violinplot(data, showmeans=False, showmedians=True)

# 设置填充区域颜色
for pc in boxplot['bodies']:
pc.set_facecolor('lightgreen') # 设置填充颜色
pc.set_edgecolor('lightgreen') # 设置边缘线颜色
pc.set_alpha(0.5) # 设置透明度

# 设置其他线条颜色
boxplot['cmedians'].set_color('black') # 设置中位数线颜色
boxplot['cmins'].set_color('black') # 设置小提琴下届线颜色
boxplot['cmaxes'].set_color('black') # 设置小提琴上届线颜色
boxplot['cbars'].set_color('black') # 设置小提琴竖线颜色

# X轴标记
ax.set_xlim(0, 2)
ax.set_xticks([1])
ax.set_xticklabels(labels)

# 设置为对数y轴
ax.set_yscale('log')
# 取消 y 轴的科学计数法
formatter = ScalarFormatter(useOffset=False, useMathText=False)
ax.yaxis.set_major_formatter(formatter)
# 设置坐标轴范围
ax.set_ylim(1, 1000)

# 在第一组数据上标记点
ax.scatter(1, key_point_value, color='red', s=50, zorder=5, marker='o')

# 添加网格
ax.grid(True, which='both', linestyle='-', linewidth=0.5, alpha=0.5)

# 设置主刻度和次刻度的位置和格式
#ax.yaxis.set_major_locator(ticker.MultipleLocator(5)) # 主刻度间隔为5
ax.xaxis.set_minor_locator(ticker.MultipleLocator(1)) # 次刻度间隔为1

# 分别设置 x 轴和 y 轴的刻度标签大小
ax.tick_params(axis='x', labelsize=7) # 设置 x 轴刻度标签大小
ax.tick_params(axis='y', labelsize=8) # 设置 y 轴刻度标签大小

# 设置刻度长度和宽度方向
ax.tick_params(axis='x', which='major', length=4, width=1, direction='in')
ax.tick_params(axis='x', which='minor', length=3, width=1, direction='in')
ax.tick_params(axis='y', which='major', length=4, width=1, direction='in')
ax.tick_params(axis='y', which='minor', length=3, width=1, direction='in')

# 设置坐标轴线条样式
ax.spines['bottom'].set_linewidth(1) # 底部轴线宽度
ax.spines['left'].set_linewidth(1) # 左侧轴线宽度
ax.spines['top'].set_linewidth(1) # 顶部轴线宽度
ax.spines['right'].set_linewidth(1) # 右侧轴线宽度

# 坐标轴标题
ax.set_ylabel('Permeability(mD)', fontsize=10, fontname='Times New Roman', fontweight='bold')

plt.tight_layout()
return plt
文章作者: HibisciDai
文章链接: http://hibiscidai.com/2025/02/28/Python科学绘图/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 HibisciDai
好用、实惠、稳定的梯子,点击这里