【问题标题】:Parallelism with Matplotlib.pyplot与 Matplotlib.pyplot 的并行性
【发布时间】:2021-09-09 06:35:50
【问题描述】:

我有一个特征文件,我想显示每个特征之间的对比,但由于它们很多,我将每个特征的图分开,所以每个图的一个特征与所有其他特征。由于它很慢,我将它并行化,并且我有这个代码。

def DrawPlots(Features, FeatureNames, ...):
    feature1 = FeatureNames[Column]
    fig, axs = plt.subplots(...)
    for j in range(length):
        if Column != j:
            feature2 = FeatureNames[j]
            ...
            plot = seaborn.scatterplot(data=X, x=feature1, y=feature2, ax=axs[...])

    fig.savefig("Test " + str(Column) + ".png", dpi=150)


if __name__ == '__main__':
    Features = pandas.read_csv("...csv")
    ColumnNames = list(Features.columns)
    ...
    Threads = []
    startime = time.time()
    for i in range(5):
        #DrawPlots(Features, ColumnNames, i, ...) # When not parallelized
        thread = threading.Thread(target=DrawPlots, args=(Features, ColumnNames, i, ...))
        Threads.append(thread)
        thread.start()
        print(str(i) + ' running.')

    for t in Threads:
        t.join()

    print("--- %s seconds ---" % (time.time() - startime))

当我从 PyCharm 运行此代码时,它会按预期工作:

0 running.
1 running.
2 running.
3 running.
4 running.
--- 118.35315799713135 seconds ---
All done.

Process finished with exit code 0

但是当我从命令行启动它时,我立即收到以下错误(胎面的短版):

0 running.
1 running.
Test.py:25: UserWarning: Starting a Matplotlib GUI outside of the main thread will likely fail.
figs, axs = plt.subplots(...)
2021-06-25 17:05:23.080 Python[96144:2936258] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'NSWindow drag regions should only be invalidated on the Main Thread!'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007fff38ded627 __exceptionPreprocess + 250
    1   libobjc.A.dylib                     0x00007fff71ccd5bf objc_exception_throw + 48
...
60  libsystem_pthread.dylib             0x00007fff7307a109 _pthread_start + 148
61  libsystem_pthread.dylib             0x00007fff73075b8b thread_start + 15
)
libc++abi.dylib: terminating with uncaught exception of type NSException
[1]    96144 abort      python Test.py

为什么它是从命令行而不是从 PyCharm 发生的?

我该如何解决?

有没有更好的方法来并行化代码以在两种环境中工作?

【问题讨论】:

    标签: python matplotlib parallel-processing pycharm seaborn


    【解决方案1】:

    在这种情况下,您不应该使用线程。它们不会显着改善执行时间,因为计算时间可能受 CPython GIL 的限制。实际上,线程对于 CPython 中的 IO 或阻塞操作很有用,因此它们通常更快,但绘图可能受到 Matplotlib 中通常在 CPU 上执行的类似图形的操作的限制。您应该改用多处理。它也应该可以解决您的问题,因为 Matplotlib 并不打算用于多线程函数。

    请注意,由于创建多个进程和进程之间的数据通信 (IPC),多处理会引入开销。因此,人们应该尝试创建一次进程(即不在循环中)并处理非常小的数据和/或执行关于数据大小的相对密集的操作。使用 Matplotlib 绘图通常非常密集,因此在您的情况下应该没问题。请注意,如果在某些情况下需要,您可以使用 shared-memory 减少数据通信开销。

    【讨论】:

    • 谢谢。我用thread = Process 替换了thread = threading.Thread,但thread.start() 似乎被冻结了。第一个进程被冻结,其他进程没有启动。
    • 如果你在 Windows 上运行,你应该仔细阅读 multiprocessing 包的文档,因为需要额外的操作。话虽如此,为了性能和可读性,请考虑使用multiprocessing Pools。
    • 我在 MacOS 上,一旦它可以工作,代码将部署在 Linux 上。
    猜你喜欢
    • 2014-06-20
    • 2023-03-21
    • 2011-06-03
    • 2021-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多