2016-02-13 25 views
1

自從版本1.5以來,我有Matplotlib中的多處理麻煩。字體隨機跳躍到原來的位置。例子如下: enter image description hereMatplotlib多處理字體損壞使用savefig

簡單的例子來重現此錯誤是在這裏:

import multiprocessing 
import matplotlib.pyplot as plt 

fig = plt.figure() 

def plot(i): 
    fig = plt.gcf() 
    plt.plot([],[]) 
    fig.savefig('%d.png' % i) 

plot(0) 
pool = multiprocessing.Pool(4) 
pool.map(plot, range(10)) 

如果多和簡單的繪圖的順序顛倒

pool = multiprocessing.Pool(4) 
plot(0) 
pool.map(plot, range(10)) 

那麼它的工作原理,但這種解決方法對我的目的沒用。

謝謝。

+2

您假設並行訪問繪圖邏輯是安全的。如果它真的存在,我會感到很驚訝。 – cel

+0

可能它不是,但它與舊的matplotlib一起工作,它有時也與新的工作。我只需要一種方法來創建和保存多處理圖。 – Tomas

+0

繪圖與現實生活中的繪畫非常相似。擁有多名藝術家往往不會改善結果。 :) – cel

回答

2

我最近遇到同樣的問題,同時測試平行繪製大量圖的方法。雖然我還沒有找到使用多處理模塊的解決方案,但我發現使用並行Python包(http://www.parallelpython.com/)看不到相同的錯誤。在我的早期測試中,它似乎比多處理模塊慢50%,但仍然比串行繪圖顯着加速。對於模塊導入也是一個挑剔的問題,所以我最終希望找到一個使用多處理的解決方案,但現在這是一個可以通過的解決方法(至少對我來說)。這就是說,我對並行處理相當陌生,所以我在這裏可能會忽略兩種方法的細微差別。

############################################################################### 
import os 
import sys 
import time 
#import numpy as np 
import numpy # Importing with 'as' doesn't work with Parallel Python 
#import matplotlib.pyplot as plt 
import matplotlib.pyplot # Importing with 'as' doesn't work with Parallel Python 
import pp 
import multiprocessing as mp 
############################################################################### 
path1='./Test_PP' 
path2='./Test_MP' 
nplots=100 
############################################################################### 
def plotrandom(plotid,N,path): 
    numpy.random.seed() # Required for multiprocessing module but not Parallel Python... 
    x=numpy.random.randn(N) 
    y=x**2 
    matplotlib.pyplot.scatter(x,y) 
    matplotlib.pyplot.savefig(os.path.join(path,'test_%d.png'%(plotid)),dpi=150) 
    matplotlib.pyplot.close('all') 
############################################################################## # 
# Parallel Python implementation 
tstart_1=time.time() 
if not os.path.exists(path1): 
    os.makedirs(path1) 

ppservers =() 

if len(sys.argv) > 1: 
    ncpus = int(sys.argv[1]) 
    job_server = pp.Server(ncpus, ppservers=ppservers) 
else: 
    job_server = pp.Server(ppservers=ppservers) 

print "Starting Parallel Python v2 with", job_server.get_ncpus(), "workers" 

jobs = [(input_i, job_server.submit(plotrandom,(input_i,10,path1),(),("numpy","matplotlib.pyplot"))) for input_i in range(nplots)] 

for input_i, job in jobs: 
    job() 

tend_1=time.time() 
t1=tend_1-tstart_1 
print 'Parallel Python = %0.5f sec'%(t1) 
job_server.print_stats() 
############################################################################## # 
# Multiprocessing implementation 
tstart_2=time.time() 
if not os.path.exists(path2): 
    os.makedirs(path2) 

if len(sys.argv) > 1: 
    ncpus = int(sys.argv[1]) 
else: 
    ncpus = mp.cpu_count() 

print "Starting multiprocessing v2 with %d workers"%(ncpus) 

pool = mp.Pool(processes=ncpus) 
jobs = [pool.apply_async(plotrandom, args=(i,10,path2)) for i in range(nplots)] 
results = [r.get() for r in jobs] # This line actually runs the jobs 
pool.close() 
pool.join() 

tend_2=time.time() 
t2=tend_2-tstart_2 
print 'Multiprocessing = %0.5f sec'%(t2) 
############################################################################### 
0

我找到了解決辦法。煩惱的主要原因是在字典_fontd字體高速緩存中/matplotlib/backends/backend_agg.py

因此,我已通過添加multiprocessing.current_process用於每個處理的不同的散列()。PID到散列稱爲在函數_get_agg_font中鍵

如果有人知道更優雅的解決方案,不需要修改matplotlib文件,請讓我知道。