HOWTO · Seaborn
如何建立 Seaborn 餅圖
使用 Matplotlib 的 plt.pie 和 Seaborn 顏色調色盤建立餅圖,然後加入標籤、百分比、間距和樣式。
本頁內容
在 Python 中建立餅圖的方法是:用 Matplotlib 的 plt.pie 繪製,並用 Seaborn 的 sns.color_palette 選擇切片顏色。Seaborn 不提供自己的餅圖函式;在這個流程中,這兩個庫各自承擔不同的角色,因為 Seaborn 提供顏色,而 Matplotlib 繪製圖表。您需要同時安裝這兩個庫(pip install matplotlib seaborn)。下面的範例為幾個類別使用數值,為每個切片加入標籤並顯示其佔整體的份額;第二個範例將圖表改造成帶圖例的環形圖;最後一個範例展示當標籤與數值不匹配時 Matplotlib 引發的錯誤。
在 Seaborn 中建立餅圖
import matplotlib.pyplot as plt
import seaborn as sns
values = [35, 21, 29, 39, 11]
labels = ["A", "B", "C", "D", "E"]
colors = sns.color_palette("pastel", n_colors=len(values))
explode = [0.08, 0, 0, 0, 0]
plt.pie(
values,
labels=labels,
colors=colors,
autopct="%1.1f%%",
explode=explode,
startangle=90,
counterclock=False,
textprops={"fontsize": 10},
wedgeprops={"linewidth": 1, "edgecolor": "white"},
)
plt.show()
這段程式碼產生上圖所示的圖表。五個值的總和為 135,因此切片上列印的百分比分別為:A 為 25.9%,B 為 15.6%,C 為 21.5%,D 為 28.9%,E 為 8.1%。由於 explode 偏移,切片 A 與其餘切片略微分開。
讓值和標籤按位置對齊:第一個標籤命名第一個值,第二個標籤命名第二個值,依此類推。使用描述一個整體各部分的數值清單,例如按類別統計的數量。百分比由這些數量計算得出,因此它們描述的是每個類別的份額,而不是單獨提供的百分比。
作為 values 傳入的清單決定了每個切片的相對大小。plt.pie 繪製圖表,而 sns.color_palette 返回切片的顏色。調色盤名稱是一個字串;將 "pastel" 改為其他 Seaborn 調色盤,例如 "deep"、"muted"、"colorblind"、"bright" 或 "dark"。根據資料長度設定 n_colors,即可為每個值請求一種顏色。
labels 清單按與值相同的順序提供類別名稱。autopct 格式顯示每個值佔所有值總和的百分比;例如,"%1.1f%%" 將百分比格式化為小數點後一位。使用不同的格式字串可更改顯示精度。標籤標識類別,而百分比使它們的比例易於比較。
若要在視覺上分離切片,請向 explode 傳遞一個與每個值對應一項的序列。每一項控制相應切片的偏移,因此第一個 0.08 將類別 A 向外移動,其餘的零則讓它們的切片保持原位。調整這些項以強調不同的類別,或全部使用零以獲得無偏移的圖表。
自訂餅圖
您可以使用更多的 plt.pie 引數調整圖表的方向和外觀。startangle 旋轉起始位置,counterclock=False 設定切片繪製的方向。使用 shadow=True 加入陰影,使用 textprops 設定標籤和百分比文字的屬性,使用 wedgeprops 設定切片邊界的樣式。一個有用的 wedgeprops 設定是 width:它將每個楔形向邊緣收縮,把餅圖變成環形圖,如下一個範例所示。其他引數包括:加入座標軸邊框的 frame=True、放置餅圖中心的 center=(x, y),以及讓標籤沿其切片旋轉的 rotatelabels=True;這些布林選項採用不帶引號的 Python 值 True 或 False。
import matplotlib.pyplot as plt
import seaborn as sns
values = [58, 33, 6, 3]
labels = ["Desktop", "Mobile", "Tablet", "Other"]
colors = sns.color_palette("colorblind", n_colors=len(values))
wedges, texts = plt.pie(
values,
colors=colors,
startangle=90,
counterclock=False,
wedgeprops={"width": 0.45, "linewidth": 1, "edgecolor": "white"},
)
plt.legend(wedges, labels, title="Device", loc="center left", bbox_to_anchor=(1, 0.5))
plt.title("Sessions by Device")
plt.show()
在這裡,wedgeprops={"width": 0.45, ...} 只保留每個楔形外側的 45%,從而使中心留空。由於這次切片沒有標籤,plt.pie 返回楔形物件,將它們與標籤清單一起傳遞給 plt.legend,即可在圖表旁邊建立圖例。plt.title 加入標題。當類別名稱很長或有幾個切片很細時,圖例比切片上的標籤更易讀;範例資料的總和為 100,因此各段的大小可以直接讀作百分比(58%、33%、6% 和 3%)。
避免長度和數值錯誤
每個按切片傳遞的引數都必須與資料匹配:labels、explode 和顏色清單都必須為每個值恰好提供一項,並且每個值都必須為非負數,因為切片不可能佔整體的負份額。如果長度不一致,plt.pie 會引發 ValueError 並停止,而不是繪製圖表:
import matplotlib.pyplot as plt
values = [35, 21, 29]
labels = ["A", "B"]
plt.pie(values, labels=labels)
plt.show()
輸出:
ValueError: 'labels' must be of length 'x', not 2
修正方法是為 labels 提供與三個值一一對應的項。同樣的規則適用於 explode:為三個值提供只有兩項的 explode 清單會引發 ValueError: 'explode' must be of length 'x', not 2。values 中的負數項同樣會失敗,並引發 ValueError: Wedge sizes 'x' must be non negative values。最後,請讓類別數量保持較少:切片過多過細時,標籤會相互碰撞,份額也難以比較,因此請將次要類別歸入一個 “Other” 切片,或改用條形圖。