Why is matplotlib's save method slow?

0

I had 3d time series data as numpy. I used matplotlib for visualization of them. I was able to show animation without problem, but when I called save method, the calculation (saving) time is too slow... Why is it too slow?

Also, I tried to use opencv. In other words, I extracted image of figure.canvas in matplotlib. Then, I converted it to opencv image array. Here is my code(not all):

fourcc = cv2.VideoWriter_fourcc(*'MPEG')
video = cv2.VideoWriter(savepath, fourcc, fps, size)
for frame in range(len(x)):
    percent = int((frame + 1.0) * 100 / len(x))
    sys.stdout.write(
        '\r|{0}| {1}% finished'.format('#' * int(percent * 0.2) + '-' * (20 - int(percent * 0.2)), percent))
    sys.stdout.flush()
    self.__update3d(frame, x, y, z, xrange, yrange, zrange,
                    joint_name, line_index_lower, line_index_upper, show_joint_name)

    # convert canvas to image
    self.__ax.figure.canvas.draw()
    img = np.fromstring(self.__ax.figure.canvas.tostring_rgb(), dtype=np.uint8,
                        sep='')
    img = img.reshape(self.__ax.figure.canvas.get_width_height()[::-1] + (3,))

    # img is rgb, convert to opencv's default bgr
    img = cv2.resize(cv2.cvtColor(img, cv2.COLOR_RGB2BGR), size)

    video.write(img)
    """
    # display image with opencv or any operation you like
    cv2.imshow("plot", img)
    k = cv2.waitKey(int(100*1.0/fps))
    if k == ord('q'):
        show = False
        break
    """
video.release()
print("\nsaved to {0}".format(savepath))

The merit of this code is I can see progress. The result of this code is:

OpenCV: FFMPEG: tag 0x4745504d/'MPEG' is not supported with codec id 2 
and format 'mp4 / MP4 (MPEG-4 Part 14)'
OpenCV: FFMPEG: fallback to use tag 0x00000061/'a???'
|####################| 100% finished
saved to ~/Desktop/sample.mp4
calculation time: 58.3186759949 s

Also, I can call ordinary matplotlib save method. Here is code:

ani = anm.FuncAnimation(self.__fig, self.__update3d, fargs=(x, y, z, xrange, yrange, zrange,
                                                     joint_name, line_index_lower, line_index_upper, show_joint_name),
                            interval=1.0/fps, frames=len(x))  # interval ms

if savepath is not None:
    print("saving now...")
    ani.save(savepath)
    print("saved to {0}".format(savepath))
    if saveonly:
        return

Output is:

saving now...
saved to ~/Desktop/sample.mp4
calculation time: 68.9247670174 s

Ordinary method is slower than method using opencv... For your information, frame number is 512 and plots number per frames is 35. Why is these methods slow? Is there faster way?

python
opencv
matplotlib
asked on Stack Overflow May 21, 2018 by jkjk

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0