Я надеюсь найти способ оптимизировать следующую ситуацию. У меня есть большой контурный график, созданный с помощью imshow из matplotlib. Затем я хочу использовать этот контурный график для создания большого количества изображений png, где каждое изображение представляет собой небольшую часть контурного изображения, изменяя пределы x и y и соотношение сторон.
Таким образом, данные графика не меняются в цикле, меняются только пределы осей и соотношение сторон между каждым изображением png.
Следующий MWE создает 70 изображений PNG в папке «figs», демонстрируя упрощенную идею. Около 80% времени выполнения занимает fig.savefig('figs/'+filename)
.
Я изучил следующее, не придумав улучшения:
- Альтернатива
matplotlib
с упором на скорость - я изо всех сил пытался найти какие-либо примеры/документацию контурных/поверхностных графиков с аналогичными требованиями. - Многопроцессорность. Подобные вопросы, которые я видел здесь, по-видимому, требуют вызова
fig = plt.figure()
иax.imshow
внутри цикла, поскольку fig и axe не могут быть замаринованы. В моем случае это будет дороже, чем любой прирост скорости, достигнутый за счет реализации многопроцессорности.
Я был бы признателен за любые идеи или предложения, которые у вас могут быть.
import numpy as np
import matplotlib as mpl
mpl.use('agg')
import matplotlib.pyplot as plt
import time, os
def make_plot(x, y, fix, ax):
aspect = np.random.random(1)+y/2.0-x
xrand = np.random.random(2)*x
xlim = [min(xrand), max(xrand)]
yrand = np.random.random(2)*y
ylim = [min(yrand), max(yrand)]
filename = '{:d}_{:d}.png'.format(x,y)
ax.set_aspect(abs(aspect[0]))
ax.set_xlim(xlim)
ax.set_ylim(ylim)
fig.savefig('figs/'+filename)
if not os.path.isdir('figs'):
os.makedirs('figs')
data = np.random.rand(25, 25)
fig = plt.figure()
ax = fig.add_axes([0., 0., 1., 1.])
# in the real case, imshow is an expensive calculation which can't be put inside the loop
ax.imshow(data, interpolation='nearest')
tstart = time.clock()
for i in range(1, 8):
for j in range(3, 13):
make_plot(i, j, fig, ax)
print('took {:.2f} seconds'.format(time.clock()-tstart))