精华内容
下载资源
问答
  • matplotlib 绘制实时动态曲线图

    千次阅读 2020-10-13 22:30:22
    matplotlib 实时动态曲线

    在这里插入图片描述

    在这里插入图片描述

    import numpy as np
    import matplotlib.pyplot as plt
    %matplotlib qt5
    from IPython import display
    import math
    import time
    
     
    fig=plt.figure()
    ax=fig.add_subplot(1,1,1)
    
    ax.set_xlabel('Time')
    ax.set_ylabel('cos(t)')
    ax.set_title('')
    
    line = None
    plt.grid(True) #添加网格
    plt.ion()  #interactive mode on
    obsX = []
    obsY = []
    
    t0 = time.time()
    
    while True:
        t = time.time()-t0
        obsX.append(t)
        obsY.append(math.cos(2*math.pi*1*t))
    
        if line is None:
            line = ax.plot(obsX,obsY,'-g',marker='*')[0]
    
        line.set_xdata(obsX)
        line.set_ydata(obsY)
    
        ax.set_xlim([t-10,t+1])
        ax.set_ylim([-1,1])
    
        plt.pause(0.01)
    
    

    在这里插入图片描述

    展开全文
  • 本篇博客搬运自个人简书链接戳我,欢迎大家关注。 - 很多时候,我们需要实时的绘制曲线,如实时的绘制串口接收到的数据。最先想到的解决策略是类似...通过网上现有的资料 基于Python实现matplotlib动态更新图片(...

    本篇博客搬运自个人简书链接戳我,欢迎大家关注。

    • 很多时候,我们需要实时的绘制曲线,如实时的绘制串口接收到的数据。最先想到的解决策略是类似于Matlab种的drawnow函数。
    • 在python中Matplotlib库有着和Matlan绘图库相似的功能,但是并没有drawnow这样的函数。

    已有的解决方案

    存在的问题

    • 通过上述方法实时绘图,存在一个严重的问题:随着时间推移,CPU消耗越大,费时越多,最终导致程序卡顿。这显然无法满足我们实时绘图的要求。
    • 以下通过time模块计算每一步的耗时,直观地表现这一现象。
      • 完整代码
    def Method(point):
        es_time = np.zeros([point]) 
        fig=plt.figure()
        ax=fig.add_subplot(1,1,1)
        ax.axis("equal") #设置图像显示的时候XY轴比例
        ax.set_xlabel('Horizontal Position')
        ax.set_ylabel('Vertical Position')
        ax.set_title('Vessel trajectory')
        plt.grid(True) #添加网格
        plt.ion()  #interactive mode on
        IniObsX=0000
        IniObsY=4000
        IniObsAngle=135
        IniObsSpeed=10*math.sqrt(2)   #米/秒
        print('开始仿真')
        for t in range(point):
            t0 = time.time()
            #障碍物船只轨迹
            obsX=IniObsX+IniObsSpeed*math.sin(IniObsAngle/180*math.pi)*t
            obsY=IniObsY+IniObsSpeed*math.cos(IniObsAngle/180*math.pi)*t
            ax.scatter(obsX,obsY,c='b',marker='.')  #散点图
            #下面的图,两船的距离
            plt.pause(0.001)
            es_time[t] = 1000*(time.time() - t0)
        return es_time
    • 耗时结果
      Method
      • 很显然每步绘图时间与绘图点数呈线性相关的趋势,且随着点数增加,时间消耗越多。可以想象,当绘图的点数到达上万乃至亿的时候,那电脑就卡住了。

    分析原因

    • 个人猜测出现上述这种现象的原因,是由代码ax.scatter(obsX,obsY,c='b',marker='.')造成的。这段代码每一循环一次就新画一条曲线,而不清除之前的曲线,这就必然导致越往后循环所花费的CPU资源内存资源越多,最终机器卡死。

    改进方法

    • 既然原因是因为不断重复画图所致,导致机器资源的累积消耗,所以想到的第一个解决方法,那就是每次画图前,清除之前的曲线
    • 根据上述思想,在每一次的画图代码ax.scatter(obsX,obsY,c='b',marker='.')前加上清除代码plt.cla()。即:
            plt.cla()
            ax.plot(obsX,obsY,'-g',marker='*')  #散点图
    • 可是这样做之后就会存在新的问题:之前定义的坐标轴,标题,图例等等信息就都被清除了。解决方法则,需要在每一步的循环中,重新定义这些信息。
    • 完整代码
    def Method_Improve(point):
        def initial(ax):
            ax.axis("equal") #设置图像显示的时候XY轴比例
            ax.set_xlabel('Horizontal Position')
            ax.set_ylabel('Vertical Position')
            ax.set_title('Vessel trajectory')
            plt.grid(True) #添加网格
            return ax
    
        es_time = np.zeros([point]) 
        fig=plt.figure()
        ax=fig.add_subplot(1,1,1)
        ax = initial(ax)
        plt.ion()  #interactive mode on
        IniObsX=0000
        IniObsY=4000
        IniObsAngle=135
        IniObsSpeed=10*math.sqrt(2)   #米/秒
        print('开始仿真')
        obsX = [0,]
        obsY = [4000,]
        for t in range(point):
            t0 = time.time()
            #障碍物船只轨迹
            obsX.append(IniObsX+IniObsSpeed*math.sin(IniObsAngle/180*math.pi)*t)
            obsY.append(IniObsY+IniObsSpeed*math.cos(IniObsAngle/180*math.pi)*t)
            plt.cla()
            ax = initial(ax)
            ax.plot(obsX,obsY,'-g',marker='*')  #散点图
            #下面的图,两船的距离
            plt.pause(0.001)
            es_time[t] = 1000*(time.time() - t0)
        return es_time
    • 耗时结果
      Method_Improve
    • 显然循环次数与耗时不再呈正相关趋势,可以说是在一定误差范围内,耗时保持稳定。

    改进方法的改进

    • 改进方法中仍存在一个问题:由于每次循环都需要清除坐标轴信息,那么每次循环也必须再重新设置坐标轴信息。显然这种做法,导致了额外的算力消耗,那能否有新的方法,规避这种问题呢?答案显然是有的。
    • 但是解决思路还是得从原始问题出发,即重复画图,导致资源的累积消耗。所以令一种新的思路:只画一条(需要数量的)曲线,每次循环更改这些曲线的数据
    • 那么按照上述思路之后,只需程序开头定义好坐标轴信息,而不需要每次循环内清除重设坐标轴信息。
    • 具体做法,就是获取曲线的句柄,进行修改,即有:
            line.set_xdata(obsX)
            line.set_ydata(obsY)

    完整代码:

    def ImprovedMethod_Improve(point):    
        es_time = np.zeros([point]) 
        fig=plt.figure()
        ax=fig.add_subplot(1,1,1)
    
        ax.set_xlabel('Horizontal Position')
        ax.set_ylabel('Vertical Position')
        ax.set_title('Vessel trajectory')
    
        line = ax.plot([0,0],[4000,4000],'-g',marker='*')[0]
        plt.grid(True) #添加网格
        plt.ion()  #interactive mode on
        IniObsX=0000
        IniObsY=4000
        IniObsAngle=135
        IniObsSpeed=10*math.sqrt(2)   #米/秒
        print('开始仿真')
        obsX = [0,]
        obsY = [4000,]
        for t in range(point):
            t0 = time.time()
            #障碍物船只轨迹
            obsX.append(IniObsX+IniObsSpeed*math.sin(IniObsAngle/180*math.pi)*t)
            obsY.append(IniObsY+IniObsSpeed*math.cos(IniObsAngle/180*math.pi)*t)
    
            line.set_xdata(obsX)
            line.set_ydata(obsY)
            ax.set_xlim([-200,10*point+200])
            ax.set_ylim([3800-10*point,4200])
            #下面的图,两船的距离
            plt.pause(0.001)
            es_time[t] = 1000*(time.time() - t0)
        return es_time

    三种方法对比

    三种方法对比

    展开全文
  • 点击Start按钮,会开启定时器,每隔100ms根据队列来实时更新数据图像 点击PrintBtn按钮,会在后台打印三个队列中的数据,及大小,主要为了方便调试 点击End按钮,停止计时器,退出线程,回收资源 目录 pyqt5 准备...
  • 实时画图 import matplotlib.pyplot as plt ax = [] # 定义一个 x 轴的空列表用来接收动态的数据 ay = [] # 定义一个 y 轴的空列表用来接收动态的数据 plt.ion() # 开启一个画图的窗口 for i in range(100): # 遍历...
  • Python中matplotlib实时画图

    万次阅读 多人点赞 2018-09-13 11:16:14
    github博客传送门 ...实时画图 import matplotlib.pyplot as plt ax = [] # 定义一个 x 轴的空列表用来接收动态的数据 ay = [] # 定义一个 y 轴的空列表用来接收动态的数据 plt.ion() # 开启一个画图的...

    github博客传送门
    博客园传送门

    实时画图

    import matplotlib.pyplot as plt
    
    ax = []                    # 定义一个 x 轴的空列表用来接收动态的数据
    ay = []                    # 定义一个 y 轴的空列表用来接收动态的数据
    plt.ion()                  # 开启一个画图的窗口
    for i in range(100):       # 遍历0-99的值
    	ax.append(i)           # 添加 i 到 x 轴的数据中
    	ay.append(i**2)        # 添加 i 的平方到 y 轴的数据中
    	plt.clf()              # 清除之前画的图
    	plt.plot(ax,ay)        # 画出当前 ax 列表和 ay 列表中的值的图形
    	plt.pause(0.1)         # 暂停一秒
    	plt.ioff()             # 关闭画图的窗口
    

    实时画图 效果图
    动态画图

    展开全文
  • 实时画图import matplotlib.pyplot as pltax = [] # 定义一个 x 轴的空列表用来接收动态的数据ay = [] # 定义一个 y 轴的空列表用来接收动态的数据plt.ion() # 开启一个画图的窗口for i in range(100): # 遍历0-99的...

    实时画图

    import matplotlib.pyplot as plt

    ax = [] # 定义一个 x 轴的空列表用来接收动态的数据

    ay = [] # 定义一个 y 轴的空列表用来接收动态的数据

    plt.ion() # 开启一个画图的窗口

    for i in range(100): # 遍历0-99的值

    ax.append(i) # 添加 i 到 x 轴的数据中

    ay.append(i**2) # 添加 i 的平方到 y 轴的数据中

    plt.clf() # 清除之前画的图

    plt.plot(ax,ay) # 画出当前 ax 列表和 ay 列表中的值的图形

    plt.pause(0.1) # 暂停一秒

    plt.ioff() # 关闭画图的窗口

    实时画图 效果图

    补充知识:Python 绘图与可视化 matplotlib 动态条形图 bar

    第一种办法

    一种方法是每次都重新画,包括清除figure

    def animate(fi):

    bars=[]

    if len(frames)>fi:

    # axs.text(0.1,0.90,time_template%(time.time()-start_time),transform=axs.transAxes)#所以这样

    time_text.set_text(time_template%(0.1*fi))#这个必须没有axs.cla()才行

    # axs.cla()

    axs.set_title('bubble_sort_visualization')

    axs.set_xticks([])

    axs.set_yticks([])

    bars=axs.bar(list(range(Data.data_count)),#个数

    [d.value for d in frames[fi]],#数据

    1, #宽度

    color=[d.color for d in frames[fi]]#颜色

    ).get_children()

    return bars

    anim=animation.FuncAnimation(fig,animate,frames=len(frames), interval=frame_interval,repeat=False)

    这样效率很低,而且也有一些不可取的弊端,比如每次都需要重新设置xticks、假如figure上添加的有其他东西,这些东西也一并被clear了,还需要重新添加,比如text,或者labale。

    第二种办法

    可以像平时画线更新data那样来更新bar的高

    '''

    遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006

    寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!

    '''

    import matplotlib.pyplot as plt

    import numpy as np

    from matplotlib import animation

    fig=plt.figure(1,figsize=(4,3))

    ax=fig.add_subplot(111)

    ax.set_title('bar_animate_test')

    #ax.set_xticks([])注释了这个是能看到变化,要不看不到变化,不对,能看到变化,去了注释吧

    #ax.set_yticks([])

    ax.set_xlabel('xlable')

    N=5

    frames=50

    x=np.arange(1,N+1)

    collection=[]

    collection.append([i for i in x])

    for i in range(frames):

    collection.append([ci+1 for ci in collection[i]])

    print(collection)

    xstd=[0,1,2,3,4]

    bars=ax.bar(x,collection[0],0.30)

    def animate(fi):

    # collection=[i+1 for i in x]

    ax.set_ylim(0,max(collection[fi])+3)#对于问题3,添加了这个

    for rect ,yi in zip(bars,collection[fi]):

    rect.set_height(yi)

    # bars.set_height(collection)

    return bars

    anim=animation.FuncAnimation(fig,animate,frames=frames,interval=10,repeat=False)

    plt.show()

    问题

    *)TypeError: ‘numpy.int32' object is not iterable

    x=np.arange(1,N+1)
    collection=[i for i in x]

    #collection=[i for i in list(x)]#错误的认为是dtype的原因,将这里改成了list(x)

    for i in range(frames):

    collection.append([ci+1 for ci in collection[i]])#问题的原因是因为此时的collection还是一个一位数组,所以这个collection[i]是一个x里的一个数,并不是一个列表,我竟然还以为的dtype的原因,又改了

    xstd=[0,1,2,3,4]

    应该是

    '''

    遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006

    寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!

    '''

    collection=[]

    collection.append([i for i in x])#成为二维数组

    for i in range(frames):

    collection.append([ci+1 for ci in collection[i]])

    然后又出现了下面的问题:

    *)TypeError: only size-1 arrays can be converted to Python scalars

    Traceback (most recent call last):

    File "forTest.py", line 22, in

    bars=ax.bar(x,collection,0.30)

    File "C:\Users\Administrator.SC-201605202132\Envs\sort\lib\site-packages\matplotlib\__init__.py", line 1589, in inner

    return func(ax, *map(sanitize_sequence, args), **kwargs)

    File "C:\Users\Administrator.SC-201605202132\Envs\sort\lib\site-packages\matplotlib\axes\_axes.py", line 2430, in bar

    label='_nolegend_',

    File "C:\Users\Administrator.SC-201605202132\Envs\sort\lib\site-packages\matplotlib\patches.py", line 707, in __init__

    Patch.__init__(self, **kwargs)

    File "C:\Users\Administrator.SC-201605202132\Envs\sort\lib\site-packages\matplotlib\patches.py", line 89, in __init__

    self.set_linewidth(linewidth)

    File "C:\Users\Administrator.SC-201605202132\Envs\sort\lib\site-packages\matplotlib\patches.py", line 368, in set_linewidth

    self._linewidth = float(w)

    TypeError: only size-1 arrays can be converted to Python scalars

    应该是传递的参数错误,仔细想了一下,在报错的代码行中,collection原来是没错的,因为原来是一维数组,现在变成二维了,改为

    bars=ax.bar(x,collection[0],0.30)

    好了

    *)出现的问题,在上面的代码中,运行的时候不会画布的大小不会变,会又条形图溢出的情况,在animate()中添加了

    '''

    遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006

    寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!

    '''

    def animate(fi):

    # collection=[i+1 for i in x]

    ax.set_ylim(0,max(collection[fi])+3)#添加了这个

    for rect ,yi in zip(bars,collection[fi]):

    rect.set_height(yi)

    # bars.set_height(collection)

    return bars

    别的属性

    *)条形图是怎样控制间隔的:

    是通过控制宽度

    width=1,#没有间隔,每个条形图会紧挨着

    *)errorbar:

    是加一个横线,能通过xerr和yerr来调整方向

    xstd=[0,1,2,3,4]

    bars=ax.bar(x,collection,0.30,xerr=xstd)

    以上这篇Python matplotlib实时画图案例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持自学编程网。

    展开全文
  • 实时画图import matplotlib.pyplot as pltax = [] # 定义一个 x 轴的空列表用来接收动态的数据ay = [] # 定义一个 y 轴的空列表用来接收动态的数据plt.ion() # 开启一个画图的窗口for i in range(100): # 遍历0-99的...
  • python学习:使用Matplotlib实时动态折线图

    万次阅读 多人点赞 2019-04-26 18:01:37
    python学习:使用Matplotlib实时动态折线图 有时,为了方便看数据的变化情况,需要画一个动态图来看整体的变化情况。主要就是用Matplotlib库。 参考博客链接:...
  • 实时画图import matplotlib.pyplot as pltax = [] # 定义一个 x 轴的空列表用来接收动态的数据ay = [] # 定义一个 y 轴的空列表用来接收动态的数据plt.ion() # 开启一个画图的窗口for i in range(100): # 遍历0-99的...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 129
精华内容 51
关键字:

matplotlib实时动态