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:\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

  參考鏈接: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)

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM