Python использует многопроцессорность для построения и сохранения на одном рисунке - PullRequest
0 голосов
/ 30 ноября 2018

Могу ли я построить отдельную обработку на одной фигуре?Например, код удара может сохранить только последний график на рисунке.

import matplotlib
matplotlib.use('agg')
from multiprocessing import Pool
import matplotlib.pyplot as plt
def f111(a,b,fig):
    plt.plot(a,b,'ro')
    plt.savefig('test.jpg')

if __name__=='__main__':
    fig=plt.figure(figsize=(20,10))
    p=Pool(8)
    for i in range(8):
        p.apply_async(f111,args=(1+i*6,6+i*6,fig))
    p.close()
    p.join()

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

@ NaiveVincent.Кажется очевидным, что каждый процесс сохраняет свой собственный график, но вы используете одно и то же имя для всей фигуры.Поэтому последний график - это тот, который остается, так как предыдущий перезаписывается.Если вы хотите сохранить разные имена для каждого процесса, вы можете выполнить следующее:

import matplotlib
matplotlib.use('agg')
from multiprocessing import Pool
import matplotlib.pyplot as plt


def f111(a,b,fig, filename):
    plt.plot(a,b,'ro')
    plt.savefig(filename)

if __name__=='__main__':
    fig=plt.figure(figsize=(20,10))
    p=Pool(8)
    for i in range(8):
        filename = 'test' + str(i+1) + '.jpg'
        p.apply_async(f111,args=(1+i*6,6+i*6,fig, filename,))
    p.close()
    p.join()
0 голосов
/ 30 ноября 2018

Я полагаю, что 'fig', который вы передаете в apply_async, в этом случае становится копией, а не указателем на изначально созданный объект 'fig', здесь происходит то, что каждый процесс сохраняет (из своей собственной копии fig) тестирование.JPG с только его собственными построенными данными из

plt.plot(a, b, 'ro')

И тот, который вы видите, это процесс, который завершается последним.

Это важно, что вы делаете это в отдельных процессах?что-то настолько простое, что это было бы лучше построить в виде простого цикла.

Если, однако, вам нужно выполнить тяжелые вычисления в пуле, вы можете сохранить результаты в многопроцессорной обработке. Массив, который позволяет записывать данные из всех дочерних процессов, и который впоследствии может быть использован в родительском процессе.Таким образом, вы можете нанести на график одну фигуру в родительском процессе, которая проста, но все же имеет преимущество быстрых параллельных вычислений

import matplotlib
matplotlib.use('agg')
from multiprocessing import Pool, Array
import matplotlib.pyplot as plt


def f111(i, a, b, arr_a, arr_b):
    calc_value_a = a * 2
    calc_value_b = b * 2
    arr_a[i] = calc_value_a
    arr_b[i] = calc_value_b


if __name__=='__main__':
    fig=plt.figure(figsize=(20,10))
    arr_a = Array('i', range(8))
    arr_b = Array('i', range(8))
    p=Pool(8)
    for i in range(8):
        p.apply_async(f111, args=(i, 1+i*6, 6+i*6, arr_a, arr_b))
    p.close()
    p.join()
    plt.plot(arr_a, arr_b, 'ro') 
    plt.show()
...