Python編程實現超炫動態排序圖

用 python 制作超燃動態排序視頻

在開始之前,先貼張圖,之前網上一段時間下面這種排序風格視頻很火,下面這張圖當作是視頻其中的一幀。

制作這樣視頻的原理:就是把不同的幀組合在一起拼接成視頻;把不同時間的排序圖拼接在一起,拼接在一起形成一個隨時間快速變化的動畫,轉化成視頻,為瞭觀看效果加一首很燃的BGM,最後的效果很贊。

Snipaste_2020-02-12_09-08-19.jpg

這種視頻 python 也能做,基本上分為三大部分,主要用到的就是兩個庫函數 pandas做數據處理,matplotlib繪制表、制作視頻動畫

1,數據預處理

這一部分細分為:數據讀取,隨機生成顏色代碼,城市地區與顏色映射關系構造。

本次選取的數據為從1500年到2018年各地區的人數統計(提醒一下,是各城市所在區域人口數量)

數據源鏈接:1500-2018各地區人口數量

# 導入庫函數
import random
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import matplotlib.animation as animation
from IPython.display import HTML
import matplotlib
#防止動漫內存太大,報錯
matplotlib.rcParams['animation.embed_limit'] = 2**128

原數據是這樣的,數據之間以”,(逗號)“隔開,我們需要的隻是其中的幾列,所以這裡利用pandas 中的 usecols做一些列提取;

Snipaste_2020-02-08_13-44-59.jpg

#pandas讀取數據,且去列名分別為name,group,year和value的值;
url = 'https://gist.githubusercontent.com/johnburnmurdoch/4199dbe55095c3e13de8d5b2e5e5307a/raw/fa018b25c24b7b5f47fd0568937ff6c04e384786/city_populations'
df = pd.read_csv(url, usecols=['name', 'group', 'year', 'value'])
df.head()

因為每個地區標記一個顏色,這裡需要構造一個隨機顏色代碼生成函數:

#導入random函數,randomcolor用於生成顏色代碼
# randomcolor生成顏色代碼原理,
# 【1-9/A-F】15個數字隨機組合成6位字符串前面再加上一個“#”號鍵
import random
def randomcolor():
    colorlist = ['1','2','3','4','5','6','7','8','9','A','B','C','D','E','F']
    color =''
    for i in range(6):
        color += random.choice(colorlist)
    return '#'+ color

最後構造兩個字典:一個是城市與顏色之間的,一個是城市與所在區域(亞洲、歐洲等)之間的,

形成一一映射關系方便後續處理

#對地區列表進行去重,分類;
area_list1 = set(df['name'])
# color_list用於存放隨機生成顏色代碼個數
# 因為後面區域個數 要與顏色個數保持一致,這裡用瞭len函數;
color_list =[]
for i in range(len(area_list1)):
    str_1 = randomcolor()
    color_list.append(str_1)
    str_1 = randomcolor()    
#area_list轉化為列表
area_list_1 = [i for i in area_list1]
print(color_list)
print(area_list_1)

Snipaste_2020-02-12_10-11-07.jpg

構造映射關系:

#colors表示 所在城市:顏色 一一對應字典形式;
colors =dict(zip(area_list_1,color_list))
print(colors)
#group_lk為 城市:所在區域 --對應字典形式;
group_lk = df.set_index('name')['group'].to_dict()
print(group_lk)

Snipaste_2020-02-12_10-13-08.jpg

2,圖表繪制

這一部分主要是利用matplotlib 寫瞭一個在某一年中各地區人口分佈的直方圖繪制函數,在代碼每一步中有詳細註釋,想實現的可以參照一下代碼:

# 用plt加理圖表,figsize表示圖標長寬,ax表示標簽
fig, ax = plt.subplots(figsize=(15, 8))
#dras_barchart生成current_year這一年各城市人口基本情況;
def draw_barchart(current_year):   
    #dff對year==current_year的行,以value從升序方式排序,取後十名也就是最大值;
    dff = df[df['year'].eq(current_year)].sort_values(by='value',ascending = True).tail(12)
    # 所有坐標、標簽清除
    ax.clear()
    #顯示顏色、城市名字
    ax.barh(dff['name'],dff['value'],color = [colors[x] for x in dff['name']])
    dx = dff['value'].max()/200    
    #ax.text(x,y,name,font,va,ha)
    # x,y表示位置;
    # name表示顯示文本;
    # va,ba分別表示水平位置,垂直放置位置;
    for i ,(value,name) in enumerate(zip(dff['value'], dff['name'])):
        ax.text(value-dx,i,name,size=14,weight=600,ha ='right',va = 'bottom')
        ax.text(value-dx,i-.25,group_lk[name],size = 10,color ='#444444',ha ='right',va = 'baseline')
        ax.text(value+dx,i ,f'{value:,.0f}',size = 14,ha = 'left',va ='center')    
    #ax.transAxes表示軸坐標系,(1,0.4)表示放置位置
    ax.text(1,0.4,current_year,transform = ax.transAxes,color ='#777777',size = 46,ha ='right',weight=800) 
    ax.text(0,1.06,'Population (throusands)',transform = ax.transAxes,size=12,color='#777777')    
    #set_major_formatter表示刻度尺格式;
    ax.xaxis.set_major_formatter(ticker.StrMethodFormatter('{x:,.0f}'))
    ax.xaxis.set_ticks_position('top')
    ax.tick_params(axis='x',colors='#777777',labelsize=12)
    ax.set_yticks([])
    #margins表示自動縮放餘額;
    ax.margins(0,0.01)
    # 設置後面的網格
    ax.grid(which='major',axis='x',linestyle='-')
    #刻度線和網格線是在圖標上方還是下方,True為下方
    ax.set_axisbelow(True)
    ax.text(0,1.15,'The most population cities in the word from 1500 to 2018',
           transform=ax.transAxes,size=24,weight=600,ha='left',va='top')
    ax.text(1,0,'by@zeroing1',transform = ax.transAxes,color ='#777777',ha = 'right',
           bbox = dict(facecolor='white',alpha = 0.8,edgecolor='white'))
    #取消圖表周圍的方框顯示
    plt.box(False)

#繪制2018年各城市人口情況
draw_barchart(2018)

圖表如下:

Snipaste_2020-02-12_10-15-51.jpg

3,制作的圖表轉化為視頻、動畫

用到的功能是 matplotlib 的 animation 函數,下面這個是生成一個jshtml頁面,可以在線預覽

#將原來的靜態圖拼接成動畫
fig, ax = plt.subplots(figsize=(15, 8))
animator = animation.FuncAnimation(fig, draw_barchart, frames=range(1500, 2019))
#保存到jshtml
HTML(animator.to_jshtml())

展示效果如下:

end_imag.gif

當然,也可以直接生成視頻保存到本地,但在此之前請確保你的電腦已經配置好 FFmpeg,然後運行下面的代碼,否則的話無法生成

#生成video,並保存至指定文件夾中
animator.to_html5_video()
animator.save('E:/ceshi/country_populations1.mp4')

Snipaste_2020-02-12_10-38-52.jpg

然後可以加上合適的背景音樂,一個超燃的動態排序視頻就完成瞭!

以上就是Python編程實現超炫動態排序圖的詳細內容,更多關於Python實現動態排序圖的資料請關註WalkonNet其它相關文章!

推薦閱讀: