散点图

2022-11-01 15:37:41 浏览数 (1)

前言

源数据是一个data.txt

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

代码语言:javascript复制
xlswrite('test.csv')
csvwrite('test.csv')

操作步骤

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

读取数据

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

代码语言:javascript复制
import pandas as pd
df = pd.read_table('data2010.txt', names=['time', 'test','formal', 'color'], header=None, sep=" ") 

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

代码语言:javascript复制
df = pd.read_csv('test.csv')

需求分析

  • 需要计算标准数据与实际测量数据的偏差(bias)、均方根误差(RMSE)、散射指数(SI)三个值
  • 需要根据点坐标(标准值,实际值)绘制散点图
  • 需要根据点密度绘制不同颜色的散点分布图 效果应如下图所示:

具体实现

三个公式的计算

代码语言:javascript复制
# 分别对 测量值 和 标准值 求和
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

坐标轴的格式规范

代码语言:javascript复制
# 正确显示中文和负号
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)

普通散点图

代码语言:javascript复制
df.plot.scatter(x='formal', y='test')

彩色散点图

  • 根据每对数据的偏差,人为划分颜色
代码语言:javascript复制
# 已知 数据的偏差 绝对值为 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
代码语言:javascript复制
# 由偏差 绘制散点图
df.plot.scatter('formal', 'test', c='color', colormap='jet')
  • 根据点密度绘制散点图
代码语言:javascript复制
# 将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')
代码语言:javascript复制
- 关于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的范围越大,各个颜色的划分便越精细

效果展示

代码

代码语言:javascript复制
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()

0 人点赞