试图将一些实验数据保存到文件中我发现当尝试保存NxN大小的热图时,执行将永远不会完成。进一步调查似乎是由于.pdf扩展名。例如,如果我使用.png,它的速度非常快。
最小可重复的例子:
import matplotlib.pylab as plt
import numpy as np
import seaborn as sbn
N=200
THE_FIGURE = plt.figure(figsize=(8.27, 6), dpi=300)
ax = plt.subplot(1, 1, 1)
sbn.heatmap(np.random.uniform(1, 20, (N, N)), ax=ax)
THE_FIGURE.savefig('image.pdf', bbox_inches='tight', pad_inches=0.1)
即使N = 100,这种减速也变得明显.N = 1000甚至没有发生。这是正常的吗?以及如何解决它
谢谢!
有意义的是,对于更大的网格,节省pdf比保存png需要更长的时间。这可以在下图中看到,其中显示了将pdf和png保存为沿一个轴(N
)的瓦片数量的函数的时间(实线)。我们还可以查看pdf和png的文件大小,其中有一些类似的行为(虚线)。
在这里找到复制代码。在我的电脑上运行它需要大约1:10分钟。
import matplotlib.pylab as plt
import numpy as np
import seaborn as sns
import time
import os
def f(N, form = "pdf"):
t0= time.time()
fig = plt.figure(figsize=(8.27, 6), dpi=300)
ax = plt.subplot(1, 1, 1)
sns.heatmap(np.random.uniform(1, 20, (N, N)), ax=ax)
fig.savefig('image.'+form, bbox_inches='tight', pad_inches=0.1)
t1 = time.time()
plt.close(fig)
s = os.path.getsize('image.'+form)
return t1-t0,s
ns = [5,10,15,20,25,30] + range(40,210, 20)
pdf = []
png = []
for i,n in enumerate(ns):
pdf.append(f(n, form="pdf"))
png.append(f(n, form="png"))
#print i, n
pdf = np.array(pdf);png = np.array(png)
plt.figure()
plt.plot(ns, pdf[:,0], label="pdf")
plt.plot(ns, png[:,0], label="png")
plt.xlabel("N")
plt.ylabel("time [s]")
ax2 = plt.gca().twinx()
ax2.plot(ns, pdf[:,1]/1000., label="pdf (filesize)", ls="--")
ax2.plot(ns, png[:,1]/1000., label="png (filesize)", ls="--")
ax2.set_ylabel("filesize [kByte]")
plt.gcf().legend(ncol=2, loc="upper left", bbox_to_anchor=(0.125,0.98))
plt.subplots_adjust(top=0.85)
plt.show()
原因似乎也很直观。 Png是位图格式,它将图像保存为像素。 Pdf是一种矢量格式,它将图像保存为矢量形状。
虽然png需要存储相同数量的像素(在这种情况下约为2000x1500),但是为小N
(这里高达N=30
或NxN = 900
)保存png需要更长的时间。但是图中的瓷砖越多,需要在pdf中存储的形状越多,因此最终需要更长的时间来保存pdf格式的许多瓷砖。我们假设保存pdf文件所花费的时间大致与要存储的磁贴数量成比例。这表明时间与N
,time ~ N**2
有二次关系。将二次多项式拟合到数据并在t=1000
处评估多项式给出
fit = np.polyfit(ns, pdf[:,0], 2)
print( np.poly1d(fit)(1000) )
给出340秒,即5:40分钟。这是保存1000x1000矩阵所需的估计时间。
注意:此处的所有数据均在运行python 2.7和matplotlib 2.1的Intel i5 3.5GHz Windows计算机上生成。使用不同的计算机当然会改变时间。