使用排序的文件从原始文件中绘制带有相应Y值的X轴

时间:2019-06-21 18:33:52

标签: python python-3.x sorting matplotlib graph

Sample Data on GitHub

我有一个包含2列的csv文件。第一列的格式为:name001.a.a,第二列为4位数字(例如:0001)。

我还有另一个文件已对上面文件的第一列进行了排序。

索引第一列的目的是因为1)我有很多这些文件,将来会在同一张图中绘制出来2)我需要对它们进行排序。

具有两列的实际文件( us_csv_file )的格式如下:

name002.a.a,0002
name001.a.a,0001
name005.a.a,0025

已排序的CSV文件( hostnum.csv )-我用来对第一列进行排序的方式如下(定界符为TAB):

"1    name001.a.a"
"2    name002.a.a"
"3    name005.a.a"

我试图寻找其他解决方案,或者解决它,但是找不到。有人可以帮我提供代码吗?

我的问题是:

如何使用排序后的文件绘制带有字符串标签(不带索引号)的X轴,但显示第一个文件中Y值对应的4位数字?

我使用excel创建的示例图如下所示: Graph that was created as a model

-------------------------------------------- ---------------- 编辑1 ----------------------------------------- -------------------

*更新:图形显示在下面的代码之后* After New Code -GRAPH

from matplotlib import pyplot as plt
from matplotlib import ticker as ticker
from textwrap import wrap
import numpy as np
import csv

csv_file = []
with open('hostnum.csv', 'r') as host:
    for line in host.readlines():
        line = line.replace('"', '')
        line = line.strip('\n')
        rank, value = line.split("  ")
        csv_file.append(value)

us_csv_file = []
with open('firsFile.csv', 'r') as f:
    csvreader = csv.reader(f)
    for line in csvreader:
        us_csv_file.append(line)

us_csv_file1 = []
with open('secondFile.csv', 'r') as f:
    csvreader = csv.reader(f)
    for line in csvreader:
        us_csv_file1.append(line)

us_csv_file2 = []
with open('thirdFile.csv', 'r') as f:
    csvreader = csv.reader(f)
    for line in csvreader:
        us_csv_file2.append(line)        

us_csv_file.sort(key=lambda x: csv_file.index(x[0]))
us_csv_file1.sort(key=lambda x: csv_file.index(x[0]))
us_csv_file2.sort(key=lambda x: csv_file.index(x[0]))


plt.title("\n".join(wrap("ery very very very long long long title title title that that that wrapped wrapped wrapped")))
plt.xlabel("Node Names", fontsize = 8)
plt.ylabel("Run Times", fontsize = 8)



plt.plot([int(item[1]) for item in us_csv_file], 'o-')
plt.plot([int(item[1]) for item in us_csv_file1], 'o-')
plt.plot([int(item[1]) for item in us_csv_file2], 'o-')

#plt.xticks(np.arange(len(csv_file)), [item for item in csv_file])
plt.xticks(np.arange(len(csv_file))[::100], csv_file[::100])
plt.savefig('./test.png') #saves a picture of the graph to the file

plt.show()

-------------------------------------------- ---------------- 编辑2 ----------------------------------------- -------------------

更改了散点图。但是,值与x轴不匹配。添加了示例图片,但是应该有节点名称,而不是x轴上的数字,与上面的示例图片相同 更新的行:

plt.scatter(range(len(us_csv_file)), [int(item[1]) for item in us_csv_file], c='r')

#plt.xticks(np.arange(len(csv_file)), [item for item in csv_file])
plt.xticks(np.arange(len(csv_file))[::1], csv_file[::1])
plt.savefig('./test.png')

我要使用主机名作为X轴的方法 Scatter Graph Sample

-------------------------------------------- ---------------- 编辑3 ----------------------------------------- -------------------

最后更改了代码以清除X轴,但是它仍然不起作用。另外,用我拥有的3个文件绘制图形,并为每个文件添加了不同的符号。

更新代码

from matplotlib import pyplot as plt
import numpy as np
from textwrap import wrap
import csv

csv_file = []
with open('hostnum.csv', 'r') as host:
    for line in host.readlines():
        line = line.replace('"', '')
        line = line.strip('\n')
        rank, value = line.split("  ")
        csv_file.append(value)

us_csv_file = []
with open('firsFile.csv', 'r') as f:
    csvreader = csv.reader(f)
    for line in csvreader:
        us_csv_file.append(line)

us_csv_file1 = []
with open('secondFile.csv', 'r') as f:
    csvreader = csv.reader(f)
    for line in csvreader:
        us_csv_file1.append(line)

us_csv_file2 = []
with open('thirdFile.csv', 'r') as f:
    csvreader = csv.reader(f)
    for line in csvreader:
        us_csv_file2.append(line)


us_csv_file.sort(key=lambda x: csv_file.index(x[0]))
us_csv_file1.sort(key=lambda x: csv_file.index(x[0]))
us_csv_file2.sort(key=lambda x: csv_file.index(x[0]))


plt.scatter(range(len(us_csv_file)), [int(item[1]) for item in us_csv_file], c='r', marker='+', label="First")
plt.scatter(range(len(us_csv_file1)), [int(item[1]) for item in us_csv_file1], c='b', marker=(5,2), label="Second")
plt.scatter(range(len(us_csv_file2)), [int(item[1]) for item in us_csv_file2], c='g', marker=(5,1), label="Third")

plt.legend(loc='upper right') #where to indicate the labels of the signs
plt.grid(True) #Created grid for x-y axises

plt.title("\n".join(wrap("long long long long long long tittle ttitle ttitle that that fixed fixed ")))
plt.xlabel("Node Names", fontsize = 8)
plt.ylabel("Run Times", fontsize = 8)

#plt.xticks(np.arange(0,len(csv_file),1000)[::2], csv_file[::2])
plt.xticks(np.arange(len(csv_file))[::2], csv_file[::2])
plt.yticks(np.arange(0,11000,1000))

plt.show()

带有X轴标签的图形不清楚(也显示为网格线) Graph with X-axis labels unclear with Gridlines

*最终成绩* Final Graph

2 个答案:

答案 0 :(得分:1)

注意:排序可能不是最有效的方法,而是从头开始的

使用csv.reader()加载CSV文件并将其迭代到列表中

将排序后的XML文件也加载到另一个列表中(注意:您可能可以再次使用csv.reader()并将定界符设置为tab以便保持简单)

加载CSV文件的语法如下:

import csv
csv_file = []
with open('file.csv', 'r') as f:
    csvreader = csv.reader(f)
    for line in csvreader:
        csv_file.append(line)

有关更多信息和使用定界符,请参见csv.reader() docs。为了安全起见,请记住在打开其他文件时更改文件和阅读器的变量名。

但是,对于您的hostnum.csvcsv不起作用,因此您可以手动编写解析器。我为你做了:

csv_file = []
with open('/Users/dash/Documents/hostnum.csv', 'r') as host:
    for line in host.readlines():
        line = line.replace('"', '')
        line = line.strip('\n')
        rank, value = line.split("    ")
        csv_file.append(value)

按XML列表中每个元素的位置对列表进行排序:

us_csv_file.sort(key=lambda x: csv_file.index(x[0]))

这可以通过使用lambda(匿名函数)在CSV文件中获取字符串并在已排序的XML文件中查找其行号来实现。 Lambda返回一个数字,然后使用该数字来设置元素在列表中的新位置。

有关分类的基本教程,请参见the python wiki

要进行绘图,请使用matplotlib.pyplot并使用matplotlib.pyplot.xticks()设置xticks

例如:

from matplotlib import pyplot as plt
import numpy as np

plt.plot([int(item[1]) for item in us_csv_file], 'o-')
plt.xticks(np.arange(len(csv_file)), [item for item in csv_file])

plt.show()

The end result

希望这会有所帮助!

编辑:在csv_file中使用lambda

EDIT2:这是完整的代码:

from matplotlib import pyplot as plt
import numpy as np
import csv

csv_file = []
with open('hostnum.csv', 'r') as host:
    for line in host.readlines():
        line = line.replace('"', '')
        line = line.strip('\n')
        rank, value = line.split("    ")
        csv_file.append(value)

us_csv_file = []
with open('us_csv_file.csv', 'r') as f:
    csvreader = csv.reader(f)
    for line in csvreader:
        us_csv_file.append(line)

us_csv_file.sort(key=lambda x: csv_file.index(x[0]))

plt.plot([int(item[1]) for item in us_csv_file], 'o-')
plt.xticks(np.arange(len(csv_file)), [item for item in csv_file])

plt.show()


编辑(再次) 考虑一下之后,我认为最好的方法是为每个节点创建一个存储有所有值的字典。

from matplotlib import pyplot as plt
import numpy as np
from textwrap import wrap
import csv

#Opens the sorted hostnum.csv file and reads it; replaces the quotation marks.
csv_file = []
with open('hostnum.csv', 'r') as host:
    for line in host.readlines():
        line = line.replace('"', '')
        line = line.strip('\n')
        rank, value = line.split("  ")
        csv_file.append(value)

#Opens the file and reads it
us_csv_file = []
with open('fileFirst.csv', 'r') as f:
    csvreader = csv.reader(f)
    for line in csvreader:
        us_csv_file.append(line)

us_csv_file1 = []
with open('fileSecond.csv', 'r') as f:
    csvreader = csv.reader(f)
    for line in csvreader:
        us_csv_file1.append(line)

us_csv_file2 = []
with open('fileThird.csv', 'r') as f:
    csvreader = csv.reader(f)
    for line in csvreader:
        us_csv_file2.append(line)


runs = []

file_0 = {}
file_1 = {}
file_2 = {}

for result in us_csv_file:
    node_name = result[0]
    node_value = result[1]

    if file_0.get(node_name):   # If the node exists in the list
        file_0[node_name].append(node_value)
    else:
        file_0[node_name] = [node_value]

runs.append(file_0)

for result in us_csv_file1:
    node_name = result[0]
    node_value = result[1]

    if file_1.get(node_name):   # If the node exists in the list
        file_1[node_name].append(node_value)
    else:
        file_1[node_name] = [node_value]

runs.append(file_1)

for result in us_csv_file2:
    node_name = result[0]
    node_value = result[1]

    if file_2.get(node_name):   # If the node exists in the list
        file_2[node_name].append(node_value)
    else:
        file_2[node_name] = [node_value]

runs.append(file_2)


# all_plots = [[[], []],[[], []],[[], []]]

all_plots = [] # Make an array of 3 arrays, each with a pair of arrays inside
# Each pair holds the x and y coordinates of the datapoints

for x in range(3):
    all_plots.append([[],[]])


for run_number, run_group in enumerate(runs):

    for key, values in run_group.items():
        sorted_position = csv_file.index(key)
        for item in values:
            all_plots[run_number][0].append(sorted_position)
            all_plots[run_number][1].append(int(item))

#indicates the label names at the given spot
plt.legend(loc='upper right')

#Creates grid for x-y axises
plt.grid(True)

#Creates wrapped title for the graph
plt.title("\n".join(wrap("longlonglonglonglonglonglonglonglonglonglonglonglonglongTITLETITLETITLETITLETITLETITLE")),size = 9.5)

#x-y labels for the graph
plt.xlabel("Node Names", fontsize = 8)
plt.ylabel("Run Times", fontsize = 8)

#ticks - x and y axisses' data format.

plt.scatter(all_plots[0][0], all_plots[0][1], c='b', marker='+', label="First")
plt.scatter(all_plots[1][0], all_plots[1][1], c='g', marker=(5,2), label="Second")
plt.scatter(all_plots[2][0], all_plots[2][1], c='r', marker=(5,1), label="Third")


plt.xticks(range(len(csv_file))[::25], [item for item in csv_file][::25], rotation=90, size=8)


plt.yticks(np.arange(0,11000,1000), size=8)

#Saves a PNG file of the current graph to the folder and updates it every time
plt.savefig('./test.png', bbox_inches='tight')

# Not to cut-off bottom labels(manually) - enlarges bottom
plt.gcf().subplots_adjust(bottom=0.23)


plt.show()

答案 1 :(得分:0)

该项目记录在GITHUB页面中: https://rusife.github.io/Python-Project/