zoukankan      html  css  js  c++  java
  • Python 绘图与可视化 matplotlib 动态条形图 bar

    bar的参考链接:https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.bar.html

    第一种办法

    一种方法是每次都重新画,包括清除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。

     

    第二种办法

    参考链接:https://stackoverflow.com/questions/16249466/dynamically-updating-a-bar-plot-in-matplotlib

    这个链接里的内容和上面的差不多:https://stackoverflow.com/questions/34372021/python-matplotlib-animate-bar-and-plot-in-one-picture/34372367#34372367

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

    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]

      应该是

    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 <module>
        bars=ax.bar(x,collection,0.30)
      File "C:UsersAdministrator.SC-201605202132Envssortlibsite-packagesmatplotlib\__init__.py", line 1589, in inner
        return func(ax, *map(sanitize_sequence, args), **kwargs)
      File "C:UsersAdministrator.SC-201605202132Envssortlibsite-packagesmatplotlibaxes\_axes.py", line 2430, in bar
        label='_nolegend_',
      File "C:UsersAdministrator.SC-201605202132Envssortlibsite-packagesmatplotlibpatches.py", line 707, in __init__
        Patch.__init__(self, **kwargs)
      File "C:UsersAdministrator.SC-201605202132Envssortlibsite-packagesmatplotlibpatches.py", line 89, in __init__
        self.set_linewidth(linewidth)
      File "C:UsersAdministrator.SC-201605202132Envssortlibsite-packagesmatplotlibpatches.py", line 368, in set_linewidth
        self._linewidth = float(w)
    TypeError: only size-1 arrays can be converted to Python scalars
    

      参考链接:https://www.cnblogs.com/Summerio/p/9723099.html

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

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

      好了

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

    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)
    

      

  • 相关阅读:
    C++0x standard & features in VC10
    Win32 结构化异常处理(SEH)探秘
    What Every Programmer Should Know About Memory
    Memory leak detector(C++)
    NT's Asynchronous Procedure Call
    服务器应用程序不可用
    不安全代码只会在使用 /unsafe 编译的情况下出现
    关于“因为数据库正在使用,所以无法获得对数据库的独占访问权”的最终解决方案
    让 PowerDesigner 支持 SQLite!
    基于.Net的单点登录(SSO)解决方案
  • 原文地址:https://www.cnblogs.com/Gaoqiking/p/11261336.html
Copyright © 2011-2022 走看看