Blank plots with multiprocessing.pool

Question:

I have a list to which I map a function using multiprocessing.pool.starmap. The code looks like this:

def plot_data(actual, predicted, ax):
    if ax is None:
        ax = plt.gca()
    area, kde1_x, kde2_x, idx, x = distribution_intersection_area(actual, predicted)
    ax.plot(x, kde1_x, color='dodgerblue',label='original', linewidth=2)
    ax.plot(x, kde2_x, color='orangered', label='forecasted', linewidth=2)
    ax.fill_between(x, np.minimum(kde1_x, kde2_x), 0,color='lime', alpha=0.3,,label='intersection') 
    ax.plot(x[idx], kde2_x[idx], 'ko')
    handles, labels = ax.get_legend_handles_labels()
    labels[2] += f': {area * 100:.1f}%'
    ax.legend(handles, labels)


def do_something(col, k, rows, fig):

    ax = fig.add_subplot(rows, display_cols, position[k])
    plot_data(actual,predicted)
    annot = 'my plot'
    ax.set_title(annot)

rows = 10
fig = plt.figure(figsize=(30, 4 * rows))
fig.subplots_adjust(hspace=0.3, wspace=0.2)
actuals = [1,2,3,4,5,6] # Its actually a long list of floats
predicted = [10,20,30,40,50,60] # list of predicted values
    
loop_list= ['col1','col2','col3']
with Pool(processes=None) as pool:
    my_args = [(col, k, rows, fig) for k, col in enumerate(loop_list)]
    results = pool.starmap(do_something, my_args)

then I try to save the plot as:

try:
    plt.suptitle('my calculation status', y=0.94, fontsize=18)
    plt.savefig('./outputs/test.jpg',dpi = 150)
    plt.show
except Exception as e:
    print(e)
plt.show()

I have also tried using:

try:
    plt.show()
    fig.savefig('./outputs/line_plot.png', dpi=100)
except Exception as e:
    print(e)

but the plot I get is all blank. Its a white picture with only the text ‘my calculation status’

Can someone help?

Asked By: Obiii

||

Answers:

I ended up using custom Rasterize function:

def rasterize(fig : matplotlib.figure):

    buf = io.BytesIO()
    fig.savefig(buf, format='png', bbox_inches='tight')
    buf.seek(0)
    rasterized_plot = deepcopy(Image.open(buf))
    buf.close()
    
    return rasterized_plot

and use it to save the rasterized plots in array and öater loop over it to draw:

pil_img = rasterize(fig)
plt.close()
return pil_img 

for ax, rastered in zip(axes.ravel(), drift_plots):
    ax.imshow(rastered)
    plt.subplots_adjust(hspace=0.3, wspace=0.2)
    plt.suptitle(drift_stat, y=0.94, fontsize=18) 
Answered By: Obiii