前言

源数据是一个data.txt

某憨憨用的matlab,不会导出为xls、csv等pandas库可以处理的文件,我对你很无语……

1
2
xlswrite('test.csv')
csvwrite('test.csv')

操作步骤

转换为csv文件后,会得到如下的一个表格;

读取数据

如果直接读取data.txt的话,可以使用如下代码:

1
2
import pandas as pd
df = pd.read_table('data2010.txt', names=['time', 'test','formal', 'color'], header=None, sep=" ")

如果是在test.csv的基础上操作,可使用如下代码:

1
df = pd.read_csv('test.csv')

需求分析

  • 需要计算标准数据与实际测量数据的偏差(bias)、均方根误差(RMSE)、散射指数(SI)三个值
  • 需要根据点坐标(标准值,实际值)绘制散点图

  • 需要根据点密度绘制不同颜色的散点分布图

    效果应如下图所示:

具体实现

  • 三个公式的计算

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    # 分别对 测量值 和 标准值 求和
    ans_test = sum(df['test'])
    ans_formal = sum(df['formal'])
    # bias
    DelBias = ans_test - ans_formal
    bias = DelBias / len(df)

    # rmse
    rmse = np.sqrt(sum((df['test'] - df['formal'])**2) / len(df))

    # 测量值均值
    test_mean = ans_test / len(df)
    # 标准值均值
    formal_mean = ans_formal / len(df)

    # SI
    SI = np.sqrt(sum(((df['test'] - test_mean) - (df['formal'] - formal_mean)) ** 2) / len(df)) / formal_mean
  • 坐标轴的格式规范

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    # 正确显示中文和负号
    plt.rcParams['font.sans-serif']=['SimHei'] # 用来正常显示中文标签
    plt.rcParams['axes.unicode_minus']=True # 用来正常显示负号

    # 生成图的设置 包括坐标轴、色块范围、间距等
    plt.xlabel('浮标数据', fontsize=14)
    plt.ylabel('卫星检测数据', fontsize=14)
    plt.title('Data2010', fontsize=14)

    # 设置刻度间距
    x_major_locator = MultipleLocator(1)
    y_major_locator = MultipleLocator(1)

    # ax为两条坐标轴的实例
    ax = plt.gca()

    # 显示主刻度 均为1的倍数
    ax.xaxis.set_major_locator(x_major_locator)
    ax.yaxis.set_major_locator(y_major_locator)

    # 规定x y 轴的刻度范围
    plt.xlim(0, 10)
    plt.ylim(0, 10)
  • 普通散点图

    1
    df.plot.scatter(x='formal', y='test')
  • 彩色散点图

    • 根据每对数据的偏差,人为划分颜色
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    # 已知 数据的偏差 绝对值为 0.08
    bias = abs(bias)
    for i in range(len(df)):
    delData = abs(df['test'][i] - df['formal'][i])
    # 人为划定范围 10倍、20倍等 可自定义修改
    if delData == 0:
    df['color'][i] = 0
    elif(delData <= 10 * bias):
    df['color'][i] = 1
    elif delData <= 20 * bias:
    df['color'][i] = 2
    elif delData <= 30 * bias:
    df['color'][i] = 3
    else:
    df['color'][i] = 4
    1
    2
    # 由偏差 绘制散点图
    df.plot.scatter('formal', 'test', c='color', colormap='jet')
    • 根据点密度绘制散点图
    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 将x y转为一维
    data_test = []
    data_formal = []
    for i in range(len(df)):
    data_test.append(df['test'][i])
    data_formal.append(df['formal'][i])

    # 由点密度绘制散点图 hist2d
    plt.hist2d(data_formal, data_test, bins=100, cmin=1, vmin=1, vmax=10, cmap='jet')
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    - 关于hist2d的参数
    plt.hist2d(x, y, bins=100, cmin=1, vmin=1, vmax=10, cmap='jet')

    x y 为x轴 y轴的数据 且均为一维矩阵 如:[1, 2, 3, 4]
    bins 表示两个维度的箱数(若bins=40, nx=ny=bin | 若bins=[10,20], nx=10,ny=20
    个人认为 可以理解为 x y轴被切割成的份数

    cmin、cmax浮点 所有计数小于cmin或超过cmax 将不显示 这个参数很好理解 筛选一定计数范围的点

    cmap 颜色映射 就是我们所使用的颜色集合 无他 为了好看
    具体的映射参数 可查看这位博主的文章 https://blog.csdn.net/weixin_39580795/article/details/102622004

    vmin/vmax 官方解释为:vmin/vmax 无或标量,可选 传递给的参数 Normalize 实例。
    官方文档:https://www.osgeo.cn/matplotlib/api/_as_gen/matplotlib.pyplot.hist2d.html
    个人在调试时 理解为对所生成散点图色彩范围的划分 vmin-vmax的范围越大,各个颜色的划分便越精细

效果展示

代码

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
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.pyplot import MultipleLocator


df = pd.read_csv('test.csv')

ans_test = sum(df['test'])
ans_formal = sum(df['formal'])

# bias
bias = ans_test - ans_formal
bias = bias / len(df)

bias = abs(bias)
for i in range(len(df)):
delData = abs(df['test'][i] - df['formal'][i])
if delData == 0:
df['color'][i] = 0
elif(delData <= 10 * bias):
df['color'][i] = 1
elif delData <= 20 * bias:
df['color'][i] = 2
elif delData <= 30 * bias:
df['color'][i] = 3
else:
df['color'][i] = 4

# 由bias绘制散点图
df.plot.scatter('formal', 'test', c='color', colormap='jet')
plt.title('formal-test')
plt.show()


# 由密度绘制散点图 hist2d
plt.rcParams['font.sans-serif']=['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=True # 用来正常显示负号

data_test = []
data_formal = []
for i in range(len(df)):
data_test.append(df['test'][i])
data_formal.append(df['formal'][i])


plt.hist2d(data_formal, data_test, bins=100,
cmin=1, vmin=1, vmax=10, cmap='jet')
plt.tick_params(axis='both', which='major', labelsize=14)

# 坐标轴名称
plt.xlabel('浮标数据', fontsize=14)
plt.ylabel('卫星检测数据', fontsize=14)
plt.title('Data2010', fontsize=14)

# 设置刻度间距
x_major_locator = MultipleLocator(1)
y_major_locator = MultipleLocator(1)

# ax为两条坐标轴的实例
ax = plt.gca()

# 显示主刻度 均为1的倍数
ax.xaxis.set_major_locator(x_major_locator)
ax.yaxis.set_major_locator(y_major_locator)

# 规定x y 轴的刻度范围
plt.xlim(0, 10)
plt.ylim(0, 10)

plt.colorbar()
plt.show()