使用Matplotlab绘制散点图

Jul 16,2018   4024 words   15 min

Tags: Python

现有一堆数据,是散点坐标形式,现在需要将它们绘制成散点图。数据格式如下图。 第一行为一个数字,表示当前文件共有多少行数据。 第二行开始为真正的数据,各数据间以一个Tab分隔。第一列是数据点ID名,第二列是X坐标,第三列是Y坐标,第四、五列暂时用不到,不用管它。第六列是垂轨误差,第七列是沿轨误差。我们要画的一共是4个图,即X方向的垂轨误差图、X方向的沿轨误差图、Y方向的垂轨误差图、Y方向的沿轨误差图。简单解释一下例如X方向的垂轨误差图就是以读取的X坐标为X轴,垂轨误差为Y轴绘制散点图。要使用Matplotlab绘图需要两步,第一步是读取数据,第二部是调用函数绘图。

1.读取数据

由于上面介绍的数据格式是我们自己定义的,并没有任何通用的函数可以读取,所以只能自己写个小函数读取。好在Python读取文本文件还是挺简单的,下面直接上代码。

def readData(file_path):
    # 打开一个文本文件
    text_file = open(file_path)
    data_item = []
    # x轴垂轨数据
    x_ev = []
    # x轴沿轨数据
    x_eh = []
    # y轴垂轨数据
    y_ev = []
    # y轴沿轨数据
    y_eh = []

    # 先读取第一行,读取时注意去掉行尾的换行符
    line = text_file.readline().strip('\n')
    # 然后逐行读取数据
    while line:
        line = text_file.readline().strip('\n')
        # 如果读取的行内容不为空,则添加到list中
        # 注意这里并不能用None,注意空字符串和空对象的区别
        if line != '':
            data_item.append(line)

    # 读取完成后对于读取的每行数据进行简单的提取和处理
    for i in range(data_item.__len__()):
        data = data_item[i].split('\t')
        x_coordinate = float(data[1])
        y_coordinate = float(data[2])
        error_vertical = float(data[5])
        error_horizontal = float(data[6])
        x_ev.append([x_coordinate, error_vertical])
        x_eh.append([x_coordinate, error_horizontal])
        y_ev.append([y_coordinate, error_vertical])
        y_eh.append([y_coordinate, error_horizontal])

    # 由于原始数据中坐标并没有进行排序,因此这里进行排序
    x_ev.sort()
    x_eh.sort()
    y_eh.sort()
    y_ev.sort()
    return x_ev, x_eh, y_ev, y_eh

在读取数据完成后,下面就是用Matplotlab绘图了。

2.Matplotlab绘图

由于我们需要画四个图,因此可以采用subplot的方式绘制。代码较为简单,基本一看就能知道是什么含义,所以直接贴出来。如果有需要,直接修改相关内容即可。

# 设置绘图的大小(格网)
plt.figure(figsize=(16, 10))

# 221表示分成2行2列,占用第一块(1行1列)
plt.subplot(221)
plt.title("Rule of residual errors across the track")
plt.xlabel("X")
plt.ylabel("Errors(pixels)")
# 是否显示格网
plt.grid(True)
# s表示散点大小,alpha表示透明度,c表示颜色
points = plt.scatter(np.array(x_ev)[:, 0],
                     np.array(x_ev)[:, 1],
                     s=1,
                     alpha=0.5,
                     c='r')
plt.legend([points], ['Across Track Error'])

# 221表示分成2行2列,占用第三块(2行1列)
plt.subplot(223)
plt.title("Rule of residual errors along the track")
plt.xlabel("X")
plt.ylabel("Errors(pixels)")
plt.grid(True)
points = plt.scatter(np.array(x_eh)[:, 0],
                     np.array(x_eh)[:, 1],
                     s=1,
                     alpha=0.5)
plt.legend([points], ['Along Track Error'])

# 221表示分成2行2列,占用第二块(1行2列)
plt.subplot(222)
plt.title("Rule of residual errors across the track")
plt.xlabel("Y")
plt.ylabel("Errors(pixels)")
plt.grid(True)
points = plt.scatter(np.array(y_ev)[:, 0],
                     np.array(y_ev)[:, 1],
                     s=1,
                     alpha=0.5,
                     c='r')
plt.legend([points], ['Across Track Error'])

# 221表示分成2行2列,占用第四块(2行2列)
plt.subplot(224)
plt.title("Rule of residual errors along the track")
plt.xlabel("Y")
plt.ylabel("Errors(pixels)")
plt.grid(True)
points = plt.scatter(np.array(y_eh)[:, 0],
                     np.array(y_eh)[:, 1],
                     s=1,
                     alpha=0.5)
plt.legend([points], ['Along Track Error'])

# 最后保存绘图,dpi越高图像质量越好
plt.savefig('figure', dpi=600)
plt.show()

最终,绘制效果如下。由于上传时压缩等问题,看起来效果没那么好了。原图是9600×6000带透明度的png图像,有8.67MB大小。如果感兴趣可以点击这里下载原图“欣赏”。 不得不说Matplotlab是科研绘图利器,使用Matplotlab绘制出的图像质量还是比较高的,抗锯齿等等方面要由于一些老版本的Matlab,但是绘制代码其实和Matlab差不多。

[2019-8-17更新]

关于Matplotlib绘图不能显示汉字的问题,在代码中添加下面两句话即可:

# 支持中文
font_name = "SimHei"  # 字体名称,这里默认用黑体
plt.rcParams['font.sans-serif'] = [font_name]  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

然后就可以在绘图中显示中文了,还有一个需要注意的地方就是绘图时传入的字符串必须是Unicode字符串(字符串前面加u),不能是普通默认编码字符串,否则会报错,还是显示不了。更多相关内容可参考这个网页。实际测试代码段如下:

# coding=utf-8
from matplotlib import pyplot as plt

if __name__ == '__main__':
    font_name = "SimHei"
    plt.rcParams['font.sans-serif'] = [font_name]
    plt.rcParams['axes.unicode_minus'] = False

    x = [1, 5]
    y = [2, 7]
    # 手动设置字体
    font = {'family': font_name,
            'weight': 'normal',
            'size': 14,
            }
    plt.title(u"测试图例", font)
    plt.xlabel(u"x轴", font)
    plt.ylabel(u"y轴", font)
    plt.plot(x, y)
    plt.show()

效果如下。 [更新结束]

除此之外应别人的需求,还写了其它几个版本的脚本,独立脚本调用版、封装成函数的版本等等,同时还写了绘制3D散点图的代码,如下图所示,都放在了Github这个仓库中,感兴趣可以下载看看。相比于上面的代码多了如设置坐标轴取值范围、间隔等代码,但也都比较简单。

以上便是简单的使用Matplotlab绘制散点图的相关内容,总体来说比较简单,但也基本涵盖了日常的需求,标题、坐标轴、格网、图例、颜色等等,都在上面的代码中用到了。更多更复杂的相关内容可以参阅参考资料中的网页。

3.参考资料

  • [1]https://www.cnblogs.com/sunshinewang/p/6853813.html
  • [2]https://www.cnblogs.com/liutongqing/p/6985805.html
  • [3]https://www.jb51.net/article/136567.htm
  • [4]https://blog.csdn.net/zhangqilong120/article/details/72633115
  • [5]https://blog.csdn.net/gatieme/article/details/61416645
  • [6]https://matplotlib.org/users/legend_guide.html
  • [7]https://blog.csdn.net/eddy_zheng/article/details/48713449
  • [8]https://blog.csdn.net/helunqu2017/article/details/78641290/
  • [9]https://blog.csdn.net/xtingjie/article/details/71156743

本文作者原创,未经许可不得转载,谢谢配合

返回顶部