Python 圓餅圖/環狀圖/放射環狀圖(Pie/Donut/Sunburst Charts)

Photo by Ram HO 🇲🇽 on Unsplash
圓餅圖(Pie charts)/環狀圖(Donut charts)/放射環狀圖(Sunburst Charts)常用於描述數量或百分比之間的相對關係。我們將介紹如何利用 Python 的 Matplotlib 和 Plotly Express 套件來繪製圓餅圖。

圓餅圖(Pie charts)環狀圖(Donut charts)放射環狀圖(Sunburst Charts)常用於描述數量或百分比之間的相對關係。我們將介紹如何利用 Python 的 Matplotlib 和 Plotly Express 套件來繪製圓餅圖。

由於 Seaborn 並沒有提供繪製圓餅圖的方法,因此我們在此篇文章中不會介紹 Seaborn。

完整程式碼可以在 下載。

Matplotlib

Matplotlib 的 pie() 讓我們很簡單地就可以繪製圓餅圖。它的宣告如下,其餘的參數請參照官網。

matplotlib.pyplot.pie(x, 
                      explode=None, 
                      labels=None, 
                      colors=None, 
                      autopct=None, 
                      data=None)
  • x:1 維的資料。
  • explode:每個扇形的位移。型態為 array-like。
  • labels:每個區塊的標題。型態為 array-like。
  • colors:每個區塊的顏色。型態為 array-like。
  • autopct:區塊裡面的百分比的格式。型態為 string。
  • data:資料。如果傳遞資料給參數 data 時,則參數 x、explode、labels、和 colors 會是 data 的 column 名稱。

Pie Charts

pie() 使用起來相當地簡單,讓我們來看看下面的範例。

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame([
    ['Czech Republic', 10228744], ['France', 61083916], ['Germany', 82400996],
    ['Greece', 10706290], ['Italy', 58147733], ['Netherlands', 16570613],
    ['Poland', 38518241], ['Portugal', 10642836], ['Romania', 22276056],
    ['Spain', 40448191], ['Turkey', 71158647], ['United Kingdom', 60776238]],
    columns=['country', 'pop'])

plt.pie(df['pop'], labels=df['country'], autopct='%1.2f%%')
plt.title('Population')
plt.show()
Matplotlib pie chart
Matplotlib pie chart

範例中,我們傳入人口數與國家名稱給 pie(),並且指定顯示百分比的格式。pie() 會自動加總所有的人口數,並且計算百分比。

如果我們想要讓某個區塊分裂出去的話,可以在參數 explode 為每個區塊加上位移。下面的範例顯示如何使用區塊 explode。

explode = [0] * len(df)
explode[9] = 0.2

plt.pie(df['pop'], labels=df['country'], autopct='%1.2f%%', explode=explode)
plt.title('Population')
plt.show()
Matplotlib pie chart with explode
Matplotlib pie chart with explode

Donut Charts

環狀圖(Donut charts)是圓餅圖的一種變形。其實也就是挖掉圓餅圖的中心。我們可以利用 pie() 來繪製環狀圖,範例如下。

fig, ax = plt.subplots()
size = 0.4
ax.pie(df['pop'], labels=df['country'],
       radius=1-size, wedgeprops=dict(width=size, edgecolor='w'))
plt.title('Population')
plt.show()
Matplotlib donut chart
Matplotlib donut chart

我們是利用 pie() 的參數 radius 和 wedgeprops 來繪製環狀圖。參數 radius 是指圓餅圖的半徑。而,參數 wedgeprops 是設定每個區塊的參數。width 參數是用來設定區塊的半徑。區塊的詳細參數可以參考 Wedge

所以,在範例中,我們將圓餅的半徑設定為 0.6(1 – 0.4),而區塊的半徑則設定為 0.4。兩個總和為 1。如果我們不設定參數 radius 的話,則圓心空白的半徑會為 1,那會比目前的大很多。

Sunburst Charts

放射環狀圖(Sunburst charts)也是圓餅圖的一種變形。下面的範例顯示如何用 pie() 來繪製放射環狀圖。

df = pd.DataFrame([
    ['France', 61083916, 'Europe'], ['Germany', 82400996, 'Europe'], ['Italy', 58147733, 'Europe'],
    ['Spain', 40448191, 'Europe'], ['United Kingdom', 60776238, 'Europe'], ['Taiwan', 23174294, 'Asia'],
    ['Japan', 127467972, 'Asia'], ['Korean', 49044790, 'Asia'], ['China', 1318683096, 'Asia']],
    columns=['country', 'pop', 'continent'])
europe_sum = df[df['continent']=='Europe']['pop'].sum()
asia_sum = df[df['continent']=='Asia']['pop'].sum()

fig, ax = plt.subplots()

size = 0.4

ax.pie(df['pop'], labels=df['country'],
       autopct='%1.2f%%', pctdistance=0.8,
       radius=1, wedgeprops=dict(width=size, edgecolor='w'))

ax.pie([europe_sum, asia_sum], labels=['Europe', 'Asia'], labeldistance=0.2,
       autopct='%1.2f%%', pctdistance=0.6,
       radius=1-size, wedgeprops=dict(width=size, edgecolor='w'))

plt.title('Population')
plt.show()
Matplotlib sunburst chart
Matplotlib sunburst chart

此範例是利用兩個環狀圖來組合成一個放射環狀圖。在組合時,外層的環狀圖會和內層環狀圖的標籤發生重疊,所以我們要手動將標籤移至比較好看的地方。參數 labeldistance 是用來調整標籤的位移;而參數 pctdistance 則是調整百分比的位移。

Plotly Express

Plotly Express 的 pie() 可以用來繪製圓餅圖。讓我們先來看看它的宣告,其餘的參數請參照官網。

plotly.express.pie(data_frame=None, 
                   names=None, 
                   values=None,
                   title=None, 
                   hole=None)
  • data_frame:資料。型態為 DataFrame、array-like、或 dict。
  • names:每個區塊的標籤。型態為 data_frame 的 column 名稱、或 array-like。
  • values:每個區塊的值。型態為 data_frame 的 column 名稱、或 array-like。
  • title:圖表的標題。
  • hole:空白圓心的半徑。

Pie Charts

與 Matplotlib 的 pie() 相似,Plotly Express 的 pie() 使用起來相當地簡便,其範例如下。

import pandas as pd
import plotly.express as px

df = pd.DataFrame([
    ['Czech Republic', 10228744], ['France', 61083916], ['Germany', 82400996],
    ['Greece', 10706290], ['Italy', 58147733], ['Netherlands', 16570613],
    ['Poland', 38518241], ['Portugal', 10642836], ['Romania', 22276056],
    ['Spain', 40448191], ['Turkey', 71158647], ['United Kingdom', 60776238]],
    columns=['country', 'pop'])

fig = px.pie(df, values='pop', names='country', title='Population')
fig.show()
Plotly Express pie chart
Plotly Express pie chart

Plotly Express 繪製出來的圓餅圖相當地好看,而且還自動為我們加上分類欄。另外,我們注意到當顏色比較深的時候,它還會自動將字的顏色換成白色。與 Matplotlib 相比,它的百分比位置比較好。

下個範例是顯示如何在每個區塊中顯示標籤。

fig = px.pie(df, values='pop', names='country', title='Population')
fig.update_traces(textposition='inside', textinfo='percent+label', insidetextorientation='radial')
fig.show()
Plotly Express pie chart with labels inside
Plotly Express pie chart with labels inside

範例利用 update_traces() 來設定區塊裡字的格式。參數 textposition 設定將標籤顯示在區塊裡。參數 textinfo 設定格式為標籤加上百分比。參數 insidetextorientation 則是設定字的方向。這些參數可以參照 Pie。此外,我們還注意到,當區塊很小時,它也會自動地調整字的大小,相當地人性化。

下面的範例顯示如何將某個區塊分裂出來。

import plotly.graph_objects as go

pull = [0] * len(df)
pull[9] = 0.2

fig = go.Figure(data=[go.Pie(labels=df['country'], values=df['pop'], pull=pull)])
fig.show()
Plotly Express pie chart with explode
Plotly Express pie chart with explode

雖然說程式碼並沒有太複雜,但是與 Matplotlib 相比,想要讓某個區塊分裂出來的確複雜了一點。我們必須要先建立一個 Pie 的圖形物件,因為 Pie() 有更多的參數可用。我們用參數 pull 來設定每個區塊的位移。

官方文章提供很多繪製圓餅圖的範例。

Donut Charts

接下來讓我們來看 Plotly Express 如何繪製環狀圖。

fig = px.pie(df, values='pop', names='country', title='Population', hole=.3)
fig.show()
Plotly Express donut chart
Plotly Express donut chart

與 Matplotlib 相比,這實在是太簡單了。我們只需要設定參數 hole 的大小就可以了!

Sunburst Charts

Plotly Express 的 sunburst 是用來繪製放射環狀圖。它的宣告如下,其他的參數請參照官網。

plotly.express.sunburst(data_frame=None, 
                        names=None, 
                        values=None, 
                        parents=None, 
                        title=None,)
  • data_frame:資料。型態為 DataFrame、array-like、或 dict。
  • names:每個區塊的標籤。型態為 data_frame 的 column 名稱、或 array-like。
  • values:每個區塊的值。型態為 data_frame 的 column 名稱、或 array-like。
  • parents:每個區塊的 parent。型態為 data_frame 的 column 名稱、或 array-like。
  • title:圖表的標題。

大致與 pie() 相似,讓我們先來看一下範例。

df = pd.DataFrame([
    ['Europe', 586098529, 'Total'], ['Asia', 3811953827, 'Total'],
    ['France', 61083916, 'Europe'], ['Germany', 82400996, 'Europe'], ['Italy', 58147733, 'Europe'],
    ['Spain', 40448191, 'Europe'], ['United Kingdom', 60776238, 'Europe'], ['Taiwan', 23174294, 'Asia'],
    ['Japan', 127467972, 'Asia'], ['Korean', 49044790, 'Asia'], ['China', 1318683096, 'Asia']],
    columns=['country', 'pop', 'continent'])
fig = px.sunburst(df, names='country', values='pop', parents='continent', title='Population')
fig.show()
Plotly Express sunburst chart
Plotly Express sunburst chart

參數 parent 是指定每個區塊的 parent,整體就會像是一個樹狀結構。

與 Matplotlib 相比起來,Plotly Express 的 sunburst() 相當地簡單。而且,它還可以繪製只有部分區塊的外層區塊。

官方文章提供很多繪製放射環狀圖的範例。

結論

我們介紹了兩套繪製圓餅圖的套件。如果你只是要繪製一般的圓餅圖,Matplotlib 就已經很夠用了,而且還相當地簡單。但,如果你希望有互動式的工具列,或是希望產生更漂亮的圖表,那 Plotly Express 可以很輕鬆地辦到。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

You May Also Like