【问题标题】:Avoiding for-loop in plotting multiple graphs on a figure在图形上绘制多个图形时避免 for 循环
【发布时间】:2019-08-29 21:45:43
【问题描述】:

我正在绘制大约 10000 次迭代的误差函数值,绘制它们需要很长时间。 如果可能的话,我想避免 for-loop 将它们全部绘制在一个图中,但无论如何要加快速度。

import time
import matplotlib.pyplot as plt
a = time.time()

for one in range(len(data)):
    plt.plot(data[one],"-o")
plt.show() 

b = time.time()
print(b-a)

尝试的时间是:

(plt.plot(data[one],"-o") for one in range(len(data)))
plt.show()

但是它没有显示任何情节。所以我的目标是加快绘图速度,如果它是瓶颈,则删除 for-loop。

数据是

data = array([[  0. ,   0. ,   0. ,   0. ,   0. ],
       [-43.4, -18. , -10.5,  -7.4,  -5.7],
       [ 25.7,  18.3,  13.8,  10.7,   8.6],
       [-25. , -10. ,  -5.8,  -4.2,  -3.3],
       [ 16.1,  11.5,   8.6,   6.5,   5.1],
       [-16.2,  -6.4,  -3.8,  -2.9,  -2.4],
       [  9.6,   7.1,   5.2,   3.8,   2.9],
       [ -9.1,  -3.4,  -2. ,  -1.6,  -1.5],
       [  4.7,   3.9,   2.9,   2. ,   1.4],
       [ -4.5,  -1.3,  -0.7,  -0.8,  -0.8]])

如果有关系,x轴可以作为

n = [i for i  in range(5)]

【问题讨论】:

  • 为了避免循环,你可以做plt.plot(range(5), data.T)
  • 你的数组的转置
  • 每个循环为 478 毫秒 ± 35.2 毫秒(平均值 ± 标准偏差,7 次运行,每个循环 1 个循环)for 循环,每个循环 11.7 毫秒 ± 2.24 毫秒(平均值 ± 偏差标准偏差. 7 次运行,每次 100 次循环)对于您的建议
  • 对于不同的时间安排,请参阅Many plots in less time - python,但我不知道那里提到的任何其他选项是否适用于您的情况。
  • 我尝试使用 LineCollection,但在堆叠数据和 n 后得到ValueError: all input arrays must have the same shape。但是当我使用 time.time 时,您的第一条评论速度提高了 10 倍,它们是 ~400ms 到 ~40ms。正如您可能理解的那样,较早的时间来自 jupyter。我假设我们已经用尽了matrix和LineCollection,可以使用nans吗?

标签: python performance for-loop matplotlib plot


【解决方案1】:

这有点“作弊”,但您可以使用并行处理器包装 Python 函数。例如,如果您有一个 8 核处理器,您可以使用 7 个内核并行运行您的函数,或者使其速度提高 7 倍。

import matplotlib.pyplot as plt
from multiprocessing import Pool, cpu_count

def multi_processor(function_name):

    # Use max number of system processors - 1
    pool = Pool(processes=cpu_count()-1)
    pool.daemon = True

    results = {}
    # for every item in your list of items, start a new process
    for one in range(len(data)):
        results[one] = pool.apply_async(your_function, args=(data[one]))

    # Wait for all processes to finish before proceeding
    pool.close()
    pool.join()

    # Results and any errors are returned
    return {your_function: result.get() for your_function, result in results.items()}

def your_function(arg1):
    try:
        return plt.plot(arg1,"-o")
    except Exception as e:
        return str(e)

if __name__ == "__main__":
    multi_processor("your_function")
    plt.show()

【讨论】:

  • 这无疑很有用,我稍后会使用(学习后)它,但截至目前,我正在做的作业将在有限的库中进行测试。我认为这现在不会有用。
  • 你真的测试过这个吗?它会产生一个情节还是 5 个?
  • 不,我没有针对这个问题测试过它,但我已经在其他功能上测试过很多次。我只是使用打印语句来演示并行处理功能,而不是绘制一些东西。通用版在这里stackoverflow.com/questions/48953878/…
  • 好的,我建议用实际的绘图来测试它,因为根据我的经验,多处理会产生新的进程,这些进程在分离后无法合并到单个输出绘图中。
  • 我会试试如果我知道在哪里放置data 变量。我正在使用一个新文件。并得到TypeError: your_function() takes 1 positional argument but 5 were given
猜你喜欢
  • 1970-01-01
  • 2019-06-30
  • 1970-01-01
  • 2014-06-16
  • 2016-09-29
  • 2016-02-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多