目錄
- Matplotlib 可視化大師系列博客總覽
- Matplotlib 可視化大師系列(三):plt.bar() 與 plt.barh() - 清晰對比的柱狀圖
- 一、 柱狀圖是什么?何時使用?
- 二、 函數原型與核心參數
- `plt.bar(x, height, ...)` - 垂直柱狀圖
- `plt.barh(y, width, ...)` - 水平柱狀圖
- 三、 從入門到精通:代碼示例
- 示例 1:基礎垂直柱狀圖
- 示例 2:分組柱狀圖
- 示例 3:堆疊柱狀圖與水平柱狀圖
- 四、 最佳實踐與常見陷阱
- 五、 總結
Matplotlib 可視化大師系列博客總覽
本系列旨在提供一份系統、全面、深入的 Matplotlib 學習指南。以下是博客列表:
- 基礎篇:
plt.plot()
- 繪制折線圖的利刃 - 分布篇:
plt.scatter()
- 探索變量關系的散點圖 - 比較篇:
plt.bar()
與plt.barh()
- 清晰對比的柱狀圖 - 統計篇:
plt.hist()
與plt.boxplot()
- 洞察數據分布 - 占比篇:
plt.pie()
- 展示組成部分的餅圖 - 高級篇:
plt.imshow()
- 繪制矩陣與圖像的強大工具 - 專屬篇: 繪制誤差線 (
plt.errorbar()
)、等高線 (plt.contour()
) 等特殊圖表 - 綜合篇: 在一張圖中組合多種圖表類型
Matplotlib 可視化大師系列(三):plt.bar() 與 plt.barh() - 清晰對比的柱狀圖
柱狀圖是數據可視化中最常用、最有效的圖表類型之一,專門用于比較不同類別的數值。Matplotlib 提供了 plt.bar()
(垂直柱狀圖)和 plt.barh()
(水平柱狀圖)兩個函數來創建這種圖表。本文將深入解析這兩個函數,幫助你掌握創建清晰、準確對比圖表的藝術。
一、 柱狀圖是什么?何時使用?
柱狀圖使用高度(或長度)不同的矩形(柱體)來表示不同類別的數值大小。每個柱體代表一個類別,柱體的高度代表該類別的數值。
適用場景:
- 比較不同類別的數量(如不同產品的銷量)
- 顯示數據隨時間的變化(時間序列數據,但通常用于離散時間點)
- 對比分組數據
與直方圖的區別(重要!):
- 柱狀圖 (Bar Chart):比較不同類別的數值。X軸是分類變量(如城市名、產品類型)。
- 直方圖 (Histogram):顯示單個變量的分布情況。X軸是連續數值被分成的區間(bins)。
二、 函數原型與核心參數
plt.bar(x, height, ...)
- 垂直柱狀圖
plt.bar(x, height, width=0.8, bottom=None, *, align='center', **kwargs)
plt.barh(y, width, ...)
- 水平柱狀圖
plt.barh(y, width, height=0.8, left=None, *, align='center', **kwargs)
核心參數詳解:
- 定位參數:
x
/y
: 柱體中心的坐標。對于分類數據,通常是類別標簽的索引(如[0, 1, 2, 3]
)或直接是標簽(需要配合plt.xticks()
)。height
/width
: 柱體的高度(垂直)或寬度(水平),即要比較的數值。
- 尺寸參數:
width
: (垂直) 柱體的寬度,默認0.8。通常保持在0.8以下,柱體間會有清晰間隔。height
: (水平) 柱體的高度,默認0.8。bottom
/left
: 柱體的底部(垂直)或左側(水平)基準線。這是創建堆疊柱狀圖的關鍵!
- 對齊方式:
align
: 柱體與X坐標的對齊方式。'center'
(默認,中心對齊)或'edge'
(邊緣對齊)。
- 樣式參數 (
**kwargs
):color
/facecolor
/fc
: 柱體填充顏色。可以是一個顏色(所有柱體相同),也可以是一個顏色列表(每個柱體不同)。edgecolor
/ec
: 柱體邊緣顏色。linewidth
/lw
: 柱體邊緣線寬。alpha
: 透明度。label
: 用于圖例的標簽(為一組柱體設置標簽)。tick_label
: 直接指定每個柱體的刻度標簽,替代默認的x坐標。
三、 從入門到精通:代碼示例
示例 1:基礎垂直柱狀圖
import matplotlib.pyplot as plt
import numpy as np# 數據
categories = ['Apples', 'Oranges', 'Bananas', 'Grapes']
values = [15, 12, 18, 9]# 創建圖形
fig, ax = plt.subplots(figsize=(8, 5))# 繪制柱狀圖
bars = ax.bar(categories, values)# 美化
ax.set_title('Fruit Sales Comparison')
ax.set_ylabel('Quantity Sold')
ax.grid(axis='y', linestyle='--', alpha=0.7) # 只在y軸加網格線# 在柱體頂端添加數值標簽 (一個非常有用的技巧!)
for bar in bars:height = bar.get_height()ax.annotate(f'{height}',xy=(bar.get_x() + bar.get_width() / 2, height),xytext=(0, 3), # 3 points vertical offsettextcoords="offset points",ha='center', va='bottom')plt.tight_layout()
plt.show()
示例 2:分組柱狀圖
通過控制每個組的X坐標和柱體寬度,可以實現分組對比。
# 數據
labels = ['Q1', 'Q2', 'Q3', 'Q4']
sales_A = [20, 35, 30, 35]
sales_B = [25, 32, 34, 20]
sales_C = [15, 25, 40, 30]x = np.arange(len(labels)) # 標簽位置: [0, 1, 2, 3]
width = 0.25 # 柱寬fig, ax = plt.subplots(figsize=(10, 6))# 繪制三組柱體,每組柱體的x坐標偏移一個width
rects1 = ax.bar(x - width, sales_A, width, label='Product A')
rects2 = ax.bar(x, sales_B, width, label='Product B')
rects3 = ax.bar(x + width, sales_C, width, label='Product C')# 添加標簽和標題
ax.set_xlabel('Quarters')
ax.set_ylabel('Sales')
ax.set_title('Quarterly Sales by Product')
ax.set_xticks(x) # 設置x軸刻度位置
ax.set_xticklabels(labels) # 設置x軸刻度標簽
ax.legend()# 添加數值標簽
def autolabel(rects):for rect in rects:height = rect.get_height()ax.annotate('{}'.format(height),xy=(rect.get_x() + rect.get_width()/2, height),xytext=(0, 3),textcoords="offset points",ha='center', va='bottom')autolabel(rects1)
autolabel(rects2)
autolabel(rects3)fig.tight_layout()
plt.show()
示例 3:堆疊柱狀圖與水平柱狀圖
# 堆疊柱狀圖 - 使用 bottom 參數
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))# 數據
men_means = [20, 35, 30, 35]
women_means = [25, 32, 34, 20]
labels = ['Q1', 'Q2', 'Q3', 'Q4']
x = np.arange(len(labels))# 左側:堆疊柱狀圖
ax1.bar(labels, men_means, label='Men')
ax1.bar(labels, women_means, bottom=men_means, label='Women') # 關鍵:bottom=men_means
ax1.set_ylabel('Scores')
ax1.set_title('Stacked Bar Chart')
ax1.legend()# 右側:水平柱狀圖 - 非常適合類別名稱較長的情況
categories = ['Very Long Category Name A', 'Long Category Name B', 'Category C', 'D']
values = [15, 12, 18, 9]bars = ax2.barh(categories, values)
ax2.set_xlabel('Value')
ax2.set_title('Horizontal Bar Chart')
ax2.grid(axis='x', linestyle='--', alpha=0.7)# 在水平柱體右側添加數值標簽
for bar in bars:width = bar.get_width()ax2.annotate(f'{width}',xy=(width, bar.get_y() + bar.get_height()/2),xytext=(3, 0),textcoords="offset points",ha='left', va='center')plt.tight_layout()
plt.show()
四、 最佳實踐與常見陷阱
- 最佳實踐:
- 排序數據: 除非有特定順序要求(如時間),否則將柱體按高度排序,使比較更容易。
- 從零基線開始: Y軸必須從0開始,否則會扭曲數據的真實比例,誤導觀眾。
- 添加數值標簽: 在柱體頂端或末端直接標注數值,讓讀者無需猜測。
- 使用水平柱狀圖: 當類別名稱很長或類別數量很多時,水平柱狀圖可讀性更高。
- 謹慎使用顏色: 使用顏色來傳達信息(如突出特定類別),而不是隨意裝飾。
- 常見陷阱:
- 過度擁擠: 柱體太多、太窄、間距太小會讓圖表難以閱讀。考慮分組顯示或使用其他圖表類型(如折線圖)。
- 錯誤的排序: 隨意排序類別會掩蓋數據的真實模式。
- 3D效果: 避免使用3D柱狀圖,它們會扭曲感知,難以準確比較高度。
- 混淆柱狀圖和直方圖: 確保你使用的是正確的圖表類型來回答你的問題。
五、 總結
plt.bar()
和 plt.barh()
是進行數據對比的利器。
- 核心功能: 用矩形的高度/長度表示類別數值的大小。
- 關鍵參數:
x
/y
(位置),height
/width
(數值),bottom
/left
(堆疊),color
(樣式)。 - 高級應用: 分組柱狀圖、堆疊柱狀圖。
- 關鍵技巧: 添加數值標簽、排序數據、保持零基線。
掌握柱狀圖,意味著你能夠清晰、準確地展示數據之間的比較關系,這是數據故事中不可或缺的一環。在下一篇文章中,我們將深入探討數據的分布,使用 plt.hist()
和 plt.boxplot()
來揭示數據背后的統計特性。