python-3.x 生成.txt文件的散点图

8yoxcaq7  于 2023-04-22  发布在  Python
关注(0)|答案(1)|浏览(180)

我试图通过从txt文件中提取信息来绘制散点图,其中x轴是我的测试完成运行所需的时间,Y轴是每个成功ping命令所需的时间,我可以使用以下代码块来完成:

import matplotlib.pyplot as plt

#Read data from file
data = open("EDS4008_2023_04_12.txt",'r')
list = data.readlines()

#Extract time and ping values from the data
time = []
ping_time = []
index = 0

for string in list:
    #print(string)
    index += 1
    if (" time" in string) and (" bytes" in string):
        var1 = string.split(' ')[8]
        #print(var1)
        if "=" in var1:
            t = var1.split("=")[1].split("m")[0]
            ping_time.append(t)
            time.append(index / 60)
        elif "<" in var1:
            t = var1.split("<")[1].split("m")[0]
            ping_time.append(t)
            time.append(index / 60)
        else:
            print("error")
            ping_time.append('0')
            time.append(index / 60)
    else:
        print("skip this line")
        ping_time.append('0')
        time.append(index / 60)

print(ping_time)
print(time)

plt.scatter(time, ping_time)

plt.xlabel('Time (minutes)')
plt.ylabel('Ping Time (ms)')
plt.title('Pinging Duration')

plt.show()

以下是散点图:

我想知道是否有一种方法可以删除Y轴上0处的所有绘图点,以及如何绘制一条水平线,表示txt文件中与Y轴读数对应的读数的最大值和最小值,以便最终图形看起来像这样:

下面是一个txt文件的示例:

scyqe7ek

scyqe7ek1#

由于您是在从输入文件中阅读数据之后构造数据点的,如果您不希望Y轴上的数据值为0,那么为什么不将它们添加到数据点中呢?
在不对代码做太多修改的情况下,它可能看起来像:

import matplotlib.pyplot as plt

#Read data from file
#data = open("EDS4008_2023_04_12.txt",'r')
input_file = open("input_data.txt")
input_lines = input_file.readlines()

#Extract time and ping values from the data
time = []
ping_time = []
index = 0

for current_line in input_lines:
    #print(string)
    index += 1
    if (" time" in current_line) and (" bytes" in current_line):
        var1 = current_line.split(' ')[8]
        #print(var1)
        if "=" in var1:
            t = var1.split("=")[1].split("m")[0]
            ping_time.append(int(t))
            time.append(index / 60)
        elif "<" in var1:
            t = var1.split("<")[1].split("m")[0]
            ping_time.append(int(t))
            time.append(index / 60)
        else:
            print("error")
            # Don't add this point
            # ping_time.append(0)
            # time.append(index / 60)
    else:
        print("skip this line")
        # Don't add this point
        # ping_time.append(0)
        # time.append(index / 60)

print(ping_time)
print(time)

max_value = max(ping_time)
min_value = min(ping_time)

plt.scatter(time, ping_time)

plt.xlabel('Time (minutes)')
plt.ylabel('Ping Time (ms)')
plt.title('Pinging Duration')
plt.axhline(max_value)
plt.axhline(min_value)

plt.show()
  • 为了绘制读数的最大值和最小值的线,我们使用这些函数:
  • min()
  • max()
  • 平面轴线

我还要强调的是,你不应该创建具有泛型名称的变量,因为其中一些名称已经在标准库中使用。例如,这些名称已经存在:

  • list()是Python中的一个基本类
  • time是标准库的模块
  • string是标准库的一个模块

但我们可以做得更好。
当你需要从文本中提取数据时,regular expressions是一个非常有用的工具。

import re

import matplotlib.pyplot as plt

matcher = re.compile(r'bytes=\d+ time[=<](?P<duration>\d+)ms')

with open("input_data.txt") as input_file:
    ping_time = []
    timestamps = []
    for (line_number, current_line) in enumerate(input_file):
        if line_matched := matcher.search(current_line):
            timestamps.append(line_number / 60)
            ping_time.append(int(line_matched.group('duration')))
        else:
            print('Skip this line')

print(ping_time)
print(timestamps)

max_value = max(ping_time)
min_value = min(ping_time)

plt.scatter(timestamps, ping_time)

plt.xlabel('Time (minutes)')
plt.ylabel('Ping Time (ms)')
plt.title('Pinging Duration')
plt.axhline(max_value)
plt.axhline(min_value)

plt.show()

要理解此代码,您需要阅读:

  • 使用re module的正则表达式
  • enumerate()
  • 使用上下文管理器确保文件在您不再需要时关闭,如官方教程本节的第二个示例所述

一种高级的方法是使用生成器表达式和zip()以及正则表达式来创建代码,这些代码将更加紧凑,同时不会将文件的所有内容保留在内存中。

import re

import matplotlib.pyplot as plt

matcher = re.compile(r'bytes=\d+ time[=<](?P<duration>\d+)ms')

with open("input_data.txt") as input_file:
    lines_matched = (matcher.search(current_line) for current_line in input_file)
    data_points = (
        (x / 60, int(current_match.group('duration')))
        for (x, current_match) in enumerate(lines_matched)
        if current_match
    )
    timestamps, ping_time = zip(*data_points)

print(ping_time)
print(timestamps)

max_value = max(ping_time)
min_value = min(ping_time)

plt.scatter(timestamps, ping_time)

plt.xlabel('Time (minutes)')
plt.ylabel('Ping Time (ms)')
plt.title('Pinging Duration')
plt.axhline(max_value)
plt.axhline(min_value)

plt.show()

这就是你要找的吗

相关问题