用Python繪製超酷的gif動圖,驚艷了所有人

2022-05-13     CDA數據分析師

原標題:用Python繪製超酷的gif動圖,驚艷了所有人

作者:俊欣

來源:關於數據分析與可視化

在之前的一篇文章當中,小編當時分享了如何用 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課程諮詢

文章來源: https://twgreatdaily.com/zh-tw/de46d971d1198787578944df0a730908.html