作者:俊欣
來源:關於數據分析與可視化
在之前的一篇文章當中,小編當時分享了如何用 Python 當中的 gif 模塊來製作 gif 格式的圖表,
厲害了,用Python繪製動態可視化圖表,並保存成gif格式
今天小編再給大家來介紹一種製作 gif 格式圖表的新方法,調用的是 matplotlib 的相關模塊,其中的步驟與方法也是相當地簡單易懂。
下載和導入資料庫
我們這次用到的數據集是 bokeh 模塊自帶的數據集,通過下面這一行代碼直接就可以下載
import bokeh
bokeh.sampledata.download
然後導入後面要用到的數據集,我們挑選的是指定國家的1950年至今不同年齡階段的人口所占比重的數據
from bokeh.sampledata.population import data
import numpy as np
data = filter_loc( 'United States of America')
data.head
output
先繪製若干張靜態的圖表
我們可以先繪製若干張靜態的圖表,然後將這幾張圖表合成一張 gif 格式的動圖即可,代碼如下
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.patheffects as fx
# 繪製圖表的函數
def make_plot(year):
# 根據年份來篩選出數據
df = data[data.Year == year]
# 製作圖表
fig, (ax1, ax2) = plt.subplots(1, 2, sharey = True)
ax1.invert_xaxis
fig.subplots_adjust(wspace = 0)
ax1.barh(df[df.Sex == 'Male'].AgeGrp, df[df.Sex == 'Male'].percent, label = 'Male')
ax2.barh(df[df.Sex == 'Female'].AgeGrp, df[df.Sex == 'Female'].percent, label = 'Female', color = 'C1')
country = df.Location.iloc[0]
ifcountry == 'United States of America': country == 'US'
fig.suptitle(f '......')
fig.supxlabel( '......')
fig.legend(bbox_to_anchor = (0.9, 0.88), loc = 'upper right')
ax1.set_ylabel( 'Age Groups')
returnfig
我們自定義了一個繪製圖表的函數,其中的參數是年份,邏輯很簡單,我們是想根據年份來篩選出數據,然後根據篩選出的數據來繪製圖表,每一年的圖表不盡相同
years = [i fori inset(data.Year) ifi < 2022]
years.sort
foryear inyears:
fig = make_plot(year)
fig.savefig(f '{year}.jpeg',bbox_inches = 'tight')
output
這樣我們就生成了若干張靜態的圖表,然後集合成 gif 格式的圖表幾個,代碼如下
import matplotlib.animation as animation
fig, ax = plt.subplots
ims = []
foryear inyears:
im = ax.imshow(plt.imread(f '{year}.jpeg'), animated = True)
ims.append([im])
ani = animation.ArtistAnimation(fig, ims, interval=600)
ani.save( 'us_population.gif')
output
還有另外一種思路
可能看到這兒,有人會覺得上面提到的方法稍顯麻煩,畢竟我們需要先生成數十張靜態的圖表,要是電腦的磁碟空間有點緊張的話,或者還沒有這樣的一個地方來存放這數十張的圖表。於是乎就會疑問道,是不是可以一步到位的來。
當然也是可以的,例如我們打算繪製1950年到2020年不同年齡階段的人口比例分布圖,首先第一步在於我們先要繪製1950年,也就是起始年,該年不同年齡階段的人口比例分布圖,代碼如下
fig, (ax1, ax2) = plt.subplots(1, 2, sharey = True)
df = data[data.Year == 1955]
y_pos = [i fori inrange(len(df[df.Sex == 'Male']))]
male = ax1.barh(y_pos, df[df.Sex == 'Male'].percent, label = 'Male',
tick_label = df[df.Sex == 'Male'].AgeGrp)
female = ax2.barh(y_pos, df[df.Sex == 'Female'].percent, label = 'Female',
color = 'C1', tick_label = df[df.Sex == 'Male'].AgeGrp)
ax1.invert_xaxis
fig.suptitle( '.......')
fig.supxlabel( '....... (%)')
fig.legend(bbox_to_anchor = (0.9, 0.88), loc = 'upper right')
ax1.set_ylabel( 'Age Groups')
output
然後我們自定義一個繪製圖表的函數,其中參數為年份,目的在於通過年份來篩選出相對應的數據並且繪製出相對應的圖表
def run(year):
# 通過年份來篩選出數據
df = data[data.Year == year]
# 針對不同地性別來繪製
total_pop = df.Value.sum
df[ 'percent'] = df.Value / total_pop * 100
male.remove
y_pos = [i fori inrange(len(df[df.Sex == 'Male']))]
male.patches = ax1.barh(y_pos, df[df.Sex == 'Male'].percent, label = 'Male',
color = 'C0', tick_label = df[df.Sex == 'Male'].AgeGrp)
female.remove
female.patches = ax2.barh(y_pos, df[df.Sex == 'Female'].percent, label = 'Female',
color = 'C1', tick_label = df[df.Sex == 'Female'].AgeGrp)
text.set_text(year)
returnmale #, female
然後我們調用 animation.FuncAnimation 方法,
ani = animation.FuncAnimation(fig, run, years, blit = True, repeat = True,
interval = 600)
ani.save( '文件名.gif')
output
這樣就可以一步到位生成 gif 格式的圖表,避免生成數十張繁多地靜態圖片了。
將若干張 gif 動圖放置在一張大圖當中
最後我們可以將若干張 gif 動圖放置在一張大的圖表當中,代碼如下
import matplotlib.animation as animation
# 創建一個新的畫布
fig, (ax, ax2, ax3) = plt.subplots(1, 3, figsize = (10, 3))
ims = []
foryear inyears:
im = ax.imshow(plt.imread(f '文件1{year}.jpeg'), animated = True)
im2 = ax2.imshow(plt.imread(f '文件2{year}.jpeg'), animated = True)
im3 = ax3.imshow(plt.imread(f '文件3{year}.jpeg'), animated = True)
ims.append([im, im2, im3])
ani = animation.ArtistAnimation(fig, ims, interval=600)
ani.save( 'comparison.gif')
output
點這裡關注我,記得標星哦~
CDA課程諮詢