Python 使用Matplotlib对数据进行动画散点绘制
我试图以这种方式调整动画散点图示例,因此它实时显示了我开发的基于代理的模型的结果。然而,图中显示的结果并不是我想要的结果,除了它们。 更新值时出错,代理倾向于以对角线聚集的地方会出现奇怪的模式。 我添加了一些简单的代码来说明这个问题。有人知道哪里出了问题吗Python 使用Matplotlib对数据进行动画散点绘制,python,matplotlib,animated,scatter,Python,Matplotlib,Animated,Scatter,我试图以这种方式调整动画散点图示例,因此它实时显示了我开发的基于代理的模型的结果。然而,图中显示的结果并不是我想要的结果,除了它们。 更新值时出错,代理倾向于以对角线聚集的地方会出现奇怪的模式。 我添加了一些简单的代码来说明这个问题。有人知道哪里出了问题吗 import matplotlib.pyplot as plt import matplotlib.animation as animation import numpy as np import os n = 25 ## nr of ag
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
import os
n = 25 ## nr of agents
x,y = 10, 10 ## matrix of x by y dimension
dataX, dataY, binaryRaster = [],[],[]
class AnimatedScatter(object):
"""An animated scatter plot using matplotlib.animations.FuncAnimation."""
def __init__(self):
global n
self.numpoints = n
self.stream = self.data_stream()
self.fig, self.ax = plt.subplots()
self.ax.set_title("My first Agent Based Model (ABM)",fontsize=14)
self.ax.grid(True,linestyle='-',color='0.75')
self.ani = animation.FuncAnimation(self.fig, self.update, interval=100,
init_func=self.setup_plot, blit=True,
repeat=False)
def setup_plot(self):
"""Initial drawing of the scatter plot."""
global x,y
dataX,dataY = next(self.stream)
self.scat = self.ax.scatter(dataY, dataX, c="tomato", s=20, animated=True)
self.ax.axis([0, y, x, 0])
return self.scat,
def data_stream(self):
"""Generate a random walk (brownian motion). Data is scaled to produce
a soft "flickering" effect."""
global x,y, n
dataX,dataY = self.createRandomData()
#printing results to ascii for validation
lines = []
binaryData = np.zeros((x,y), dtype=np.int)
for i in range(n):
binaryData[dataX,dataY] =1
for i in range(x):
line = ""
for j in range(y):
line += str(binaryData[i,j])+ ","
line= line[:-1]+ "\n"
lines.append(line)
lines.append("\n")
yx = np.array([dataY,dataX])
cnt = 0
while cnt < 10:
dataX,dataY = self.createRandomData()
yx = np.array([dataY,dataX])
#printing results to ascii for validation
binaryData = np.zeros((x,y), dtype=np.int)
for i in range(n):
binaryData[dataX,dataY] =1
for i in range(x):
line = ""
for j in range(y):
line += str(binaryData[i,j])+ ","
line= line[:-1]+ "\n"
lines.append(line)
lines.append("\n")
cnt+=1
yield yx
#printing results to ascii for validation
outNm = os.getcwd()+"\\ScatterValidation.txt"
outfile = open(outNm, "w")
outfile.writelines(lines)
outfile.close()
return
def update(self, i):
"""Update the scatter plot."""
data = next(self.stream)
self.scat.set_offsets(data[:2, :])
return self.scat,
def show(self):
plt.show()
def createRandomData(self):
"""Positions n agents randomly on a raster of x by y cells.
Each cell can only hold a single agent."""
global x,y,n
binaryData = np.zeros((x,y), dtype=np.int)
newAgents = 0
dataX,dataY = [],[]
while newAgents < n:
row = np.random.randint(0,x,1)[0]
col = np.random.randint(0,y,1)[0]
if binaryData[row][col] != 1:
binaryData[row][col] = 1
newAgents+=1
for row in range(x):
for col in range(y):
if binaryData[row][col] == 1:
dataX.append(row)
dataY.append(col)
return dataX, dataY
def main():
global n, x, y, dataX, dataY, binaryRaster
a = AnimatedScatter()
a.show()
return
if __name__ == "__main__":
main()
导入matplotlib.pyplot作为plt
将matplotlib.animation导入为动画
将numpy作为np导入
导入操作系统
n=25个代理人
x、 y=10,x×y维的10##矩阵
dataX、dataY、二进制光栅=[]、[]、[]
类AnimatedScatter(对象):
“”“使用matplotlib.animations.FuncAnimation的动画散点图。”“”
定义初始化(自):
全球n
self.numpoints=n
self.stream=self.data\u stream()
self.fig,self.ax=plt.subplot()
self.ax.set_title(“我的第一个基于代理的模型(ABM)”,fontsize=14)
self.ax.grid(True,linestyle='-',color='0.75')
self.ani=animation.FuncAnimation(self.fig,self.update,interval=100,
init_func=self.setup_plot,blit=True,
重复(错误)
def设置图(自):
“”“散点图的初始绘制。”“”
全局x,y
dataX,dataY=next(self.stream)
self.scat=self.ax.scatt(dataY,dataX,c=“番茄”,s=20,动画=True)
自身最大轴([0,y,x,0])
返回self.scat,
def数据流(自):
“”“生成随机游动(布朗运动)。数据按比例缩放以生成
柔和的“闪烁”效果
全局x,y,n
dataX,dataY=self.createRandomData()
#将结果打印到ascii以进行验证
行=[]
binaryData=np.zeros((x,y),dtype=np.int)
对于范围(n)中的i:
binaryData[dataX,dataY]=1
对于范围(x)内的i:
line=“”
对于范围(y)内的j:
line+=str(二进制数据[i,j])+“,”
行=行[:-1]+“\n”
行。追加(行)
行。追加(“\n”)
yx=np.array([dataY,dataX])
cnt=0
当cnt<10时:
dataX,dataY=self.createRandomData()
yx=np.array([dataY,dataX])
#将结果打印到ascii以进行验证
binaryData=np.zeros((x,y),dtype=np.int)
对于范围(n)中的i:
binaryData[dataX,dataY]=1
对于范围(x)内的i:
line=“”
对于范围(y)内的j:
line+=str(二进制数据[i,j])+“,”
行=行[:-1]+“\n”
行。追加(行)
行。追加(“\n”)
cnt+=1
产量yx
#将结果打印到ascii以进行验证
outNm=os.getcwd()+“\\ScatterValidation.txt”
输出文件=打开(输出NM,“w”)
输出文件写入线(行)
outfile.close()
返回
def更新(自我,i):
“”“更新散点图。”“”
数据=下一个(self.stream)
self.scat.set_偏移量(数据[:2,:])
返回self.scat,
def显示(自我):
plt.show()
def createRandomData(自):
“”“在x×y单元格的光栅上随机定位n个代理。”。
每个单元格只能容纳一个代理。”“”
全局x,y,n
binaryData=np.zeros((x,y),dtype=np.int)
newAgents=0
dataX,dataY=[],[]
当新代理
您可以通过两种方式修复脚本,这两种方式都涉及更改更新功能:
我认为在update函数中使用分散调用更清晰
在update中调用set_offset之前转置数据数组
使用分散调用是最清晰的修复方法,您可以在运行期间增加代理:
def update(self, i):
"""Update the scatter plot."""
dataX, dataY = next(self.stream)
self.scat = self.ax.scatter(dataX, dataY, c="tomato", s=20, animated=True)
return self.scat,
变换偏移量数组也会起作用:
def update(self, i):
"""Update the scatter plot."""
data = next(self.stream)
self.scat.set_offsets(data.transpose())
return self.scat,
偏移量以每个2项的N个元组的形式给出,而数据数组以每个N项的2个元组的形式给出,转换数据数组将解决您的问题
注意:如果不更改全局变量,则不需要使用全局语句指定全局变量,因此在设置\u绘图
,初始化
等中,可以删除全局n,x,y
行。
我会将n
、x
和y
作为类的实例变量,而且不需要在脚本顶部定义dataX
、dataY
和binaryRasted
。亲爱的Arjenve,回答得很好!!我已经认为这个“更新”功能出现了故障。你的两个选择都很完美。