Jack
Jack

Reputation: 11

Why matplotlib get slow when use plot() to draw lines?

I want to know why it will be very slow when I use matplotlib to draw lines? How to fix it?

Belows are the demo code. It used plot() to draw a line between two randomly generated points.

On my computer, 'END=100/200/500' results 'FPS=36.9/28.6/20'. I need to endless draw lines and it will get worse while time being. How to solve it? Thanks!

import numpy as np
import matplotlib.pyplot as plt
import time

def draw_demo():
    x = 100
    plt.axis([0, x, 0, 1])
    plt.ion()

    last = 50
    TIME = 5
    END = 1000
    time_start = time.time()

    for i in range(0, END):
        random_num = np.random.random()

        if i > 70:
            plt.axis([x - 100, x + 1, 0, 1])
            x += 1

        plt.plot([i, i + 1], [last, random_num])
        last = random_num

        plt.pause(0.0001)

    print ('FPS:', END/(time.time()-time_start))
    raw_input()

if __name__ == '__main__':
    draw_demo()

Upvotes: 1

Views: 612

Answers (2)

Simon Gibbons
Simon Gibbons

Reputation: 7184

matplotlib is getting slower as the script progresses because it is redrawing all of the lines that you have previously plotted - even the ones that have scrolled off the screen.

Upvotes: 0

tacaswell
tacaswell

Reputation: 87376

Try something like:

import numpy as np
import matplotlib.pyplot as plt
import time

def draw_demo2(ax):
    x = 100
    ax.set_xlim([x-100, x + 250])
    ax.set_ylim([0, 1])

    END = 250
    time_start = time.time()

    ln, = ax.plot([], [])
    x_data = []
    y_data = []
    for i in range(0, END):
        random_num = np.random.random()

        if i%100 == 99:
            cur_xlim = ax.get_xlim()
            ax.set_xlim(np.array(cur_xlim) + 100)
        x += 1
        x_data.append(x)
        y_data.append(random_num)
        ln.set_data(x_data, y_data)
        ax.figure.canvas.draw_idle()
        ax.figure.canvas.flush_events()

    print ('FPS:', END/(time.time()-time_start))


if __name__ == '__main__':
    draw_demo()

It might be worth truncating the x and y data buffers to the view range (as the lists are converted to arrays every time the screen is drawn.

If you need to go really fast look into blitting, however that does not interact well with changing the limits, redrawing the text is one of the slowest parts of drawing the figure.

Also try qt instead of tk, I saw a 4x speed up from that change.

Upvotes: 2

Related Questions