0

我正在創建一個帶有大約一百個子圖/軸的圖,每個子圖都有幾千個數據點。目前,我正在遍歷每個子區域,並使用plt.scatter來放置點。但是,這很慢。是否可以使用多個CPU來加速繪圖,通過將每個子圖劃分爲一個核心還是繪製單個子圖中的數據點?在matplotlib中,我可以使用多個CPU來加速繪製許多子圖和數據點嗎?

到目前爲止,我曾嘗試使用joblib爲子圖創建使用並行處理,但不是在同一圖中創建新的子圖,而是爲每個子圖生成一個新圖。我已經嘗試過後端PDF,Qt5AggAgg。這是我的代碼的一個簡單例子。

import matplotlib as mpl 
mpl.use('PDF') 
import seaborn as sns 
import matplotlib.pyplot as plt 
from joblib import Parallel, delayed 

def plotter(name, df, ax): 
    ax.scatter(df['petal_length'], df['sepal_length']) 

iris = sns.load_dataset('iris') 
fig, axes = plt.subplots(3,1) 

Parallel(n_jobs=2)(delayed(plotter) 
    (species_name, species_df, ax) 
    for (species_name, species_df), ax in zip(iris.groupby('species'), axes.ravel())) 

fig.savefig('test.pdf') 

設置n_jobs=1工程,所有點然後繪製在同一個圖內。然而,將它增加到1以上會產生四個數字:我以plt.subplots開始,然後每次調用一個ax.scatter

由於我將軸從第一個圖傳遞到plotter,我不知道如何/爲什麼會創建附加數字。在matplotlib中是否有一個回退,如果指定的數字被另一個繪圖過程「鎖定」,會自動創建新數字?

任何有關如何改善我目前的做法或通過替代方法實現加速的建議,我們感激不盡。

回答

2

Joblib的parallel使用multiprocessing模塊進行產卵過程,因此每個作業都將在不同的過程中運行。這就是爲什麼你會得到每個工作的新數字。這些進程不會像線程那樣共享任何內存,所以他們無法訪問原始數字。

您可以嘗試使用線程,但是由於全局解釋器鎖定(GIL),您是否能夠獲得任何速度增益是值得懷疑的。

爲了加快繪圖速度,您可以嘗試避免使用pyplot。它增加了一些開銷和幫助程序線程,在每個繪圖命令之後重繪繪圖。這主要是爲了讓例如ipython感覺更像是Matlab--但速度很糟糕。如果您僅使用matplotlib,則只有在完成繪圖後纔可以選擇繪製繪圖,並且可能會節省相當長的時間。

注意:@Faultier在評論中提到,您可以啓用和禁用與pyplot.ion()pyplot.ioff()的交互式繪圖。

+1

創建單獨的數字,暫時保存並最終將它們加載到組合數字中可能最爲可行?對於速度增益'plt.ioff()'也有幫助,因爲避免了自動重繪。 – Faultier

+0

@Faultier @ J.P.Petersen謝謝!我已經在使用'plt.ioff'(不包括在問題的例子中,對不起),我從不顯示這個圖,只是創建它並保存爲pdf。直接使用'matplotlib'還是避免使用'pyplot',我仍然可以獲得顯着的速度收益嗎? –

+0

@Faultier你是指創建單獨的數字並將它們合併的意思是什麼?從[我讀過](http://stackoverflow.com/questions/6309472/matplotlib-can-i-create-axessubplot-objects-then-add-them-to-a-figure-instance?noredirect=1&lq= 1),它很麻煩(如果可能的話),並且不正式支持分別創建matplotlib座標軸並將它們組合在一個圖中。你是指保存單獨的PDF文件,然後將它們拼接在一起?我正在考慮這一點,但不知道哪一個是最好的跨平臺(不幸的是我需要)python庫來實現pdf拼接。 –

相關問題