【Python中matplotlib的使用】

【Python中matplotlib的使用】

为了配合实验研究写的代码,临时学了一下matplotlib,感觉学到一些知识点,复盘一下,最近比较忙,先上代码。

一、txt文档初步处理

// An highlighted block
# 此代码功能:初始化文件的数据格式,修改标点 (#将:替换为空格 #将替换为空白 #将;替换为空格)
# 与link chain 5代码配套使用

f = open("msg.txt", "r", encoding="utf-8")
f_new = open("msg_new.txt", "w", encoding="utf-8")
find_str1 = ":"
find_str2 = ","
find_str3 = ";"
replace_str1 = " "
replace_str2 = ""
for line in f:
    if find_str1 in line:
        line = line.replace(find_str1, replace_str1)  # 将 : 替换为空格
    if find_str2 in line:
        line = line.replace(find_str2, replace_str2)  # 将 ,替换为空白(即相邻端口写在一起)
    if find_str3 in line:
        line = line.replace(find_str3, replace_str1)  # 将 ;替换为空格
    f_new.write(line)
    print(line)
f.close()
f_new.close()

二、端口流量信息绘制
1.效果图
【Python中matplotlib的使用】

2.完整代码

// An highlighted block
# 此代码功能:绘制一个端口的流量信息
import matplotlib.pylab as plt
import math

from pylab import *  # 解决字体问题
mpl.rcParams['font.sans-serif'] = ['SimHei']

txt = open("historySCHED1_new.txt", "r", encoding="utf-8")  # 打开链路时间文件
port = input("请输入端口名称port(如SW42SW52): ")

# 1.将输入端口port的所有流量信息提取到数组x中
x = []
tt = []
order = []
pan1 = 0
pan2 = 0
pan3 = 0

for line in txt:
    pan3 = 1
    ls = line.split()  # 以空格为分隔符,将line中元素分隔开,变为ls(列表)
    for s in ls:
        if s == port:
            pan1 = 1  # 找到port时pan1为1
            break
        # 排除掉下一个端口内的信息
        if pan1 == 1:
            if (s[0] != "0") & (s[0] != "1") & (s[0] != "2") & (s[0] != "3") & (s[0] != "4") & (s[0] != "5") & (s[0] != "6") & (s[0] != "7") & (s[0] != "8") & (s[0] != "9") & (s[0] != "t"):
                pan2 = 1  # 当pan2为1时说明此端口内信息已经取完
        if (pan1 == 1) & (pan2 != 1):
            if pan3 == 1:
                pan3 = 0
                x.append(float(ls[0])), x.append(float(ls[1]))  # 将端口的时间信息转化为数字添加到x中
                tt.append(ls[2])  # 将端口的时间信息转化为数字添加到x中
                order.append(ls[3])  # 将端口的时间信息转化为数字添加到x中

print("端口{}的流量为:".format(port))
for i in range(len(tt)):
    print("{} {} {} {}".format(x[2*i], x[2*i+1], tt[i], order[i]))

length = len(tt)  # 总信息条数

height = []
for i in range(length):
    # height.append(1)  # 高度一样
    # height.append(round((max(x)-x[2*i+1])/(x[1]-x[0])))  # 计算端口的高度,高度随时间递减
    height.append(round(x[2*i+1] - x[2*i]))
print("所有端口的高度为:{}".format(height))


# 2.绘制端口时间信息
for i in range(length):
    x_axis_data = [x[2*i], x[2*i], x[2*i+1], x[2*i+1]]  # 通过绘制四个点来绘制折线
    y_axis_data = [0, height[i]+1, height[i]+1, 0]

    plt.text(x[2*i]+5, height[i]+1.05, "{} {}".format(tt[i], order[i]), fontsize=5)  # 绘制折线上的文字

    plt.plot(x_axis_data, y_axis_data, label="{}第{}次".format(tt[i], order[i]))  # label绘制图例
    plt.xlabel("时间(us)")  # x轴标题
    plt.xticks(fontsize=5)  # x轴数字大小
    plt.title("端口 {} 的流量图".format(port))
# plt.savefig('link chain{}第{}次.jpg'.format(tt, order), dpi=1200)  # 保存图片(此行要在绘制前面写)
plt.legend(loc='upper right', prop={'size': 4})
plt.show()

txt.close()

三、链路流量信息绘制
1.效果图
【Python中matplotlib的使用】

2.完整代码

// An highlighted block
# 此代码功能:绘制同轴的时间信息图(幅度规律变化且能分开两条链路)
import matplotlib.pylab as plt
import math

from pylab import *  # 解决字体问题
mpl.rcParams['font.sans-serif'] = ['SimHei']

#  打开用test代码处理后的三个文档
txt1 = open("vls_new.txt", "r", encoding="utf-8")  # 打开链路路径文件
txt2 = open("msg_new.txt", "r", encoding="utf-8")  # 打开链路参数文件
txt3 = open("historySCHED1_new.txt", "r", encoding="utf-8")  # 打开链路时间文件

pan1 = 0  # 为1代表找到链路端口
pan2 = 0  # 为1代表找到tt编号

tt = input("请输入tt编号(如tt3.0): ")
order = input("请输入tt出现的次序(如3): ")

# 1.搜索到tt编号对应的vl编号
for line in txt2:
    ls = line.split()  # 以空格为分隔符,将line中元素分隔开,变为ls(列表)
    for s in ls:
        if s == tt:
            vl = ls[3]
            print("vl编号为:", vl)

# 2.搜索到vl编号对应链路并且将链路端口信息输入到link中
for line in txt1:
    ls = line.split()  # 以空格为分隔符,将line中元素分隔开,变为ls(列表)
    for s in ls:
        if s == vl:
            link = ls
            length = len(link)-1
            print("链路为link:", link)
            print("链路长度length:", length)

# 3.搜索链路端口对应的时间信息
x = []
for i in range(int(length)):
    for line in txt3:
        pan2 = 0
        ls = line.split()  # 以空格为分隔符,将line中元素分隔开,变为ls(列表)
        for s in ls:
            if s == link[i+1]:  # 找到链路第一个端口
                pan1 = 1
                break
            if s == tt:  # 找到端口内对应的tt编号所在行
                pan2 = 1
            if s == str(int(order)-1):  # 找到对应的tt次序
                if (pan1 == 1) and (pan2 == 1):  # 找到对应tt编号并且找到tt出现的次序和端口的位置
                    pan1 = pan2 = 0
                    x.append(float(ls[0])), x.append(float(ls[1]))  # 将端口的时间信息转化为数字添加到x中
                    print("链路第{}个端口 {} 第{}次出现为:{}".format(i + 1, link[i + 1], int(order), line))
                    break
                else:
                    pan2 = 0
                    break
    txt3.seek(0)  # 解决了文本txt3不能重复遍历的问题
print("链路所有的端口时间为 x:", x)

# 4.绘制链路传输图

# # 计算端口高度相关思路的参数(此段代码可去除)
# print('时间最大值和最小值为:', max(x), min(x))
# differance = max(x)-min(x)
# print("最大值和最小值的时间差值为:", differance)
# num = int(differance/(x[1]-x[0]))
# print("较长链路端口个数为:", num)

height = []
for i in range(length):
    height.append(round((max(x)-x[2*i+1])/(x[1]-x[0])))  # 计算端口的高度
print("所有端口的高度为:{}".format(height))

# 将端口高度因为链路重复引起的重合去除
height2 = height
for i in range(length):
    for j in range(length-i-1):
        if height[i] == height2[j+i+1]:  # 错位去重
            height[i] = height[i]+0.5  # 将重复的端口高度加0.5
            break
print("去重后所有端口的高度为:{}".format(height))

# 绘制端口时间信息
for i in range(int(length)):
    x_axis_data = [x[2*i], x[2*i], x[2*i+1], x[2*i+1]]  # 通过绘制四个点来绘制折线
    y_axis_data = [0, height[i]+1, height[i]+1, 0]

    plt.text(x[2*i]+5, height[i]+1.05, "{}".format(link[i+1]))  # 绘制折线上的文字

    # 绘制点的坐标
    plt.text(x[2*i]+2, height[i]+0.9, x[2*i], fontsize=5)  # 绘制奇数点的坐标
    plt.text(x[2*i+1]+2, height[i]+0.9, x[2*i+1], fontsize=5)  # 绘制偶数点的坐标
    # "{}{}{}".format(x[2*i], '\n', link[i+1]) #给坐标添加标签
    # "{}{}{}".format(x[2*i+1], '\n', link[i+1])
    # 0+0.45*(i % 2) # 坐标在底部时,上下位置区分

    plt.plot(x_axis_data, y_axis_data, label=link[i+1], marker='>', markersize=3)  # label绘制图例
    plt.xlabel("时间(us)")  # x轴标题
    plt.xticks(fontsize=8)  # x轴数字大小
    plt.title("链路 {} {} 第{}次消息的流量图".format(vl, tt, order))
    plt.legend()
# plt.savefig('link chain{}第{}次.jpg'.format(tt, order), dpi=1200)  # 保存图片(此行要在绘制前面写)
plt.show()


txt1.close()
txt2.close()
txt3.close()



上一篇:挑战程序设计竞赛 第十二章 图


下一篇:PTA L1-019 谁先倒(团体程序设计天梯赛)