<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          案例:繪制Matplotlib動(dòng)態(tài)圖

          共 3784字,需瀏覽 8分鐘

           ·

          2022-06-24 18:47

          學(xué)習(xí) zhenguo 老師的 Python 課已經(jīng)一個(gè)星期了,自己感覺(jué)已經(jīng)學(xué)有小成,剛好昨天老師在接單群里發(fā)了一個(gè) 100元的單子,我毫不猶豫的接了,不僅可以檢驗(yàn)自己能否學(xué)以致用,還能賺頓小龍蝦的錢(50元~)。

          開(kāi)發(fā)需求

          這個(gè)單子的要求,是使用 Python 中的 matplotlib 庫(kù)繪制動(dòng)態(tài)的折線圖,需求描述雖然很簡(jiǎn)單易懂,但是也要好好分析一下。

          Matplotlib庫(kù)

          這個(gè)庫(kù)也算是 Python 數(shù)據(jù)開(kāi)發(fā)必學(xué)的庫(kù)之一了,它主要的功能就是繪制圖表,而且實(shí)現(xiàn)也非常簡(jiǎn)單,幾行代碼就可以繪制出直方圖、折線圖、散點(diǎn)圖、餅圖等等常用的圖表,一些復(fù)雜的數(shù)據(jù)分析圖表它也可以勝任。

          這里分享一個(gè)網(wǎng)址: www.matplotlib.org.cn/gallery/#lines-bars-and-markers,大家可以看看 Matplotlib 繪圖的一些案例,作為自己開(kāi)發(fā)的參考。

          核心問(wèn)題

          Matplotlib 庫(kù)繪制一張靜態(tài)的折線圖比較簡(jiǎn)單,給定X軸和Y軸的數(shù)據(jù)集就行,但是想要繪制動(dòng)態(tài)的折線圖,就要想辦法讓繪制出來(lái)的圖片動(dòng)起來(lái)。

          其實(shí)這個(gè)問(wèn)題理解起來(lái)也不難,Matplotlib 繪圖是生成一張圖片,讓它動(dòng)起來(lái)的原理就像是動(dòng)畫(huà)片,不斷生成新的圖片,讓它們前后連接,逐幀播放就行了。

          開(kāi)發(fā)過(guò)程

          理解了核心問(wèn)題,就可以開(kāi)始動(dòng)手來(lái)解決問(wèn)題了。

          加載數(shù)據(jù)

          在繪圖之前,先要把數(shù)據(jù)集合弄到,需求方給了一張 excel 表格,需要從表格中提取需要的數(shù)據(jù)集。

          這個(gè)過(guò)程也是比較簡(jiǎn)單的,需要用到 Python 數(shù)據(jù)分析必學(xué)的另一個(gè)庫(kù) Pandas

          只需要一行代碼 pandas.read_excel('data.xls'),就可以把 excel 文件加載到內(nèi)存。

          然后可以像操作 dict 一樣獲取每一列的數(shù)據(jù)集合,如:cls = pandas.read_excel('data.xls')['列頭名稱'],會(huì)得到一個(gè) <class 'pandas.core.series.Series'> 對(duì)象,可以直接遍歷每行的數(shù)據(jù),也可以格式轉(zhuǎn)化成列表類型。

          繪制一條折線

          有了數(shù)據(jù)之后,就可以畫(huà)圖了,先畫(huà)一條折線,把現(xiàn)有的數(shù)據(jù)展示出來(lái),看看效果。

          import matplotlib.pyplot as plt
          import data

          fig, ax = plt.subplots(figsize=(169), dpi=80)
          ax.set_ylim(035)
          ax.set_xticks(range(0, len(xdata), 10))

          xdata = data.times
          ydata = data.dealnums
          ax.plot(xdata, ydata)

          fig.autofmt_xdate()
          plt.show()

          代碼比較簡(jiǎn)單,下面是繪制出來(lái)的折線圖:

          讓折線動(dòng)起來(lái)

          接下來(lái)要做的,就是要讓折線圖動(dòng)起來(lái),不斷顯示新的數(shù)據(jù)。

          要實(shí)現(xiàn)這個(gè)效果,需要做兩個(gè)操作,一是讓數(shù)據(jù)動(dòng)起來(lái),在數(shù)據(jù)集中不斷增加新數(shù)據(jù),二是讓繪制的圖形按指定時(shí)間間隔動(dòng)起來(lái)。

          第一個(gè)操作,我是這樣做的,直接上代碼:

          for x, y in zip(xdata_set, ydata_set):
              xdata.append(x)
              ydata.append(y)

          也就是將原始數(shù)據(jù)集拆成單個(gè)數(shù)據(jù),逐個(gè)加載到X軸和Y軸的數(shù)據(jù)集中,實(shí)現(xiàn)數(shù)據(jù)動(dòng)態(tài)增加的效果。

          第二個(gè)操作,我首先想到的辦法,是每次數(shù)據(jù)更新的同時(shí),將整個(gè)畫(huà)布清空,重新畫(huà)出最新的圖表。

          for x, y in zip(xdata_set, ydata_set):
              xdata.append(x)
              ydata.append(y)
              
              plt.clf()  # 清空整個(gè)figure
              
              # 重新建立坐標(biāo)軸并畫(huà)出折線圖
              ax = fig.add_subplot(111)
              ax.plot(xdata, ydata)
              
              plt.pause(1# 休眠1秒后繪制新圖

          這個(gè)思路還有一點(diǎn)需要注意,就是要在開(kāi)始調(diào)用 plt.ion() 方法,啟動(dòng)互動(dòng)模式。

          這個(gè)方式不能直接保存圖像為動(dòng)圖,所以沒(méi)法展示了,效果跟后面的動(dòng)圖一樣。

          動(dòng)圖新思路

          按照上面的思路完成各個(gè)需求細(xì)節(jié)之后,我就把代碼提交給了 zhenguo 老師,老師不僅給予了肯定和鼓勵(lì),還提供了一個(gè)新的思路。

          也就是使用 Matplotlib 中的動(dòng)畫(huà)模塊來(lái)畫(huà)動(dòng)態(tài)圖。

          趕緊找到相關(guān)模塊和方法的文檔學(xué)習(xí)了起來(lái),最后發(fā)現(xiàn),只需要使用一個(gè) animation.FuncAnimation 類就可以滿足這個(gè)單子的需求。

          而且這個(gè)類用起來(lái)很方便,在構(gòu)建函數(shù)中傳入 figure 對(duì)象、更新圖表的函數(shù)、初始化函數(shù)和間隔參數(shù)就行了。

          import matplotlib.animation
          import matplotlib.pyplot as plt
          import data

          fig = plt.figure(figsize=(169), dpi=70)

          def draw_line(fig, x_data, y_data):
              ax = fig.add_subplot(111)
              ax.plot(xdata, ydata)
              return ax

          def init_figure():
              # 繪制初始的圖表
              xdata = data.times
              ydata = data.dealnums

              return draw_line(fig, xdata, ydata)
              
          def update(n):
              # 更新數(shù)據(jù)集 xdata 和 ydata
              xdata = data.new_times
              ydata = data.new_dealnums
              # 清除之前的坐標(biāo)系
              plt.clf() 
              # 繪制最新的折線圖
              return draw_line(fit, xdata, ydata)

          ani = animation.FuncAnimation(fig, update, init_func=init_figure, interval=1000)

          # 生成 gif 動(dòng)圖并保存
          ani.save('test.gif', writer='pillow')

          plt.show()

          這樣改造之后的代碼也是非常簡(jiǎn)單清晰,而且還能保存生成的動(dòng)圖。

          最后完善一些需求和代碼上的細(xì)節(jié)問(wèn)題,最終的效果是這樣的:

          是不是很酷!

          學(xué)習(xí)了 Python 之后,發(fā)現(xiàn)了很多有意思的編程方向,繪圖開(kāi)發(fā)只是宏觀藍(lán)圖的一小部分。

          通過(guò)這次的單子,我完成了從眼會(huì)到手會(huì)的突破,不僅對(duì) Matplotlib 庫(kù)有了更深的理解,更重要的是!

          今晚的小龍蝦有著落了!

          瀏覽 84
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  影音先锋啪 | 四虎高清无码 | 欧洲操逼免费看 | 大香蕉网在线视频 | 人人爱综合 |