Python读取txt文件画Loss曲线图---txt文件转xls文件---xls文件转txt文件--xml文件转txt文件

任务1- 读取.txt文件画折线图(曲线图)

任务2- 将.txt文件转换成.xls(excel)文件

任务3- 将.xls(excel)文件转换成.txt文件

任务4- 读取.txt文件画折线图(曲线图)

任务5- xml格式的数据集标签文件转.txt文件

任务6- 读取两个.txt文件画折线图(曲线图)

最近在做目标检测的任务,但是由于自己训练的损失函数不是自己想要的,但是自己的程序在训练的时候每个E p o c h EpochEpoch都会生成一个模型的损失数值,所以想根据这些数值自己画图。

任务1:根据t x t txttxt文件内的数值,生成损失曲线。

t x t txttxt文件内的数据样例如下图所示:
在这里插入图片描述
因为我的模型训练了150次,所以这样的数据有150个,且只有一列。直接在代码里详细叙述:

#导入必须的包
import matplotlib.pyplot as plt
import numpy as np
#-----------  打开txt文件   ----------
file = open('YOLOV4.txt')
#-----------  逐行读取文件内的数据  ------------
data = file.readlines()
#-----------  根据自己的需要查看data的内容  ---------
#print(data)
'''
txt文件的数值为y轴的数据
所以x要根据y的个数有序生成
'''
#------ x轴数据有序生成150个(根据自己的横坐标范围自己修改范围)  ----
x = np.arange(0,150)
#----------  新建一个空的列表,用于存储上一步逐行读取的data  ------------
y = []
#---------- 用循环的方式添加进列表  -----------
for num in data:
	#------split用于将每一行数据用逗号分割成多个对象-----
    #------取分割后的第0列,转换成float格式后添加到列表中-------
    y.append(float(num.split(',')[0]))
#---------------    输出图    ----------------------
#---------   可以理解为在图上加载x和y的数据   label为关于x和y曲线的标签------------
pic = plt.plot(x,y,label='Yolov4')
#---------   x轴的小标题   -------------
plt.xlabel('Epoch')
#---------   y轴的小标题   -------------
plt.ylabel('Loss')
#---------   整个图的标题  ----------
plt.title('yolov4-loss')
plt.legend()
plt.show()

代码关于画图的每个细节写的很详细,下面生成的折线图。
在这里插入图片描述

任务2- 将.txt文件转换成.xls(excel)文件

需要的同学直接复制代码,代码中注释了你需要修改的地方。

import xlwt
def txt_xls(filename, xlsname):
    try:
        f = open(filename, 'r', encoding='utf-8')
        xls = xlwt.Workbook()
        sheet = xls.add_sheet('sheet1', cell_overwrite_ok=True)
        x = 0
        while True:
            # 按行循环,读取文本文件
            line = f.readline()
            if not line:
                break
            for i in range(len(line.split('\t'))):
                item = line.split('\t')[i]
                sheet.write(x, i, item)
            x += 1
        f.close()
        # 保存xls文件
        xls.save(xlsname)  
    except:
        raise
'''
下面的地址中就是自己根据自己的需要修改的地方
为什么看上去没有路径呢?因为我是把txt文件和运行的此程序放在了同一个文件夹中
所以生成的.xls文件也在同级文件下,也就是他们在同一个文件夹中
如果你没放在一起,建议使用E://Path//...
'''
if __name__ == "__main__":
    #----------   需要转化的.txt文件   -----------
    filename = "YOLOV4.txt"  
    #----------   转换后的.xls文件名   -----------
    xlsname = "YOLOV4.xls"  # 保存及命名
    txt_xls(filename, xlsname)

任务3- 将.xls(excel)文件转换成.txt文件

. x l s .xls.xls文件转换成. t x t .txt.txt文件。

python
import pandas as pd
#----------   如果你的.xls文件开了多个窗口文件(sheet1,sheet2,sheet3....)使用下面的代码    -----------
#df = pd.read_excel('YOLOV4.xls', sheet_name='Sheet1',header=None)
#----------   如果你的.xls文件没有开多个窗口(没有sheet1,sheet2,sheet3....)试用下面的代码
data = pd.read_excel('YOLOV4.xls', sheet_name='Sheet1',header=None)
print('正在读取将.xls文件内容')
#----------  写入txt文件,seq表示逗号分隔  --------------
data.to_csv('YOLOV4.txt', header=None, sep=',', index=False)
print('.xls文件转换成.txt文件成功')

任务4- 读取.txt文件画折线图(曲线图)

该任务算是任务一的进阶版,通过文件数据的转换,我的. t x t .txt.txt文件的内容不再是一列,而是两列,第一列为序号,第二列为数值,基于此种情况,读取. t x t .txt.txt文件,将其以折线图(曲线图)表示出来。
下图是我现在. t x t .txt.txt数据的图例。
在这里插入图片描述
可以发现和任务一数据唯一不同就是多了一列的序列号,下面的是基于任务一改进的,就是改了几行,修改后的内容以注释的形式保存。话不多说直接代码中详细介绍:

#导入必须的包
import matplotlib.pyplot as plt
import numpy as np
#-----------  打开txt文件   ----------
file = open('file2.txt')
#-----------  逐行读取文件内的数据  ------------
data = file.readlines()
#-----------  根据自己的需要查看data的内容  ---------
#print(data)
'''
txt文件的数值为y轴的数据
所以x要根据y的个数有序生成
'''
#------ x轴数据有序生成150个(根据自己的横坐标范围自己修改范围)  ----
#x = np.arange(0,150)
#----------  新建一个空的列表,用于存储上一步逐行读取的data  ------------
x = []
y = []
#---------- 用循环的方式添加进列表  -----------
for num in data:
	#------split用于将每一行数据用逗号分割成多个对象-----
	#------x读取data数据的第一列(也就是序列号)
    x.append(float(num.split(',')[0]))
    #------取分割后的第0列,转换成float格式后添加到列表中-------
    #------y读取data数据的第二列(也就是数值)
    y.append(float(num.split(',')[1]))
#---------------    输出图    ----------------------
#---------   可以理解为在图上加载x和y的数据   label为关于x和y曲线的标签------------
pic = plt.plot(x,y,label='Yolov4')
#---------   x轴的小标题   -------------
plt.xlabel('Epoch')
#---------   y轴的小标题   -------------
plt.ylabel('Loss')
#---------   整个图的标题  ----------
plt.title('yolov4-loss')
plt.legend()
plt.show()

下面是得到的折线图(曲线图),和任务一得到的一模一样。
在这里插入图片描述

任务5- xml格式的数据集标签文件转.txt文件

在做目标检测任务时,我们手工打的标签往往都是.xml的文件,但是对于很多的网络,标签文件都需要.txt的文件,所以需要将.xml文件转换成模型需要的.txt文件,直接下面的代码可以转换:

#-------------------------------  successful  ----------------------------------
import os
import xml.etree.ElementTree as ET
from decimal import Decimal
#-------------------------     xml文件夹路径   ----------------------------
dirpath = 'E:\\pycharm\\py_shiyancode\\LYD-Champion-Function\\xml_origan'  
#----------------------   转换后的txt文件夹路径   ----------------------
newdir = 'E:\\pycharm\\py_shiyancode\\LYD-Champion-Function\\txt' 

if not os.path.exists(newdir):
    os.makedirs(newdir)
for fp in os.listdir(dirpath):

    root = ET.parse(os.path.join(dirpath, fp)).getroot()

    xmin, ymin, xmax, ymax = 0, 0, 0, 0
    sz = root.find('size')
    width = float(sz[0].text)
    height = float(sz[1].text)
    filename = root.find('filename').text
    print(fp)
    with open(os.path.join(newdir, fp.split('.')[0] + '.txt'), 'a+') as f:
        for child in root.findall('object'):  # 找到图片中的所有框

            sub = child.find('bndbox')  # 找到框的标注值并进行读取
            sub_label = child.find('name')
            xmin = float(sub[0].text)
            ymin = float(sub[1].text)
            xmax = float(sub[2].text)
            ymax = float(sub[3].text)
            try:  # 转换成yolov的标签格式,需要归一化到(0-1)的范围内
                x_center = Decimal(str(round(float((xmin + xmax) / (2 * width)), 6))).quantize(Decimal('0.000000'))
                y_center = Decimal(str(round(float((ymin + ymax) / (2 * height)), 6))).quantize(Decimal('0.000000'))
                w = Decimal(str(round(float((xmax - xmin) / width), 6))).quantize(Decimal('0.000000'))
                h = Decimal(str(round(float((ymax - ymin) / height), 6))).quantize(Decimal('0.000000'))
                print(str(x_center) + ' ' + str(y_center) + ' ' + str(w) + ' ' + str(h))
                # 读取需要的标签
                if sub_label.text == 'armor':
                    f.write(' '.join([str(0), str(x_center), str(y_center), str(w), str(h) + '\n']))
            except ZeroDivisionError:
                print(filename, '的 width有问题')

任务6- 读取两个.txt文件画折线图(曲线图)

由于技术有限,只能使用最笨的方式读取每个文本的数据,然后再逐个遍历文本中的内容,将其添加进入列表内,然后画图,方法不是最优的,但是结果没问题。由于我没有之前的损失函数的文件了,所以自己手动添加进入文件几个数,作为教程。
这里需要注意:

  • 如果你的t x t txttxt文本数据内只有一列,且这一列就是你要绘制图的y yy数值,则只需要将以下代码中的y 1 y1y1直接读取第0 00列就可以了,y 2 y2y2也同理,读取第0 00列(1默认为第2例)。至于x xx,你只需要根据y的个数生成1 − − l e n ( y 1 ) 1--len(y1)1len(y1)的数就可以画图了。(下面就是t x t txttxt文本数据内的内容,仅作为参考)
  • 保持y 1 y1y1的个数与y 2 y2y2的个数一致,不然会超出x xx坐标的范围
    在这里插入图片描述

import matplotlib.pyplot as plt

if __name__== '__main__':
    # -----------  打开txt文件(路径一定要修改成自己的路径)   ----------
    file1 = open('./dataloader_experience/1.txt')
    file2 = open('./dataloader_experience/2.txt')
    # -----------  逐行读取文件内的数据  ------------
    data1 = file1.readlines()
    data2 = file2.readlines()
    # -----------  根据自己的需要查看data的内容  ---------
    # print(data)
    '''
    txt文件的数值为y轴的数据
    所以x要根据y的个数有序生成
    '''
    # ------ x轴数据有序生成150个(根据自己的横坐标范围自己修改范围)  ----
    # x = np.arange(0,150)
    # ----------  新建一个空的列表,用于存储上一步逐行读取的data  ------------
    x1 = []
    y1 = []
    y2 = []
    # ---------- 用循环的方式添加进列表  -----------
    for num1 in data1:
        # ------split用于将每一行数据用逗号分割成多个对象-----
        # ------x读取data数据的第一列(也就是序列号)
        #-------建议以float类型添加,因为得到的损失值,一般都为小数
        x1.append(float(num1.split(',')[0]))
        # ------取分割后的第0列,转换成float格式后添加到列表中-------
        # ------y读取data数据的第二列(也就是数值)
        y1.append(float(num1.split(',')[1]))

    for num2 in data2:
        y2.append(float(num2.split(',')[1]))
    # ---------------    输出图    ----------------------
    # ---------   可以理解为在图上加载x和y的数据   label为关于x和y曲线的标签------------
    #    根据需求变换线的格式和颜色
    plt.plot(x1, y1,label= 'yolov4_loss2')
    plt.plot(x1, y2, color='red', linestyle='--',label = 'yolov4_loss1')
    # ---------   x轴的小标题   -------------
    plt.xlabel('Epoch')
    # ---------   y轴的小标题   -------------
    plt.ylabel('Loss')
    # ---------   整个图的标题  ----------
    plt.title('yolov4-loss')
    plt.legend()
    plt.show()

结果图如下
在这里插入图片描述
总结:

  • 如果你的数据是. t x t .txt.txt文件,数据只有一列,那么任务一就可以解决你的问题
  • 如果你有. x l s .xls.xls格式的文件,你可以通过任务三将其转换成. t x t .txt.txt文件,然后通过任务一或者四解决你的问题
  • 如果你将. t x t .txt.txt文件转换成. x l s .xls.xls文件,任务二可以解决你的问题
  • 如果你将. x m l .xml.xml文件转换成. t x t .txt.txt文件,任务五可以解决你的问题
    如果对您有用,不妨点个赞吧在这里插入图片描述

版权声明:本文为qq_46497842原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。