Matplotlib 視覺化指南:結合 JSON 資料的完整實戰教程
好的,以下是您提供的 Matplotlib 視覺化指南內容,以 Markdown 格式重新輸出:
Matplotlib 視覺化指南
1. 通用的 Matplotlib 技巧
Matplotlib 是 Python 中最常用的 2D 繪圖工具,幾個核心概念包括:
- Figure(圖像):整個視覺化畫布
- Axes(座標軸):Figure 內的單個子圖
- Axis(軸):x 軸和 y 軸
- Artist(繪圖元素):圖形、標籤、圖例等
基礎設定
import matplotlib.pyplot as plt
import numpy as np
import json
# JSON 資料範例:
# 從 JSON 字串載入資料
json_data = '''
{
"x_values": [0, 1, 2, 3, 4, 5],
"y_values": [0, 1, 4, 9, 16, 25]
}
'''
data = json.loads(json_data)
# 基本繪圖流程
plt.figure()
plt.plot(data["x_values"], data["y_values"])
plt.xlabel("X 軸")
plt.ylabel("Y 軸")
plt.title("從 JSON 資料繪製的基本圖表")
plt.show()
2. 買一送一的介面
Matplotlib 提供兩種繪圖 API:
簡單介面(pyplot)
# 從 JSON 載入資料
json_data = '''{"x": [1, 2, 3], "y": [4, 5, 6]}'''
data = json.loads(json_data)
plt.plot(data["x"], data["y"])
plt.show()
面向對象 API(物件導向方式)
json_data = '''{"x": [1, 2, 3], "y": [4, 5, 6]}'''
data = json.loads(json_data)
fig, ax = plt.subplots()
ax.plot(data["x"], data["y"])
plt.show()
建議複雜圖表使用物件導向方式,可以更細緻控制。
3. 簡單的線條圖形
折線圖(Line Plot)
x = np.linspace(0, 10, 100)
y = np.sin(x)
# 轉換為 JSON 格式
json_data = json.dumps({"x": x.tolist(), "y": y.tolist()})
data = json.loads(json_data)
plt.plot(data["x"], data["y"], label="sin(x)")
plt.xlabel("X 軸")
plt.ylabel("Y 軸")
plt.title("從 JSON 資料繪製的基本折線圖")
plt.legend()
plt.show()
進階設定:
linestyle='dashed'
設定線條樣式color='r'
設定顏色marker='o'
添加數據點標記
4. 簡單的散佈圖
# 將隨機資料轉換為 JSON 格式
json_data = json.dumps({
"x": np.random.rand(100).tolist(),
"y": np.random.rand(100).tolist()
})
data = json.loads(json_data)
plt.scatter(data["x"], data["y"], color='blue', alpha=0.5)
plt.xlabel("X 軸")
plt.ylabel("Y 軸")
plt.title("從 JSON 資料繪製的散佈圖")
plt.show()
進階設定:
s=
設定點的大小c=
設定顏色alpha=
設定透明度
5. 視覺化誤差
# 建立並轉換為 JSON 格式
x = np.linspace(0, 10, 10)
y = np.sin(x)
error = np.random.rand(10) * 0.2
json_data = json.dumps({
"x": x.tolist(),
"y": y.tolist(),
"error": error.tolist()
})
data = json.loads(json_data)
plt.errorbar(data["x"], data["y"], yerr=data["error"], fmt='-o', capsize=5)
plt.title("從 JSON 資料繪製的誤差棒圖")
plt.show()
進階參數:
yerr=
Y 軸誤差xerr=
X 軸誤差capsize=
設定誤差線端點大小
6. 密度圖和等高線圖
密度圖(Kernel Density Estimation, KDE)
import seaborn as sns
# 將隨機資料轉換為 JSON 格式
json_data = json.dumps({
"data": np.random.randn(1000).tolist()
})
data = json.loads(json_data)
sns.kdeplot(data["data"], shade=True)
plt.title("從 JSON 資料繪製的密度圖")
plt.show()
等高線圖(Contour Plot)
X, Y = np.meshgrid(np.linspace(-3, 3, 100), np.linspace(-3, 3, 100))
Z = np.sin(X) * np.cos(Y)
# 轉換為 JSON 格式(注意:大型網格資料會產生較大的 JSON 字串)
json_data = json.dumps({
"Z": Z.tolist()
})
data = json.loads(json_data)
plt.contourf(X, Y, data["Z"], levels=20, cmap="viridis")
plt.colorbar()
plt.title("從 JSON 資料繪製的等高線圖")
plt.show()
7. 直方圖、分箱法及密度
直方圖(Histogram)
# 將隨機資料轉換為 JSON 格式
json_data = json.dumps({
"values": np.random.randn(1000).tolist()
})
data = json.loads(json_data)
plt.hist(data["values"], bins=30, alpha=0.7, color='blue', edgecolor='black')
plt.title("從 JSON 資料繪製的直方圖")
plt.show()
關鍵參數:
bins=
分箱數alpha=
透明度density=True
轉換為密度函數
8. 自訂圖表的圖例
# 將資料轉換為 JSON 格式
json_data = json.dumps({
"x": np.linspace(0, 10, 100).tolist(),
"y": np.sin(np.linspace(0, 10, 100)).tolist()
})
data = json.loads(json_data)
plt.plot(data["x"], data["y"], label="sin(x)", linestyle="--", color="r")
plt.legend(loc="upper right")
plt.title("從 JSON 資料繪製的帶圖例圖表")
plt.show()
loc=
設定圖例位置fontsize=
設定大小frameon=False
移除背景
9. 自訂色彩條
X, Y = np.meshgrid(np.linspace(-3, 3, 50), np.linspace(-3, 3, 50))
Z = np.sin(X) * np.cos(Y)
# 轉換為 JSON 格式
json_data = json.dumps({
"Z": Z.tolist()
})
data = json.loads(json_data)
plt.contourf(X, Y, data["Z"], cmap="coolwarm")
cbar = plt.colorbar()
cbar.set_label("數值")
plt.title("從 JSON 資料繪製的帶色彩條圖表")
plt.show()
10. 多重子圖表
x = np.linspace(0, 10, 100)
y = np.sin(x)
X, Y = np.meshgrid(np.linspace(-3, 3, 30), np.linspace(-3, 3, 30))
Z = np.sin(X) * np.cos(Y)
# 轉換為 JSON 格式
json_data = json.dumps({
"x": x.tolist(),
"y": y.tolist(),
"Z": Z.tolist(),
"random_data": np.random.randn(1000).tolist()
})
data = json.loads(json_data)
fig, axs = plt.subplots(2, 2, figsize=(10, 8))
axs[0, 0].plot(data["x"], data["y"], 'r')
axs[0, 0].set_title("折線圖")
axs[0, 1].scatter(data["x"], data["y"])
axs[0, 1].set_title("散佈圖")
axs[1, 0].hist(data["random_data"], bins=30)
axs[1, 0].set_title("直方圖")
axs[1, 1].contourf(X, Y, data["Z"])
axs[1, 1].set_title("等高線圖")
plt.tight_layout()
plt.suptitle("從 JSON 資料繪製的多重子圖表", y=1.05)
plt.show()
11. 文字和註解
# 將資料轉換為 JSON 格式
json_data = json.dumps({
"x": np.linspace(0, 10, 100).tolist(),
"y": np.sin(np.linspace(0, 10, 100)).tolist(),
"annotations": [
{"x": 5, "y": 0, "text": "中間點"},
{"x": 7, "y": 0.7, "text": "局部最大值", "xytext": [6, 1]}
]
})
data = json.loads(json_data)
plt.plot(data["x"], data["y"])
plt.text(data["annotations"][0]["x"], data["annotations"][0]["y"],
data["annotations"][0]["text"], fontsize=12, color="red")
plt.annotate(data["annotations"][1]["text"],
xy=(data["annotations"][1]["x"], data["annotations"][1]["y"]),
xytext=(data["annotations"][1]["xytext"][0], data["annotations"][1]["xytext"][1]),
arrowprops=dict(facecolor='black'))
plt.title("從 JSON 資料繪製的帶註解圖表")
plt.show()
12. 自訂刻度
# 將資料轉換為 JSON 格式
json_data = json.dumps({
"x": np.linspace(0, 10, 100).tolist(),
"y": np.sin(np.linspace(0, 10, 100)).tolist(),
"xticks": {"positions": [0, 2, 4, 6, 8, 10], "labels": ["A", "B", "C", "D", "E", "F"]},
"yticks": {"positions": [-1, 0, 1], "labels": ["Low", "Mid", "High"]}
})
data = json.loads(json_data)
plt.plot(data["x"], data["y"])
plt.xticks(data["xticks"]["positions"], labels=data["xticks"]["labels"])
plt.yticks(data["yticks"]["positions"], labels=data["yticks"]["labels"])
plt.title("從 JSON 資料繪製的自訂刻度圖表")
plt.show()
13. 客製化 Matplotlib:系統配置和樣式表
# 將樣式設定轉換為 JSON 格式
json_data = json.dumps({
"style": "ggplot",
"params": {
"font.size": 12,
"axes.labelcolor": "blue"
},
"x": np.linspace(0, 10, 100).tolist(),
"y": np.sin(np.linspace(0, 10, 100)).tolist()
})
data = json.loads(json_data)
plt.style.use(data["style"]) # 內建樣式
plt.rcParams["font.size"] = data["params"]["font.size"]
plt.rcParams["axes.labelcolor"] = data["params"]["axes.labelcolor"]
plt.plot(data["x"], data["y"])
plt.title("從 JSON 資料繪製的客製化樣式圖表")
plt.show()
14. 在 Matplotlib 中的三維繪圖法
from mpl_toolkits.mplot3d import Axes3D
# 將資料轉換為 JSON 格式
json_data = json.dumps({
"x": np.random.randn(100).tolist(),
"y": np.random.randn(100).tolist(),
"z": np.random.randn(100).tolist()
})
data = json.loads(json_data)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(data["x"], data["y"], data["z"])
plt.title("從 JSON 資料繪製的 3D 散佈圖")
plt.show()
15. Basemap 的地理資料
from mpl_toolkits.basemap import Basemap
# 將地圖設定轉換為 JSON 格式
json_data = json.dumps({
"projection": "mill",
"llcrnrlat": -60,
"urcrnrlat": 80,
"llcrnrlon": -180,
"urcrnrlon": 180,
"points": {
"lats": [20, 30, 40, 50],
"lons": [0, 60, 120, -60]
}
})
data = json.loads(json_data)
m = Basemap(projection=data["projection"],
llcrnrlat=data["llcrnrlat"],
urcrnrlat=data["urcrnrlat"],
llcrnrlon=data["llcrnrlon"],
urcrnrlon=data["urcrnrlon"])
m.drawcoastlines()
# 繪製點
x, y = m(data["points"]["lons"], data["points"]["lats"])
m.scatter(x, y, marker='o', color='red')
plt.title("從 JSON 資料繪製的地理圖")
plt.show()
16. 使用 Seaborn 進行視覺化
import seaborn as sns
# 將資料轉換為 JSON 格式
json_data = '''
{
"data": [
{"day": "Sun", "total_bill": 16.99, "tip": 1.01, "sex": "Female", "smoker": "No", "time": "Dinner"},
{"day": "Sun", "total_bill": 10.34, "tip": 1.66, "sex": "Male", "smoker": "No", "time": "Dinner"},
{"day": "Sun", "total_bill": 21.01, "tip": 3.50, "sex": "Male", "smoker": "No", "time": "Dinner"},
{"day": "Sun", "total_bill": 23.68, "tip": 3.31, "sex": "Male", "smoker": "No", "time": "Dinner"},
{"day": "Sun", "total_bill": 24.59, "tip": 3.61, "sex": "Female", "smoker": "No", "time": "Dinner"},
{"day": "Sun", "total_bill": 25.29, "tip": 4.71, "sex": "Male", "smoker": "No", "time": "Dinner"},
{"day": "Sat", "total_bill": 20.65, "tip": 3.35, "sex": "Male", "smoker": "No", "time": "Dinner"},
{"day": "Sat", "total_bill": 17.92, "tip": 4.08, "sex": "Male", "smoker": "No", "time": "Dinner"},
{"day": "Sat", "total_bill": 20.29, "tip": 2.75, "sex": "Female", "smoker": "No", "time": "Dinner"},
{"day": "Sat", "total_bill": 15.77, "tip": 2.23, "sex": "Female", "smoker": "No", "time": "Dinner"},
{"day": "Thur", "total_bill": 14.83, "tip": 3.02, "sex": "Female", "smoker": "No", "time": "Lunch"},
{"day": "Thur", "total_bill": 21.58, "tip": 3.92, "sex": "Male", "smoker": "No", "time": "Lunch"},
{"day": "Thur", "total_bill": 12.60, "tip": 1.00, "sex": "Male", "smoker": "Yes", "time": "Lunch"},
{"day": "Thur", "total_bill": 16.31, "tip": 2.00, "sex": "Male", "smoker": "Yes", "time": "Lunch"},
{"day": "Fri", "total_bill": 17.89, "tip": 2.00, "sex": "Male", "smoker": "Yes", "time": "Lunch"},
{"day": "Fri", "total_bill": 19.77, "tip": 2.00, "sex": "Male", "smoker": "No", "time": "Lunch"}
]
}
'''
data = json.loads(json_data)
# 將 JSON 資料轉換為 pandas DataFrame
import pandas as pd
tips_df = pd.DataFrame(data["data"])
# 繪製箱型圖
sns.boxplot(x="day", y="total_bill", data=tips_df)
plt.title("從 JSON 資料繪製的 Seaborn 箱型圖")
plt.show()
# 繪製熱圖
pivot_data = tips_df.pivot_table(index="day", columns="time", values="total_bill", aggfunc="mean")
sns.heatmap(pivot_data, annot=True, cmap="YlGnBu")
plt.title("從 JSON 資料繪製的 Seaborn 熱圖")
plt.show()
# 繪製小提琴圖
sns.violinplot(x="day", y="total_bill", hue="sex", data=tips_df, split=True)
plt.title("從 JSON 資料繪製的 Seaborn 小提琴圖")
plt.show()
以下是用 Markdown 格式編排的內容:
17. 互動式儀表板與 JSON 資料整合
import json
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
# 從 JSON 資料來源載入複雜資料集
json_data = '''
{
"sales": [
{"month": "Jan", "revenue": 12000, "costs": 8000, "profit": 4000, "category": "Electronics"},
{"month": "Feb", "revenue": 15000, "costs": 9000, "profit": 6000, "category": "Electronics"},
{"month": "Mar", "revenue": 18000, "costs": 10000, "profit": 8000, "category": "Electronics"},
{"month": "Jan", "revenue": 8000, "costs": 5000, "profit": 3000, "category": "Clothing"},
{"month": "Feb", "revenue": 10000, "costs": 6000, "profit": 4000, "category": "Clothing"},
{"month": "Mar", "revenue": 12000, "costs": 7000, "profit": 5000, "category": "Clothing"},
{"month": "Jan", "revenue": 5000, "costs": 3000, "profit": 2000, "category": "Food"},
{"month": "Feb", "revenue": 7000, "costs": 4000, "profit": 3000, "category": "Food"},
{"month": "Mar", "revenue": 9000, "costs": 5000, "profit": 4000, "category": "Food"}
],
"metadata": {
"title": "季度銷售報告",
"colors": {
"Electronics": "#1f77b4",
"Clothing": "#ff7f0e",
"Food": "#2ca02c"
}
}
}
'''
data = json.loads(json_data)
df = pd.DataFrame(data["sales"])
# 創建儀表板
fig = plt.figure(figsize=(15, 10))
gs = GridSpec(2, 3, figure=fig)
# 設置標題
fig.suptitle(data["metadata"]["title"], fontsize=16)
# 1. 收入趨勢圖
ax1 = fig.add_subplot(gs[0, :2])
for category in df["category"].unique():
category_data = df[df["category"] == category]
ax1.plot(category_data["month"], category_data["revenue"],
marker='o', label=category, color=data["metadata"]["colors"][category])
ax1.set_title("收入趨勢")
ax1.set_xlabel("月份")
ax1.set_ylabel("收入")
ax1.legend()
# 2. 餅圖 - 各類別總收入
ax2 = fig.add_subplot(gs[0, 2])
category_totals = df.groupby("category")["revenue"].sum()
ax2.pie(category_totals, labels=category_totals.index, autopct='%1.1f%%',
colors=[data["metadata"]["colors"][cat] for cat in category_totals.index])
ax2.set_title("各類別總收入")
# 3. 長條圖 - 各月份收入、成本、利潤
ax3 = fig.add_subplot(gs[1, :])
months = df["month"].unique()
x = np.arange(len(months))
width = 0.25
revenue_by_month = df.groupby("month")["revenue"].sum()
costs_by_month = df.groupby("month")["costs"].sum()
profit_by_month = df.groupby("month")["profit"].sum()
ax3.bar(x - width, revenue_by_month, width, label='收入')
ax3.bar(x, costs_by_month, width, label='成本')
ax3.bar(x + width, profit_by_month, width, label='利潤')
ax3.set_xticks(x)
ax3.set_xticklabels(months)
ax3.set_title("各月份收入、成本與利潤")
ax3.set_xlabel("月份")
ax3.set_ylabel("金額")
ax3.legend()
plt.tight_layout()
plt.subplots_adjust(top=0.9)
plt.show()
18. 時間序列資料視覺化
import json
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter
# 從 JSON 資料來源載入時間序列資料
json_data = '''
{
"timeData": [
{"date": "2024-01-01", "value": 100, "category": "A"},
{"date": "2024-01-02", "value": 105, "category": "A"},
{"date": "2024-01-03", "value": 110, "category": "A"},
{"date": "2024-01-04", "value": 115, "category": "A"},
{"date": "2024-01-05", "value": 118, "category": "A"},
{"date": "2024-01-06", "value": 125, "category": "A"},
{"date": "2024-01-07", "value": 130, "category": "A"},
{"date": "2024-01-01", "value": 80, "category": "B"},
{"date": "2024-01-02", "value": 82, "category": "B"},
{"date": "2024-01-03", "value": 87, "category": "B"},
{"date": "2024-01-04", "value": 95, "category": "B"},
{"date": "2024-01-05", "value": 100, "category": "B"},
{"date": "2024-01-06", "value": 110, "category": "B"},
{"date": "2024-01-07", "value": 115, "category": "B"}
],
"settings": {
"title": "時間序列資料視覺化",
"colors": {"A": "blue", "B": "red"}
}
}
'''
data = json.loads(json_data)
df = pd.DataFrame(data["timeData"])
df["date"] = pd.to_datetime(df["date"])
# 創建時間序列圖
plt.figure(figsize=(12, 6))
for category in df["category"].unique():
category_data = df[df["category"] == category]
plt.plot(category_data["date"], category_data["value"],
marker='o', label=category, color=data["settings"]["colors"][category])
plt.title(data["settings"]["title"])
plt.xlabel("日期")
plt.ylabel("數值")
plt.legend()
plt.grid(True, linestyle='--', alpha=0.7)
# 格式化 x 軸日期
plt.gca().xaxis.set_major_formatter(DateFormatter('%Y-%m-%d'))
plt.gcf().autofmt_xdate() # 自動旋轉日期標籤
plt.tight_layout()
plt.show()
19. 互動式金融圖表
import json
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.finance import candlestick_ohlc
import matplotlib.dates as mdates
# 從 JSON 資料來源載入股票資料
json_data = '''
{
"stockData": [
{"date": "2024-01-01", "open": 100, "high": 105, "low": 98, "close": 103, "volume": 1000},
{"date": "2024-01-02", "open": 103, "high": 110, "low": 102, "close": 108, "volume": 1200},
{"date": "2024-01-03", "open": 108, "high": 115, "low": 107, "close": 112, "volume": 1500},
{"date": "2024-01-04", "open": 112, "high": 118, "low": 110, "close": 115, "volume": 1800},
{"date": "2024-01-05", "open": 115, "high": 120, "low": 113, "close": 118, "volume": 1600},
{"date": "2024-01-08", "open": 118, "high": 122, "low": 116, "close": 120, "volume": 1400},
{"date": "2024-01-09", "open": 120, "high": 125, "low": 118, "close": 122, "volume": 1700},
{"date": "2024-01-10", "open": 122, "high": 128, "low": 120, "close": 125, "volume": 2000}
],
"settings": {
"title": "股票價格走勢",
"ticker": "EXAMPLE"
}
}
'''
data = json.loads(json_data)
df = pd.DataFrame(data["stockData"])
df["date"] = pd.to_datetime(df["date"])
df["date_num"] = mdates.date2num(df["date"])
# 準備資料為 OHLC 格式
ohlc = df[["date_num", "open", "high", "low", "close"]].values
# 創建 K 線圖和成交量圖
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8), gridspec_kw={'height_ratios': [3, 1]}, sharex=True)
# K 線圖
candlestick_ohlc(ax1, ohlc, width=0.6, colorup='green', colordown='red')
ax1.set_title(f"{data['settings']['title']} - {data['settings']['ticker']}")
ax1.set_ylabel('價格')
ax1.grid(True)
# 成交量圖
ax2.bar(df["date_num"], df["volume"], width=0.6, color='blue', alpha=0.7)
ax2.set_ylabel('成交量')
ax2.grid(True)
# 格式化 x 軸日期
ax2.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
plt.gcf().autofmt_xdate()
plt.tight_layout()
plt.show()
20. 結合 Matplotlib 與 JSON 資料的進階技巧
import json
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick
from matplotlib.gridspec import GridSpec
# 從 JSON 資料來源載入商業指標資料
json_data = '''
{
"businessMetrics": {
"monthlyRevenue": [
{"month": "Jan", "revenue": 120000, "target": 100000},
{"month": "Feb", "revenue": 130000, "target": 110000},
{"month": "Mar", "revenue": 150000, "target": 120000},
{"month": "Apr", "revenue": 160000, "target": 130000},
{"month": "May", "revenue": 180000, "target": 140000},
{"month": "Jun", "revenue": 190000, "target": 150000}
],
"customerSegments": [
{"segment": "Enterprise", "count": 50, "value": 120000},
{"segment": "SMB", "count": 200, "value": 80000},
{"segment": "Startup", "count": 400, "value": 40000},
{"segment": "Individual", "count": 1000, "value": 20000}
],
"satisfaction": [
{"quarter": "Q1", "score": 8.5},
{"quarter": "Q2", "score": 8.7},
{"quarter": "Q3", "score": 9.0},
{"quarter": "Q4", "score": 9.2}
]
},
"settings": {
"colors": {
"primary": "#1f77b4",
"secondary": "#ff7f0e",
"positive": "#2ca02c",
"negative": "#d62728"
},
"companyName": "TechCorp Inc."
}
}
'''
data = json.loads(json_data)
# 創建綜合儀表板
fig = plt.figure(figsize=(15, 10))
gs = GridSpec(2, 3, figure=fig)
# 設置標題
fig.suptitle(f"{data['settings']['companyName']} - 業務績效儀表板", fontsize=16)
# 1. 收入與目標對比圖
revenue_df = pd.DataFrame(data["businessMetrics"]["monthlyRevenue"])
ax1 = fig.add_subplot(gs[0, :2])
x = np.arange(len(revenue_df["month"]))
width = 0.35
ax1.bar(x - width/2, revenue_df["revenue"], width, label='實際收入',
color=data["settings"]["colors"]["primary"])
ax1.bar(x + width/2, revenue_df["target"], width, label='目標收入',
color=data["settings"]["colors"]["secondary"], alpha=0.7)
# 添加百分比標籤
for i, (r, t) in enumerate(zip(revenue_df["revenue"], revenue_df["target"])):
percentage = (r / t - 1) * 100
color = data["settings"]["colors"]["positive"] if percentage >= 0 else data["settings"]["colors"]["negative"]
ax1.text(i, max(r, t) + 5000, f"{percentage:.1f}%", ha='center', color=color, fontweight='bold')
ax1.set_title("月度收入與目標對比")
ax1.set_xlabel("月份")
ax1.set_ylabel("收入 ($)")
ax1.set_xticks(x)
ax1.set_xticklabels(revenue_df["month"])
ax1.legend()
ax1.grid(axis='y', linestyle='--', alpha=0.7)
ax1.yaxis.set_major_formatter('${x:,.0f}')
# 2. 客戶群體分析 - 氣泡圖
segment_df = pd.DataFrame(data["businessMetrics"]["customerSegments"])
ax2 = fig.add_subplot(gs[0, 2])
sizes = segment_df["value"] / segment_df["value"].max() * 1000 # 氣泡大小標準化
scatter = ax2.scatter(segment_df["count"], segment_df["value"], s=sizes,
alpha=0.6, c=range(len(segment_df)), cmap='viridis')
# 添加標籤
for i, segment in enumerate(segment_df["segment"]):
ax2.annotate(segment,
(segment_df["count"].iloc[i], segment_df["value"].iloc[i]),
ha='center', va='center', fontweight='bold')
ax2.set_title("客戶群體分析")
ax2.set_xlabel("客戶數量")
ax2.set_ylabel("總價值 ($)")
ax2.grid(True, linestyle='--', alpha=0.7)
ax2.yaxis.set_major_formatter('${x:,.0f}')
# 3. 滿意度走勢圖
satisfaction_df = pd.DataFrame(data["businessMetrics"]["satisfaction"])
ax3 = fig.add_subplot(gs[1, :])
ax3.plot(satisfaction_df["quarter"], satisfaction_df["score"], marker='o',
linewidth=3, color=data["settings"]["colors"]["primary"])
# 添加基準線
ax3.axhline(y=8.0, color='gray', linestyle='--', alpha=0.5)
ax3.text(0, 8.0, "基準線", va='bottom', ha='left', color='gray')
# 設定 y 軸範圍從 7 到 10
ax3.set_ylim(7, 10)
# 計算趨勢
start_score = satisfaction_df["score"].iloc[0]
end_score = satisfaction_df["score"].iloc[-1]
improvement = ((end_score / start_score) - 1) * 100
ax3.set_title(f"客戶滿意度走勢 (提升 {improvement:.1f}%)")
ax3.set_xlabel("季度")
ax3.set_ylabel("滿意度分數 (0-10)")
ax3.grid(True, linestyle='--', alpha=0.7)
# 格式化刻度為百分比
fmt = '%.1f'
ax3.yaxis.set_major_formatter(mtick.FormatStrFormatter(fmt))
# 增加註解
for i, score in enumerate(satisfaction_df["score"]):
ax3.annotate(f"{score}",
(satisfaction_df["quarter"].iloc[i], score),
textcoords="offset points",
xytext=(0, 10),
ha='center')
plt.tight_layout()
plt.subplots_adjust(top=0.9)
plt.show()
結語
這份完整的 Matplotlib 視覺化指南涵蓋了從基礎到進階的各種技巧,每個範例都加入了使用 JSON 格式資料來產出圖表的示例。透過這種方式,你可以輕鬆將從 API 獲取的 JSON 資料直接用於視覺化分析。主要優點包括:
- 資料與視覺化分離:JSON 格式允許將資料與視覺化代碼分離,使程式更易於維護
- API 整合友好:大多數網路 API 返回 JSON 格式資料,本指南提供直接整合的方法
- 可序列化和存儲:JSON 格式便於資料的存儲和傳輸
- 動態視覺化:容易更新資料源而不需修改視覺化代碼
這些技巧從簡單的線條圖形到複雜的互動式儀表板,都能幫助你更高效地處理和視覺化 JSON 格式的資料。
希望這份指南對你使用 Matplotlib 與 JSON 資料結合的視覺化工作有所幫助!