Home > Software design >  How to avoid multiple plots using matplotlib pause function
How to avoid multiple plots using matplotlib pause function

Time:12-30

I am trying to create a crude animation, where each additional data point is plotted on the same graph. The problem is that the loop is generating a new graph for each data point.

Here's the code:

x = []
y = []

for i in range(3):
    x.append(random.randint(0,10))
    y.append(random.randint(0,10))
    
    plt.scatter(x,y)
    plt.pause(0.1)

This resulted in 3 separate plots stacked vertically. I would like all data points to update on the same graph, creating an animation. Thanks!

CodePudding user response:

James, I think plt.scatter can't make an animation. All the code will be executed and then a chart with 3 points will be the result.

To avoid the generation of multiple figures you can use plt.subplots.

fig, ax = plt.subplots()

for i in range(3):
    ax.scatter(x=random.randint(0,10),y= random.randint(0,10))

If you want to create some animated figure use matplotlib.animation.FuncAnimation , as in the answer of the following topic. How can i make points of a python plot appear over time?

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from IPython.display import HTML


x = np.arange(10)
y = np.random.random(10)
size = np.random.randint(150, size=10)
colors = np.random.choice(["r", "g", "b"], size=10)

fig = plt.figure()
plt.xlim(0, 10)
plt.ylim(0, 1)
graph = plt.scatter([], [])

def animate(i):
    graph.set_offsets(np.vstack((x[:i 1], y[:i 1])).T)
    graph.set_sizes(size[:i 1])
    graph.set_facecolors(colors[:i 1])
    return graph

ani = FuncAnimation(fig, animate, repeat=False, interval=200)

HTML(ani.to_jshtml())

Mark the option loop, and click in the minus ou plus sing to slow or speed up the animation

CodePudding user response:

I suggest you to use a timer in a thread and adjust the frequence to refresh periodically your datas like following :

you have also another example here too : How can I dynamically update my matplotlib figure as the data file changes?

import pylab as pl
import random
from threading import Timer

datas = [8, 20]

def dataprovider():
    global datas
    datas.append(random.randint(0, 20))
    return datas

def random_col():
    return ['blue', 'red', 'green', 'orange'][random.randint(0,3)]

# .... #
fig = pl.figure()
axes = [fig.add_subplot(1,1,1)]
paths = [ax.scatter(x=datas, y=datas, marker = ' ', c=random_col()) for ax in axes]
# .... #

def clear_arts(paths, all_arts=-1):
    if all_arts < 0:
        all_arts = len(paths)
    for path in paths[:all_arts]:
        path.remove()   

def refresh_arts(paths, delay_repeat):
    datas = dataprovider()
    print(datas)
    # 1 - clear previous artists
    clear_arts(paths,all_arts=-1)
    # 2 - Get artists paths for cleaning
    paths = [ax.scatter(x=datas, y=datas, marker = ' ', c=random_col()) for ax in axes]
    # 3 - Apply changes
    fig.canvas.draw_idle()    
    # 4 - Create another timer
    Timer(delay_repeat, refresh_arts, (paths, delay_repeat)).start()

# 4- Create a timer that will run function with arguments args and keyword arguments kwargs, 
# after interval seconds have passed.
delay_repeat = 2
Timer(delay_repeat, refresh_arts, (paths, delay_repeat)).start()

# print("process continues here")

pl.show()
  • Related