Matplotlib绘制二维误差图

Jan 22,2019   2710 words   10 min

Tags: Python

这篇博客利用Matplotlib绘制带有方向的散点误差图,局部如下。主要内容是如何画箭头。 箭头的长短表示误差的大小,方向表示误差的方向。

1.代码

# coding=utf-8
import matplotlib.pyplot as plt
import math
import argparse


def readData(file_path):
    text_file = open(file_path)
    points_x = []
    points_y = []
    errs_x = []
    errs_y = []

    line = text_file.readline().strip('\n')
    while line:
        line = text_file.readline().strip('\n')
        if line != '' and line.startswith("ID_"):
            tmp_elements = line.split("\t")
            points_x.append(float(tmp_elements[1]))
            points_y.append(float(tmp_elements[2]))
            errs_x.append(float(tmp_elements[5]) * 300)
            errs_y.append(float(tmp_elements[6]) * 300)

    print points_x.__len__(), 'points have been read.'
    return points_x, points_y, errs_x, errs_y


def drawPlot(points_x, points_y, errs_x, errs_y,
             arrow_length_ratio=0.15, arrow_width_ratio=0.5, lineWidth=0.15,
             figDpi=600, scale_x=18,
             save_path="figure.png"):
    width = max(points_x) + 100
    height = max(points_y) + 100
    min_x = min(points_x) - 100
    min_y = min(points_y) - 100

    ratio_y = (height + abs(min_y)) / (width + abs(min_x))
    scale_y = int(scale_x * ratio_y)

    for ex, ey in zip(errs_x, errs_y):
        if ex == 0:
            print '0x'
            ex = 0.001
        if ey == 0:
            print '0y'
            ey = 0.001

    print "plotting figure..."
    fig = plt.figure(figsize=(scale_x, scale_y))
    ax = fig.gca()
    ax.set_aspect('equal')
    ax.set_xlim(min_x, width)
    ax.set_ylim(min_y, height)
    plt.title("Errors", fontsize=2 * scale_x)
    ax.set_xlabel("X", fontsize=1.5 * scale_x)
    ax.set_ylabel("Y", fontsize=1.5 * scale_x)
    ax.grid()
    for x, y, dx, dy in zip(points_x, points_y, errs_x, errs_y):
        line_length = math.sqrt(dx * dx + dy * dy)
        ax.arrow(x, y, dx, dy, length_includes_head=True,
                 head_width=line_length * arrow_length_ratio * arrow_width_ratio,
                 head_length=line_length * arrow_length_ratio, fc='b', ec='b', linewidth=lineWidth)
    print 'x range:', min_x, ' - ', width
    print 'y range:', min_y, ' - ', height

    plt.show()
    print "saving figure..."
    plt.savefig(save_path, bbox_inches='tight', dpi=figDpi, pad_inches=0.25)


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Script for plotting error figure.')
    parser.add_argument('-input', help='file path for data file')
    parser.add_argument('-arrow_len', default='0.15', help='the ratio of arrow length ang total line length')
    parser.add_argument('-arrow_wid', default='0.5', help='the ratio of arrow width and arrow length')
    parser.add_argument('-line_wid', default='0.15', help='the width of lines')
    parser.add_argument('-dpi', default='600', help='the dpi of output image')
    parser.add_argument('-scale', default='18', help='the number to scale output image')
    parser.add_argument('-output', default='figure.png', help='file path for output file')

    args = parser.parse_args()

    try:
        pts_x, pts_y, errs_x, errs_y = readData(args.input)
        drawPlot(pts_x, pts_y, errs_x, errs_y,
                 arrow_length_ratio=float(args.arrow_len),
                 arrow_width_ratio=float(args.arrow_wid),
                 lineWidth=float(args.line_wid),
                 figDpi=int(args.dpi),
                 scale_x=int(args.scale),
                 save_path=args.output)
    except:
        print 'input \'-h\' to get help information'

完整的测试数据及代码见Github项目,点击查看

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

返回顶部