python matplotlib更新函数的散点图

时间:2022-09-10 22:26:41

I am trying to automatically update a scatter plot. The source of my X and Y values is external, and the data is pushed automatically into my code in a non-predicted time intervals (rounds).

我正在尝试自动更新散点图。我的X和Y值的来源是外部的,数据会以非预测的时间间隔(轮次)自动推送到我的代码中。

I have only managed to plot all the data when the whole process ended, whereas I am trying to constantly add and plot data into my canvas.

我只是设法在整个过程结束时绘制所有数据,而我正在尝试不断添加数据并将数据绘制到我的画布中。

What I DO get (at the end of the whole run) is this: python matplotlib更新函数的散点图

我得到的(在整个运行结束时)是这样的:

Whereas, what I am after is this: python matplotlib更新函数的散点图

然而,我所追求的是:

A simplified version of my code:

我的代码的简化版本:

import matplotlib.pyplot as plt

def read_data():
    #This function gets the values of xAxis and yAxis
    xAxis = [some values]  #these valuers change in each run
    yAxis = [other values] #these valuers change in each run

    plt.scatter(xAxis,yAxis, label  = 'myPlot', color = 'k', s=50)     
    plt.xlabel('x')
    plt.ylabel('y')
    plt.show()

2 个解决方案

#1


12  

There are several ways to animate a matplotlib plot. In the following let's look at two minimal examples using a scatter plot.

有几种方法可以对matplotlib图进行动画处理。在下文中,我们将使用散点图查看两个最小示例。

(a) use interactive mode plt.ion()

For an animation to take place we need an event loop. One way of getting the event loop is to use plt.ion() ("interactive on"). One then needs to first draw the figure and can then update the plot in a loop. Inside the loop, we need to draw the canvas and introduce a little pause for the window to process other events (like the mouse interactions etc.). Without this pause the window would freeze. Finally we call plt.waitforbuttonpress() to let the window stay open even after the animation has finished.

要进行动画制作,我们需要一个事件循环。获取事件循环的一种方法是使用plt.ion()(“交互式打开”)。然后需要首先绘制图形,然后可以循环更新绘图。在循环内部,我们需要绘制画布并为窗口引入一点暂停来处理其他事件(如鼠标交互等)。没有这个暂停,窗口就会冻结。最后,我们调用plt.waitforbuttonpress()让窗口保持打开状态,即使动画完成后也是如此。

import matplotlib.pyplot as plt
import numpy as np

plt.ion()
fig, ax = plt.subplots()
x, y = [],[]
sc = ax.scatter(x,y)
plt.xlim(0,10)
plt.ylim(0,10)

plt.draw()
for i in range(1000):
    x.append(np.random.rand(1)*10)
    y.append(np.random.rand(1)*10)
    sc.set_offsets(np.c_[x,y])
    fig.canvas.draw_idle()
    plt.pause(0.1)

plt.waitforbuttonpress()

(b) using FuncAnimation

Much of the above can be automated using matplotlib.animation.FuncAnimation. The FuncAnimation will take care of the loop and the redrawing and will constantly call a function (in this case animate()) after a given time interval. The animation will only start once plt.show() is called, thereby automatically running in the plot window's event loop.

以上大部分都可以使用matplotlib.animation.FuncAnimation自动完成。 FuncAnimation将处理循环和重绘,并将在给定的时间间隔后不断调用函数(在本例中为animate())。只有在调用plt.show()时动画才会启动,从而在绘图窗口的事件循环中自动运行。

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

fig, ax = plt.subplots()
x, y = [],[]
sc = ax.scatter(x,y)
plt.xlim(0,10)
plt.ylim(0,10)

def animate(i):
    x.append(np.random.rand(1)*10)
    y.append(np.random.rand(1)*10)
    sc.set_offsets(np.c_[x,y])

ani = matplotlib.animation.FuncAnimation(fig, animate, 
                frames=2, interval=100, repeat=True) 
plt.show()

#2


2  

From what I understand, you want to update interactively your plot. If so, you can use plot instead of scatter plot and update the data of your plot like this.

据我所知,您希望以交互方式更新您的情节。如果是这样,您可以使用绘图而不是散点图并像这样更新绘图的数据。

import numpy
import matplotlib.pyplot as plt 
fig = plt.figure()
axe = fig.add_subplot(111)
X,Y = [],[]
sp, = axe.plot([],[],label='toto',ms=10,color='k',marker='o',ls='')
fig.show()
for iter in range(5):
    X.append(numpy.random.rand())
    Y.append(numpy.random.rand())
    sp.set_data(X,Y)
    axe.set_xlim(min(X),max(X))
    axe.set_ylim(min(Y),max(Y))
    raw_input('...')
    fig.canvas.draw()

If this is the behaviour your are looking for, you just need to create a function appending the data of sp, and get in that function the new points you want to plot (either with I/O management or whatever the communication process you're using). I hope it helps.

如果这是您正在寻找的行为,您只需要创建一个附加sp数据的函数,并在该函数中输入您想要绘制的新点(使用I / O管理或任何通信过程即可使用)。我希望它有所帮助。

#1


12  

There are several ways to animate a matplotlib plot. In the following let's look at two minimal examples using a scatter plot.

有几种方法可以对matplotlib图进行动画处理。在下文中,我们将使用散点图查看两个最小示例。

(a) use interactive mode plt.ion()

For an animation to take place we need an event loop. One way of getting the event loop is to use plt.ion() ("interactive on"). One then needs to first draw the figure and can then update the plot in a loop. Inside the loop, we need to draw the canvas and introduce a little pause for the window to process other events (like the mouse interactions etc.). Without this pause the window would freeze. Finally we call plt.waitforbuttonpress() to let the window stay open even after the animation has finished.

要进行动画制作,我们需要一个事件循环。获取事件循环的一种方法是使用plt.ion()(“交互式打开”)。然后需要首先绘制图形,然后可以循环更新绘图。在循环内部,我们需要绘制画布并为窗口引入一点暂停来处理其他事件(如鼠标交互等)。没有这个暂停,窗口就会冻结。最后,我们调用plt.waitforbuttonpress()让窗口保持打开状态,即使动画完成后也是如此。

import matplotlib.pyplot as plt
import numpy as np

plt.ion()
fig, ax = plt.subplots()
x, y = [],[]
sc = ax.scatter(x,y)
plt.xlim(0,10)
plt.ylim(0,10)

plt.draw()
for i in range(1000):
    x.append(np.random.rand(1)*10)
    y.append(np.random.rand(1)*10)
    sc.set_offsets(np.c_[x,y])
    fig.canvas.draw_idle()
    plt.pause(0.1)

plt.waitforbuttonpress()

(b) using FuncAnimation

Much of the above can be automated using matplotlib.animation.FuncAnimation. The FuncAnimation will take care of the loop and the redrawing and will constantly call a function (in this case animate()) after a given time interval. The animation will only start once plt.show() is called, thereby automatically running in the plot window's event loop.

以上大部分都可以使用matplotlib.animation.FuncAnimation自动完成。 FuncAnimation将处理循环和重绘,并将在给定的时间间隔后不断调用函数(在本例中为animate())。只有在调用plt.show()时动画才会启动,从而在绘图窗口的事件循环中自动运行。

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

fig, ax = plt.subplots()
x, y = [],[]
sc = ax.scatter(x,y)
plt.xlim(0,10)
plt.ylim(0,10)

def animate(i):
    x.append(np.random.rand(1)*10)
    y.append(np.random.rand(1)*10)
    sc.set_offsets(np.c_[x,y])

ani = matplotlib.animation.FuncAnimation(fig, animate, 
                frames=2, interval=100, repeat=True) 
plt.show()

#2


2  

From what I understand, you want to update interactively your plot. If so, you can use plot instead of scatter plot and update the data of your plot like this.

据我所知,您希望以交互方式更新您的情节。如果是这样,您可以使用绘图而不是散点图并像这样更新绘图的数据。

import numpy
import matplotlib.pyplot as plt 
fig = plt.figure()
axe = fig.add_subplot(111)
X,Y = [],[]
sp, = axe.plot([],[],label='toto',ms=10,color='k',marker='o',ls='')
fig.show()
for iter in range(5):
    X.append(numpy.random.rand())
    Y.append(numpy.random.rand())
    sp.set_data(X,Y)
    axe.set_xlim(min(X),max(X))
    axe.set_ylim(min(Y),max(Y))
    raw_input('...')
    fig.canvas.draw()

If this is the behaviour your are looking for, you just need to create a function appending the data of sp, and get in that function the new points you want to plot (either with I/O management or whatever the communication process you're using). I hope it helps.

如果这是您正在寻找的行为,您只需要创建一个附加sp数据的函数,并在该函数中输入您想要绘制的新点(使用I / O管理或任何通信过程即可使用)。我希望它有所帮助。