【Python 筆記】Matplotlib Pyplot 套件應用(下)
感謝您點進本篇文章,我是 LukeTseng,該系列主要以筆記加上口語白話形式學習 Python,若文章某處有誤敬請告知,非常感謝。
繪製長條圖以及橫條圖
plt.bar():繪製長條圖。plt.barh():繪製橫條圖。其中 h 是 horizontal 的意思。
plt.bar() 的語法如下:
1 2
| plt.bar(x, height, width=0.8, bottom=None, align='center', color=None, edgecolor=None, linewidth=None, label=None, alpha=None)
|
x: x 軸的座標位置(可以是數字或類別)height: 長條的高度(數值大小)width: 長條的寬度,預設為 0.8(範圍 0~1)bottom: 長條的起始位置,預設為 0(y 軸起始座標)align: 對齊方式,’center’(中心對齊)或 ‘edge’(邊緣對齊)color: 長條的顏色edgecolor: 邊框顏色linewidth: 邊框線寬label: 圖例標籤alpha: 透明度(0~1)
plt.barh() 的語法如下:
1 2
| plt.barh(y, width, height=0.8, left=None, align='center', color=None, edgecolor=None, linewidth=None, label=None, alpha=None)
|
參數基本上跟 plt.bar() 相同,就不講了,重點是參數基本上就是 plt.bar() 跟它對調而已,x 變成 y,width 變成 height 等等。
範例 1:繪製簡單長條圖。(數據僅供參考,教學展示用)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import matplotlib.pyplot as plt import numpy as np
plt.rcParams['font.sans-serif'] = ['DFKai-sb'] plt.rcParams['axes.unicode_minus'] = False
cities = ['台北', '台中', '台南', '高雄', '新竹'] population = [260, 280, 188, 277, 450] x = np.arange(len(cities))
plt.bar(x, population, width=0.6, color='steelblue', edgecolor='black', linewidth=1.5)
plt.xlabel('城市') plt.ylabel('人口密度(萬)') plt.title('各城市人口密度比較') plt.xticks(x, cities)
plt.show()
|
Output:

範例 2:繪製簡單橫條圖。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import matplotlib.pyplot as plt import numpy as np
subjects = ['國文', '英文', '數學', '自然', '社會'] scores = [85, 92, 78, 88, 90] y = np.arange(len(subjects))
plt.barh(y, scores, height=0.5, color='coral', alpha=0.8)
plt.xlabel('分數') plt.ylabel('科目') plt.title('各科成績表現') plt.yticks(y, subjects)
plt.show()
|
Output:

範例 3:並列長條圖(比較兩組資料)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import matplotlib.pyplot as plt import numpy as np
categories = ['Q1', 'Q2', 'Q3', 'Q4'] sales_2023 = [120, 150, 180, 200] sales_2024 = [140, 160, 190, 220]
x = np.arange(len(categories)) bar_width = 0.35
plt.bar(x - bar_width/2, sales_2023, bar_width, label='2023年', color='skyblue') plt.bar(x + bar_width/2, sales_2024, bar_width, label='2024年', color='orange')
plt.xlabel('季度') plt.ylabel('銷售額(萬元)') plt.title('2023 vs 2024 季度銷售比較') plt.xticks(x, categories) plt.legend()
plt.show()
|
Output:

並列長條圖透過調整 x 座標位置(x - bar_width/2 和 x + bar_width/2)來讓兩組資料並排顯示。
範例 4:堆疊長條圖。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import matplotlib.pyplot as plt import numpy as np
months = ['1月', '2月', '3月', '4月'] online_sales = [50, 60, 70, 80] offline_sales = [30, 35, 40, 45]
x = np.arange(len(months))
plt.bar(x, online_sales, label='線上銷售', color='#3498db') plt.bar(x, offline_sales, bottom=online_sales, label='實體銷售', color='#e74c3c')
plt.xlabel('月份') plt.ylabel('銷售額(萬元)') plt.title('線上與實體銷售堆疊圖') plt.xticks(x, months) plt.legend()
plt.show()
|
Output:

範例 5:新增資料標籤在長條圖頂端。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import matplotlib.pyplot as plt import numpy as np
products = ['筆電', '手機', '平板', '耳機'] quantities = [45, 78, 52, 65] x = np.arange(len(products))
bars = plt.bar(x, quantities, color=['#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A'], edgecolor='black', linewidth=2)
for i, (xi, yi) in enumerate(zip(x, quantities)): plt.text(xi, yi + 2, str(yi), ha='center', va='bottom', fontsize=12, fontweight='bold')
plt.xlabel('產品類別') plt.ylabel('銷售數量') plt.title('各產品銷售數量統計') plt.xticks(x, products) plt.ylim(0, max(quantities) + 15)
plt.show()
|
Output:

繪製圓餅圖
要繪製圓餅圖,則使用 plt.pie() 函式來進行繪製,以下是他的語法:
1 2 3 4 5
| plt.pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, startangle=0, radius=1, counterclock=True, wedgeprops=None, textprops=None, center=(0, 0), frame=False, rotatelabels=False, normalize=True)
|
基本參數:
x:一維陣列,表示每個扇形的數值大小(必填參數)。labels:字串列表,為每個扇形提供標籤。colors:顏色序列,指定每個扇形的顏色。autopct:字串或函數,在扇形內顯示百分比(如 '%1.1f%%')。explode:陣列,指定每個扇形與圓心的偏移距離。
位置與樣式參數:
pctdistance:百分比文字距離圓心的比例(預設 0.6)。labeldistance:標籤距離圓心的比例(預設 1.1)。startangle:起始角度,逆時針從 x 軸開始旋轉(預設 0)。shadow:布林值,是否顯示陰影效果。radius:圓餅圖的半徑大小(預設 1)。
進階參數:
wedgeprops:字典,設定扇形屬性(如邊框寬度、顏色)。textprops:字典,設定文字屬性(如字體大小、顏色)。counterclock:布林值,是否逆時針排列(預設 True)。rotatelabels:布林值,是否旋轉標籤以配合扇形角度。
只能說參數真他媽多,不過來看範例 1:
1 2 3 4 5 6 7 8 9 10
| import matplotlib.pyplot as plt
subjects = ['國文', '英文', '數學', '社會', '自然'] scores = [85, 92, 78, 88, 95]
plt.pie(scores, labels=subjects) plt.title('各科成績分布') plt.show()
|
Output:

範例 2:顯示百分比。
1 2 3 4 5 6 7 8 9 10
| import matplotlib.pyplot as plt
subjects = ['國文', '英文', '數學', '社會', '自然'] scores = [85, 92, 78, 88, 95]
plt.pie(scores, labels=subjects, autopct='%1.1f%%') plt.title('各科成績分布') plt.show()
|
Output:

範例 3:美化效果,添加顏色和陰影。
1 2 3 4 5 6 7 8 9 10 11 12
| import matplotlib.pyplot as plt
categories = ['行動裝置', '筆記型電腦', '桌上型電腦', '平板電腦'] market_share = [45, 30, 15, 10] colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A']
plt.pie(market_share, labels=categories, colors=colors, autopct='%1.1f%%', shadow=True, startangle=90) plt.title('市場佔有率分析') plt.show()
|
Output:

範例 4:凸顯效果,就是單獨把某一個扇形稍微拿出來一下。
1 2 3 4 5 6 7 8 9 10 11 12 13
| import matplotlib.pyplot as plt
transport = ['汽車', '機車', '公車', '捷運', '腳踏車'] usage = [30, 25, 20, 15, 10] explode = (0, 0.1, 0, 0.2, 0) colors = ['gold', 'lightcoral', 'lightskyblue', 'lightgreen', 'plum']
plt.pie(usage, labels=transport, explode=explode, colors=colors, autopct='%1.1f%%', shadow=True, startangle=140) plt.title('通勤方式分布') plt.show()
|
Output:

範例 5:繪製甜甜圈圖,就是圓餅圖然後中空這樣。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import matplotlib.pyplot as plt
languages = ['Python', 'JavaScript', 'Java', 'C++', 'Go'] popularity = [40, 25, 20, 10, 5] colors = ['#3498db', '#f39c12', '#e74c3c', '#9b59b6', '#1abc9c']
wedgeprops = {'width': 0.4, 'edgecolor': 'white', 'linewidth': 2}
plt.pie(popularity, labels=languages, colors=colors, autopct='%1.1f%%', startangle=90, wedgeprops=wedgeprops) plt.title('程式語言使用率') plt.show()
|
Output:

範例 6:自訂百分比顯示格式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import matplotlib.pyplot as plt import numpy as np
products = ['筆電', '手機', '耳機', '滑鼠', '鍵盤'] sales_amount = [120000, 85000, 35000, 15000, 25000]
def make_autopct(values): def my_autopct(pct): total = sum(values) val = int(round(pct*total/100.0)) return f'{pct:.1f}%\n(${val:,})' return my_autopct
plt.figure(figsize=(10, 7)) plt.pie(sales_amount, labels=products, autopct=make_autopct(sales_amount), startangle=90, textprops={'fontsize': 11, 'weight': 'bold'}) plt.title('產品銷售金額分析', fontsize=14, weight='bold') plt.show()
|
Output:

範例 7:新增圖例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import matplotlib.pyplot as plt
ages = ['18-25歲', '26-35歲', '36-45歲', '46-55歲', '56歲以上'] population = [15, 28, 32, 18, 7] colors = ['#FF6B9D', '#C44569', '#FFC048', '#16A085', '#2C3E50']
plt.figure(figsize=(10, 6)) wedges, texts, autotexts = plt.pie(population, colors=colors, autopct='%1.1f%%', startangle=90, textprops={'fontsize': 12})
plt.legend(wedges, ages, title='年齡層', loc='center left', bbox_to_anchor=(1, 0, 0.5, 1)) plt.title('顧客年齡分布', fontsize=14) plt.tight_layout() plt.show()
|
Output:

範例 8:多個圓餅圖比較,這部分用到 subplot() 函式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import matplotlib.pyplot as plt
categories = ['線上課程', '實體課程', '混合模式'] year_2023 = [30, 50, 20] year_2024 = [45, 35, 20]
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
ax1.pie(year_2023, labels=categories, autopct='%1.1f%%', startangle=90, colors=['#FF6B6B', '#4ECDC4', '#45B7D1']) ax1.set_title('2023年授課方式分布', fontsize=12, weight='bold')
ax2.pie(year_2024, labels=categories, autopct='%1.1f%%', startangle=90, colors=['#FF6B6B', '#4ECDC4', '#45B7D1']) ax2.set_title('2024年授課方式分布', fontsize=12, weight='bold')
plt.tight_layout() plt.show()
|
Output:

繪製直方圖
使用 plt.hist() 函式,語法如下:
1 2 3 4
| plt.hist(x, bins=None, range=None, density=False, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=False, color=None, label=None, stacked=False, **kwargs)
|
主要參數:
x:必填參數,要繪製直方圖的數據(可以是列表、NumPy 陣列或多組數據)。bins:(一條一條的數量)箱子的數量或箱子邊界,可以是整數(如 20)或序列(如 [10][11][8]),預設為自動計算。range:元組,指定數據範圍 (min, max),超出範圍的值會被忽略。density:布林值,如果為 True,會將直方圖標準化成機率密度,使總面積為 1(預設 False)。weights:權重陣列,與 x 相同形狀,用於加權統計。
樣式參數:
histtype,直方圖類型有以下選項可選:
'bar':傳統長條圖(預設)。'barstacked':堆疊長條圖。'step':只顯示邊界線。'stepfilled':填充的階梯圖。
其他樣式參數:
color:設定顏色。edgecolor:設定邊框顏色。alpha:透明度(0~1)。rwidth:長條相對寬度(相對於箱子寬度的比例)。
進階參數:
cumulative:布林值,如果為 True,繪製累積分布圖。orientation:'vertical'(垂直,預設)或 'horizontal'(水平)。log:布林值,是否使用對數刻度。align:對齊方式,'left'、'mid'(預設)、'right'。stacked:布林值,多組數據是否堆疊顯示。
回傳值:
函數回傳 (n, bins, patches) 元組:
n:每個箱子的計數值。bins:箱子的邊界值。patches:圖形物件列表。
範例 1:簡單直方圖。
1 2 3 4 5 6 7 8 9 10 11 12
| import matplotlib.pyplot as plt import numpy as np
scores = np.random.normal(70, 15, 1000)
plt.hist(scores, bins=50, color='skyblue', edgecolor='black') plt.xlabel('成績') plt.ylabel('學生人數') plt.title('期末考成績分布') plt.show()
|
Output:

範例 2:設定數據範圍。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import matplotlib.pyplot as plt import numpy as np
heights = np.random.normal(170, 10, 1000)
plt.hist(heights, bins=25, range=(150, 190), color='lightgreen', edgecolor='darkgreen', linewidth=1.2) plt.xlabel('身高(公分)') plt.ylabel('人數') plt.title('成年人身高分布(150-190cm)') plt.grid(axis='y', alpha=0.3) plt.show()
|
Output:

範例 3:多組數據比較。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import matplotlib.pyplot as plt import numpy as np
class_A = np.random.normal(75, 10, 200) class_B = np.random.normal(70, 12, 200) class_C = np.random.normal(80, 8, 200)
plt.hist(class_A, bins=20, alpha=0.6, label='A 班', color='red') plt.hist(class_B, bins=20, alpha=0.6, label='B 班', color='blue') plt.hist(class_C, bins=20, alpha=0.6, label='C 班', color='green')
plt.xlabel('成績') plt.ylabel('學生人數') plt.title('三個班級成績分布比較') plt.legend() plt.grid(axis='y', alpha=0.3) plt.show()
|
Output:

範例 4:堆疊直方圖。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import matplotlib.pyplot as plt import numpy as np
male_spending = np.random.gamma(5, 200, 500) female_spending = np.random.gamma(6, 180, 500)
plt.hist([male_spending, female_spending], bins=25, stacked=True, label=['男性', '女性'], color=['#3498db', '#e74c3c'], edgecolor='white')
plt.xlabel('消費金額(元)') plt.ylabel('顧客人數') plt.title('不同性別消費金額分布(堆疊)') plt.legend() plt.show()
|
Output:

範例 5:不同直方圖的效果展示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import matplotlib.pyplot as plt import numpy as np
data = np.random.normal(50, 10, 500)
fig, axes = plt.subplots(2, 2, figsize=(12, 10)) types = ['bar', 'barstacked', 'step', 'stepfilled'] colors = ['skyblue', 'coral', 'green', 'purple']
for ax, histtype, color in zip(axes.flatten(), types, colors): ax.hist(data, bins=20, histtype=histtype, color=color, edgecolor='black', alpha=0.7) ax.set_title(f'histtype = "{histtype}"', fontsize=12, weight='bold') ax.set_xlabel('數值') ax.set_ylabel('頻率')
plt.tight_layout() plt.show()
|
Output:

範例 6:水平直方圖。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import matplotlib.pyplot as plt import numpy as np
overtime_hours = np.random.gamma(3, 2, 300)
plt.hist(overtime_hours, bins=20, orientation='horizontal', color='orange', edgecolor='darkorange', alpha=0.8)
plt.xlabel('員工人數') plt.ylabel('加班時數') plt.title('員工每月加班時數分布') plt.grid(axis='x', alpha=0.3) plt.show()
|
Output:

繪製散佈圖
使用 plt.scatter() 函式,語法如下:
1 2 3 4
| plt.scatter(x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, edgecolors=None, plotnonfinite=False, data=None, **kwargs)
|
核心參數:
x, y:必填參數,數據點的座標位置(可以是列表、NumPy 陣列等陣列型態)。s:標記點的大小,單位是 points²(印刷點的平方,1 point = 1/72 英吋),可以是單一數值或陣列。c:標記點的顏色,可以是單一顏色、顏色陣列或數值序列(配合 colormap 使用)。marker:標記點的形狀,預設為 'o'(圓形)。
顏色映射參數:
cmap:顏色映射表名稱(如 'viridis'、'plasma'、'coolwarm'),用於將數值映射到顏色。vmin, vmax:顏色縮放的最小值和最大值,與 cmap 配合使用。norm:正規化物件,用於將數據值縮放到顏色映射範圍。
樣式參數:
alpha:透明度,範圍 0~1(0 為完全透明,1 為完全不透明)。linewidths:標記點邊框的寬度。edgecolors:標記點邊框的顏色。label:圖例標籤。
範例 1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import matplotlib.pyplot as plt import numpy as np
study_hours = np.array([2, 3, 5, 6, 8, 9, 10, 4, 7, 8]) exam_scores = np.array([55, 60, 75, 78, 88, 90, 95, 68, 85, 89])
plt.scatter(study_hours, exam_scores) plt.xlabel('讀書時間(小時)') plt.ylabel('考試成績') plt.title('讀書時間與考試成績的關係') plt.grid(True, alpha=0.3) plt.show()
|
Output:

範例 2:使用不同標記形狀。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import matplotlib.pyplot as plt import numpy as np
male_height = np.array([170, 175, 168, 180, 172, 178]) male_weight = np.array([65, 70, 62, 78, 68, 75]) female_height = np.array([160, 165, 158, 162, 170, 163]) female_weight = np.array([50, 55, 48, 52, 60, 54])
plt.scatter(male_height, male_weight, s=80, c='blue', marker='s', label='男生', alpha=0.6) plt.scatter(female_height, female_weight, s=80, c='red', marker='^', label='女生', alpha=0.6)
plt.xlabel('身高(公分)') plt.ylabel('體重(公斤)') plt.title('身高與體重關係(依性別分類)') plt.legend() plt.grid(True, alpha=0.3) plt.show()
|
Output:

總結
長條圖與橫條圖
plt.bar(x, height, ...) → 垂直長條圖plt.barh(y, width, ...) → 水平長條圖(horizontal)
參數:
| 參數 | 說明 |
|---|
x / y | 座標位置(類別或數值) |
height / width | 長條高度或寬度 |
color | 長條顏色 |
edgecolor / linewidth | 邊框顏色與寬度 |
alpha | 透明度 |
bottom / left | 起始位置(可用於堆疊) |
label | 圖例標籤 |
align | 'center' 或 'edge' |
圓餅圖
1
| plt.pie(x, labels=None, colors=None, autopct=None, explode=None, startangle=0, shadow=False, wedgeprops=None, ...)
|
| 類別 | 參數 | 說明 |
|---|
| 基本 | x | 數值大小(必填) |
| 標籤 | labels / labeldistance | 扇形名稱與距離 |
| 顏色 | colors | 顏色列表 |
| 百分比 | autopct | 百分比顯示格式(如 %1.1f%%) |
| 爆炸 | explode | 突顯特定扇形 |
| 起始角 | startangle | 起始角度(預設 0) |
| 陰影 | shadow | 是否加陰影 |
| 半徑 | radius | 圓餅半徑大小 |
| 美化 | wedgeprops / textprops | 扇形與文字樣式 |
直方圖(Histogram)
1
| plt.hist(x, bins=None, range=None, density=False, stacked=False, histtype='bar', color=None, alpha=None, orientation='vertical', ...)
|
| 類別 | 參數 | 說明 |
|---|
| 資料 | x | 數值資料(list / NumPy 陣列) |
| 箱數 | bins | 區間數或邊界 |
| 範圍 | range | 限制繪製範圍 (min, max) |
| 密度 | density | True 表示機率密度(總面積=1) |
| 權重 | weights | 權重值 |
| 樣式 | histtype | 'bar'、'barstacked'、'step'、'stepfilled' |
| 顏色 | color、edgecolor、alpha | 顏色、邊框、透明度 |
| 對齊 | align | 'left'、'mid'(預設)、'right' |
| 累積 | cumulative | True 表示累積分布 |
| 方向 | orientation | 'vertical' 或 'horizontal' |
| 堆疊 | stacked | 多組資料是否堆疊顯示 |
散佈圖(Scatter Plot)
1 2 3 4
| plt.scatter(x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, edgecolors=None, plotnonfinite=False, data=None, **kwargs)
|
核心參數:
x, y:必填參數,數據點的座標位置(可以是列表、NumPy 陣列等陣列型態)。s:標記點的大小,單位是 points²(印刷點的平方,1 point = 1/72 英吋),可以是單一數值或陣列。c:標記點的顏色,可以是單一顏色、顏色陣列或數值序列(配合 colormap 使用)。marker:標記點的形狀,預設為 'o'(圓形)。
顏色映射參數:
cmap:顏色映射表名稱(如 'viridis'、'plasma'、'coolwarm'),用於將數值映射到顏色。vmin, vmax:顏色縮放的最小值和最大值,與 cmap 配合使用。norm:正規化物件,用於將數據值縮放到顏色映射範圍。
樣式參數:
alpha:透明度,範圍 0~1(0 為完全透明,1 為完全不透明)。linewidths:標記點邊框的寬度。edgecolors:標記點邊框的顏色。label:圖例標籤。
整理表
| 圖表類型 | 函式 |
|---|
| 長條圖 | plt.bar() |
| 橫條圖 | plt.barh() |
| 圓餅圖 | plt.pie() |
| 直方圖 | plt.hist() |
| 散佈圖 | plt.scatter() |
參考資料
matplotlib 函式庫 - matplotlib 教學 ( Python ) | STEAM 教育學習網
Matplotlib Tutorial - GeeksforGeeks
Matplotlib Bars | W3Schools
Matplotlib.pyplot.barh() function in Python - GeeksforGeeks
Matplotlib Pie Charts | W3Schools
Matplotlib.pyplot.hist() in Python - GeeksforGeeks
Matplotlib Scatter | W3Schools