我有一个内部分布式计算库,我们一直用于并行计算工作。在对进程进行分区后,它们将运行数据加载和计算步骤,然后执行“保存”步骤。通常这涉及将数据写入数据库表。
但对于特定任务,我需要将每个进程的输出作为带有一些数据图的.png文件。总共有95个进程,所以95个.pngs。
在我的“保存”步骤(在每个进程上执行)中,我有一些非常简单的代码,它使用matplotlib的boxplot
函数创建一个boxplot,并使用savefig
将一些代码写入a .png文件,具有基于该进程中使用的特定数据的唯一名称。
但是,我偶尔会看到输出显示两个或多个数据集被写入同一个输出文件,尽管它们具有唯一的名称。
matplotlib在制作箱图或保存数字时是否使用临时文件保存?如果是这样,它是否总是使用相同的临时文件名(从而导致重写冲突)?我使用strace
运行我的进程,看不到任何看起来像matplotlib写的临时文件。
我如何确保这是线程安全的?我当然希望并行执行文件保存,因为我希望大大扩展输出.pngs的数量,因此首先存储所有数据然后只是连续执行绘图/保存部分的选项是非常不可取的。
我不可能重现我们正在使用的完整并行基础结构,但下面是调用创建绘图句柄的函数,然后是调用以保存绘图的函数。您应该假设线程安全与我们的分布式库无关。我们知道它不是来自我们的代码,我们的多处理作业多年来一直使用它而没有像这样的线程问题(特别是对于我们不直接控制的东西,比如来自matplotlib的任何临时文件)。
import pandas
import numpy as np
import matplotlib.pyplot as plt
def plot_category_data(betas, category_name):
"""
Function to organize beta data by date into vectors and pass to box plot
code for producing a single chart of multi-period box plots.
"""
beta_vector_list = []
yms = np.sort(betas.yearmonth.unique())
for ym in yms:
beta_vector_list.append(betas[betas.yearmonth==ym].Beta.values.flatten().tolist())
###
plot_output = plt.boxplot(beta_vector_list)
axs = plt.gcf().gca()
axs.set_xticklabels(betas.FactorDate.unique(), rotation=40, horizontalalignment='right')
axs.set_xlabel("Date")
axs.set_ylabel("Beta")
axs.set_title("%s Beta to BMI Global"%(category_name))
axs.set_ylim((-1.0, 3.0))
return plot_output
### End plot_category_data
def save(self):
"""
Make calls to store the plot to the desired output file.
"""
out_file = self.output_path + "%s.png"%(self.category_name)
fig = plt.gcf()
fig.set_figheight(6.5)
fig.set_figwidth(10)
fig.savefig(out_file, bbox_inches='tight', dpi=150)
print "Finished and stored output file %s"%(out_file)
return None
### End save
答案 0 :(得分:0)
在你的两个函数中,你正在调用plt.gcf()
。我会尝试在每次使用plt.figure()
进行绘图时生成一个新的数字,并明确地引用该数字,以便完全绕过整个问题。