Matplotlib绘图速度过慢

4
我尝试绘制2000万个数据点,但是使用matplotlib会花费极长时间(超过一小时)。
我的代码中有什么使得这个过程异常缓慢的因素吗?
import csv
import matplotlib.pyplot as plt
import numpy as np
import Tkinter
from Tkinter import *
import tkSimpleDialog
from tkFileDialog import askopenfilename

plt.clf()

root = Tk()
root.withdraw() 
listofparts = askopenfilename()                  # asks user to select file
root.destroy()

my_list1 = []
my_list2 = []
k = 0

csv_file = open(listofparts, 'rb')

for line in open(listofparts, 'rb'):
    current_part1 = line.split(',')[0]
    current_part2 = line.split(',')[1]
    k = k + 1
    if k >= 2:                                   # skips the first line
        my_list1.append(current_part1)
        my_list2.append(current_part2)

csv_file.close()

plt.plot(my_list1 * 10, 'r')
plt.plot(my_list2 * 10, 'g')

plt.show()
plt.close()

我已经删除了你的问题中与库推荐相关的部分,因为这些问题在[so]上是不适合讨论的。 - Sayse
你是否对代码进行了性能分析以找出瓶颈?在我的电脑上,绘制100万个随机数据只需要几秒钟,而200万及以上的点则会导致错误“在draw_path中:超过单元格块限制”。此外,我建议使用PyQtgraph库。 - Roman Fursenko
谢谢。当我运行超过100万个数据点时,我遇到了一个“溢出错误:分配了太多的块”的错误,但是通过添加matplotlib.pyplot.rcParams['agg.path.chunksize'] = 20000来修复了这个问题。然而,即使运行10万个数据点也需要至少20分钟。我的笔记本只有4GB内存,问题可能完全是因为我的笔记本吗? - darrenvba
不需要代码,我可能应该在stackoverflow上去掉*10。Excel每行有100万个单元格的限制,我用Excel创建了一个包含100万个数据点的CSV文件,但我想测试更多。它应该只是将图形线重复10次,在尝试较小的数据集时可以工作。 - darrenvba
3个回答

8
在matplotlib中,没有任何理由绘制20000000个数据点的折线图。
首先让我们考虑打印: 在matplotlib中,最大的图像尺寸是50英寸。即使使用3600dpi的高科技绘图仪,也只能得到最多180000个可分辨的点。
对于屏幕应用程序来说,更少:即使是高科技的4k屏幕,其分辨率也有限制,只有4000个像素。即使使用抗锯齿效果,人眼仍然只能分辨出每个像素的最多3个点。结果是:最多只能显示12000个点。
因此,你提出的问题实际上应该是:如何将我的20000000个数据点进行子采样,以便在纸张或屏幕上产生相同的图像。
这个解决方案很大程度上取决于数据的性质。如果数据足够平滑,你可以只取每个n个列表条目。
sample = data[::n]

如果有需要解决的高频成分,则需要更复杂的技术,这又取决于数据的外观。

其中一种技术可能是在如何根据密度对数组进行子采样?(删除频繁值,保留稀有值)中展示的技术。


在matplotlib中绘制20000000个点的线图毫无道理。这是一个相当大的假设。我有大约400万个时间序列传感器输出数据点,并且我正在制作一个工具来帮助识别数据的有趣部分。我需要放大并以最高分辨率查看这些区域的数据点。我不明白为什么matplotlib没有内置的子采样功能。我不介意整体绘图被子采样,但是当我缩放时,我需要最高分辨率。 - Joseph Meadows

2
以下方法可能会稍微提高性能。它通过使用Python的CSV库仅对每行执行一次拆分,并在循环之前跳过两个标题行来避免if语句:
import matplotlib.pyplot as plt
import csv

l1, l2 = [], []

with open('input.csv', 'rb') as f_input:
    csv_input = csv.reader(f_input)

    # Skip two header lines
    next(csv_input)
    next(csv_input)

    for cols in csv_input:
        l1.append(cols[0])
        l2.append(cols[1])

plt.plot(l1, 'r')
plt.plot(l2, 'g')
plt.show()

我认为主要的减速因素仍然是情节本身。

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接