微信公衆号裡的動圖
在前天推文“狗追鴨子[1]”留言中,有同學學問推文中的動圖是如何制作的。
關于動圖的制作方法,在公衆号裡大家輸入 動圖? 便可以查詢到原來的說明。
推文中的動圖是通過資料采集系統,包括可以讀取數值的數字萬用表、數字示波器、數字頻譜儀以及特制的資料采集闆卡等來采集。然後通過python語言繪制産生相應的動圖。動圖的風格包括以下兩種:
(1)動态信号波形
仿照示波器顯示波形的形式,将連續采集到的資料動态展示出來,反映了信号的變化特點。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiYWan5CZ2QmZwUWZyQWM1kzYhJTNmZDOiJ2N1M2NzUmZxkTM18CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.gif)
動态信号波形圖
(2)逐漸增多資料曲線
将采集到的資料從少到多繪制成逐漸壓縮的曲線,可以展示資料發展的趨勢規律。
動态資料曲線
繪制動圖方法
以上兩種方式主要是借助于兩組指令分成兩步形成GIF動圖。
第一步 繪制曲線,存儲圖檔
繪制曲線使用matplotlib中的plot指令完成。根據需要繪制的風格,可以選擇按照一幀一幀地逐幀繪制,也可選擇按照從少到多的繪制方式。
下面的代碼片段顯示了繪制一組頻率變化的正弦曲線的圖像,并将它們逐幀存儲在指定目錄中,檔案名稱從0.jpg,變化到49.jpg。這是制作動圖的第一步。
import matplotlib.pyplot as pltomiga = linspace(1, 5, 50)t = linspace(0, 20, 200)count=0for o in omiga: sint = sin(t * o) plt.clf() plt.plot(t, sint, label='Sinusoidal Curve') plt.xlabel('Time (s)') plt.ylabel('Amplitude (V)') plt.grid(True) plt.savefig(r'd:emp%d.jgp'%count) count = count+1
根據matplotlib中的說明,存儲圖頻的格式不包括BMP格式。可以生成JPG或者其他類型的圖檔。
生成頻譜動态增加的曲線
第二步 生成動圖檔案
有了逐幀圖檔,現在有很多獨立的程式,或者線上的網站可以提供轉換成GIF片的功能。其中一個小巧但功能比較強的軟體工具是:movgear.exe 軟體。它不僅可以将一組單張圖圖頻轉換成GIF圖檔,也可以完成相應的編輯功能。
也存在很多python軟體包可以幫助生成GIF圖檔,其中一個比較簡便的就是是踹死PIL中的Image對象,在調用save()指令的時候生成GIF檔案。在生成的同時可以指明每個圖檔顯示的時間長度。
下面的代碼片段顯示了應用Image将輸入的一組檔案名稱所對應的圖頻轉換成GIF檔案的過程。
下面是定義了一個PlotGIF類來幫助存儲plt對象中的檔案以及最後生成GIF圖檔。其中在初始化的時候指明一個臨時的目錄來存儲PLOT存儲的JPG檔案。使用append()指令來添加每一次 plt 調用 savefig 所産生的檔案。最後使用 save() 指令生成最終的 GIF 檔案。
#------------------------------------------------------------# TSDRAW.PY#------------------------------------------------------------from tsmodule.tspdata import *from PIL import Image#------------------------------------------------------------class PlotGIF(object): def __init__(self, gifdir=r'd:empGIF'): self.gifdir = gifdir self.imageDim = [] self.count = 0 if os.path.isdir(gifdir) == False: os.mkdir(gifdir) def infor(self, ): printf(self.gifdir, self.count) def __str__(self, ): return 'gifdir:%s'%self.dir def append(self, plt): filename = os.path.join(self.gifdir, '%04d.jpg'%self.count) self.count = self.count + 1 plt.savefig(filename) self.imageDim.append(Image.open(filename)) def save(self, giffile, period=100, last=100): duration = period[](self.imageDim "period") duration[-1] = last self.imageDim[0].save(giffile, save_all=True, append_images=self.imageDim[1:], duration=duration, loop=False) self.imageDim = [] self.count = 0 printf('Save GIF:%s'%giffile)
減少動圖檔案大小
如果是在微信公衆号中使用GIF檔案,它有兩個限制,一個是檔案的大小不超過5 MBytes。第二個限制是動圖中包含的圖檔不超過300張。
如果檔案的大小超過了5 M位元組怎麼辦?
一方面可以在使用 plt 時,每張圖檔的大小盡量減小。另外一方面可以使用 movgear軟體 對GIF檔案進行差分存儲。這種模式是将GIF圖檔中每相鄰的兩張圖檔相減,存儲時将變化量按照遊程無損編碼方式完成壓縮存儲。如果動圖相鄰兩張圖檔非常相似,這種差分之後的存儲就非常有效果。對于不複雜的 plt的圖檔使用差分存儲可以很輕松獲得5倍以上的壓縮效果。
movgear壓縮GIF檔案