使用Python繪製柱形競賽圖

我們經常看到的Bar Chart Race(柱形競賽圖),可以看到數據的呈現非常的直觀。今天就一起來學習下如何生成和上面一樣的柱形競賽圖。

在這裏插入圖片描述

1、導入Python庫

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import matplotlib.animation as animation
from IPython.display import HTML

2、加載數據集

這裏使用的是城市人口數據集,加載我們想要的數據:其中,name爲城市名稱,group爲城市所在區域。

df = pd.read_csv("data/city_populations.csv", usecols=['name', 'group', 'year', 'value'])
df.head()

在這裏插入圖片描述

3、初步處理數據

提取某一年的TOP10城市:

current_year = 2018
dff = df[df['year'].eq(current_year)].sort_values(by='value', ascending=True).head(10)

4、 繪製基礎柱狀圖

fig, ax = plt.subplots(figsize=(15, 8))
ax.barh(dff['name'], dff['value'])

5、 調整樣式(設置顏色、添加標籤)重新繪製圖片

'''
遇到問題沒人解答?小編創建了一個Python學習交流QQ羣:579817333 
尋找有志同道合的小夥伴,互幫互助,羣裏還有不錯的視頻學習教程和PDF電子書!
'''
colors = dict(zip(
    ["India", "Europe", "Asia", "Latin America", "Middle East", "North America", "Africa"],
    ["#adb0ff", "#ffb3ff", "#90d595", "#e48381", "#aafbff", "#f7bb5f", "#eafb50"]
))
group_lk = df.set_index('name')['group'].to_dict()
 
fig, ax = plt.subplots(figsize=(15, 8))
# pass colors values to `color=`
ax.barh(dff['name'], dff['value'], color=[colors[group_lk[x]] for x in dff['name']])
# iterate over the values to plot labels and values (Tokyo, Asia, 38194.2)
for i, (value, name) in enumerate(zip(dff['value'], dff['name'])):
    ax.text(value, i,     name,            ha='right')  # Tokyo: name
    ax.text(value, i-.25, group_lk[name],  ha='right')  # Asia: group name
    ax.text(value, i,     value,           ha='left')   # 38194.2: value
# Add year right middle portion of canvas
ax.text(1, 0.4, current_year, transform=ax.transAxes, size=46, ha='right')

在這裏插入圖片描述

6、 完善代碼,將代碼整合進函數

優化內容:

  • 文字:更新字體大小,顏色,方向
  • 軸:將X軸移到頂部,添加顏色和字幕
  • 網格:在條後面添加線
  • 格式:逗號分隔的值和座標軸
  • 添加標題,字幕,裝訂線空間
  • 刪除:框框,y軸標籤
fig, ax = plt.subplots(figsize=(15, 8))
 
def draw_barchart(year):
    dff = df[df['year'].eq(year)].sort_values(by='value', ascending=True).tail(10)
    ax.clear()
    ax.barh(dff['name'], dff['value'], color=[colors[group_lk[x]] for x in dff['name']])
    dx = dff['value'].max() / 200
    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')
    # ... polished styles
    ax.text(1, 0.4, year, transform=ax.transAxes, color='#777777', size=46, ha='right', weight=800)
    ax.text(0, 1.06, 'Population (thousands)', transform=ax.transAxes, size=12, color='#777777')
    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([])
    ax.margins(0, 0.01)
    ax.grid(which='major', axis='x', linestyle='-')
    ax.set_axisbelow(True)
    ax.text(0, 1.12, 'The most populous cities in the world from 1500 to 2018',
            transform=ax.transAxes, size=24, weight=600, ha='left')
    ax.text(1, 0, 'by @pratapvardhan; credit @jburnmurdoch', transform=ax.transAxes, ha='right',
            color='#777777', bbox=dict(facecolor='white', alpha=0.8, edgecolor='white'))
    plt.box(False)
    
draw_barchart(2018)

在這裏插入圖片描述

7、 繪製動態柱狀圖

爲了看起來像是在競賽,我們使用matplotlib.animation中的FuncAnimation來重複調用上面的函數在畫布上製作動畫。frames參數爲函數接受的值。

'''
遇到問題沒人解答?小編創建了一個Python學習交流QQ羣:579817333 
尋找有志同道合的小夥伴,互幫互助,羣裏還有不錯的視頻學習教程和PDF電子書!
'''
import matplotlib.animation as animation
from IPython.display import HTML
fig, ax = plt.subplots(figsize=(15, 8))
animator = animation.FuncAnimation(fig, draw_barchart, frames=range(1968, 2019))
HTML(animator.to_jshtml()) 
# or use animator.to_html5_video() or animator.save()

8、 額外獎勵,繪製xkcd風格的圖形

with plt.xkcd():
    fig, ax = plt.subplots(figsize=(15, 8))
    draw_barchart(2018)

原文地址:https://towardsdatascience.com/bar-chart-race-in-python-with-matplotlib-8e687a5c8a41

matplotlib 的 animations使用說明

Matplotlib中動畫實現的原理跟其它一樣,就是讓多幅圖連續播放,每一幅圖叫做一幀(frame)。

生成動畫的核心語句如下:

'''
遇到問題沒人解答?小編創建了一個Python學習交流QQ羣:579817333 
尋找有志同道合的小夥伴,互幫互助,羣裏還有不錯的視頻學習教程和PDF電子書!
'''
import matplotlib.animation as animation
from IPython.display import HTML
fig, ax = plt.subplots(figsize=(15, 8))
animator = animation.FuncAnimation(fig, draw_barchart, frames=range(1968, 2019))
HTML(animator.to_jshtml())
# or use animator.to_html5_video() or animator.save()

核心函數是animation.FuncAnimation(),接下來一起學習下如何使用此函數。

class matplotlib.animation.FuncAnimation(fig, func, frames=None, init_func=None, fargs=None, save_count=None, *, cache_frame_data=True, **kwargs)

參數說明:

  • fig:進行動畫繪製的figure
  • func:更新函數
  • frames:傳入更新函數的迭代值,即生成每一幀(frame)的參數
  • init_func:初始函數
  • fargs:傳入更新函數的額外參數
  • save_count:指定保存動畫(gif或mp4)的幀數
  • interval:指定幀間隔時間,單位是ms
  • repeat_delay:如果指定了循環動畫,則設置每次循環的間隔時間
  • repeat:指定是否循環動畫
  • blit:是否優化繪圖
  • cache_frame_data:控制是否緩存幀數據

核心方法說明:

  • save(self, filename[, writer, fps, dpi, …]):將動畫保存爲文件(gif或mp4).
  • to_html5_video(self[, embed_limit]):將動畫HTML5動畫
  • to_jshtml(self[, fps, embed_frames, …]):將動畫返回爲HTML格式
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章