Python / matplotlib
===
###### tags: `Python`
###### tags: `Python`, `matplotlib`, `Grouped Bar Chart`, `分組柱狀圖`, `Radar Chart`, `雷達圖`, `蜘蛛網圖`, `plt`, `subplots`, `bar`, `set_xticks`, `set_xlabel`, `set_xticklabels`, `set_title`, `legend`, `show`
<br>
[TOC]
<br>
## 討論
### benchmark 的統計圖,以分組柱狀圖呈現
- ### Question

像這樣的圖叫做什麼?
如果 x 軸是 benchmark1, benchmark2, benchmark3, ...
在每個 benchmark 上,有:
```json
"benchmark1": {
"GPT-4o": 90,
"Qwen2": 85,
"LLaMA": 65,
}
```
```json
"benchmark2": {
"GPT-4o": 95,
"Qwen2": 90,
"LLaMA": 70,
}
```
這樣要怎麼設定?
- ### gpt-4o-2024-08-06
> 分組柱狀圖(Grouped Bar Chart)
這類型的圖表稱為「分組柱狀圖」(Grouped Bar Chart)。它用來比較不同類別在各個群組中的表現。在這個案例中,可以用來展示模型(如 GPT-4o、Qwen2、LLaMA)在不同基準測試中的結果。
#### 1. 準備資料:
將資料格式化成適合畫圖的格式。每個基準測試是群組,每個模型的結果是該群組中的一個數值。
#### 2. 程式碼範例:
```python=
import matplotlib.pyplot as plt
import numpy as np
# 設定基準測試
benchmarks = ['benchmark1', 'benchmark2', 'benchmark3']
# 設定模型分數
scores = {
"GPT-4o": [90, 95, 88],
"Qwen2": [85, 90, 80],
"LLaMA": [65, 70, 60]
}
# X 軸座標
x = np.arange(len(benchmarks))
# 權重寬度
width = 0.2
# 畫圖
fig, ax = plt.subplots()
# 每個模型的柱狀圖
ax.bar(x - width, scores["GPT-4o"], width, label="GPT-4o")
ax.bar(x, scores["Qwen2"], width, label="Qwen2")
ax.bar(x + width, scores["LLaMA"], width, label="LLaMA")
# 設定 X 軸標籤
ax.set_xticks(x)
ax.set_xticklabels(benchmarks)
# 標題和標籤
ax.set_xlabel('Benchmarks')
ax.set_ylabel('Score')
ax.set_title('Model Performance by Benchmark')
ax.legend()
# 顯示圖表
plt.show()
```
### 說明:
1. `benchmarks`:基準測試名稱(例如 benchmark1, benchmark2, benchmark3)。
2. `scores`:字典型格式,內含每個模型的分數列表,對應各個基準測試。
3. `x = np.arange(len(benchmarks))`:生成 X 軸位置,用來標示基準測試。
4. `width`:定義每個柱狀的寬度,並讓每個模型的柱狀圖稍微偏移,避免重疊。
這樣便可以生成一個展示模型在不同基準測試上的結果的分組柱狀圖。
### 執行結果

- ### legend 擋到 bar 了,要怎麼修正?
- ### gpt-4o-2024-08-06
你可以將圖例(legend)移到圖表外,避免擋住柱狀圖。例如,將圖例放在右邊或圖表上方。下面是一個如何調整圖例位置的範例程式碼:
```python
import matplotlib.pyplot as plt
# 你的繪圖程式碼
# ...
plt.legend(loc='upper right', bbox_to_anchor=(1.15, 1)) # 將圖例移到圖表右邊的外部
plt.show()
```
在這個範例中,`loc='upper right'` 將圖例放在右上角,`bbox_to_anchor=(1.15, 1)` 將圖例進一步調整到圖表外部。你可以根據需要微調 `bbox_to_anchor` 的數值來達到理想的效果。
如果有其他需求,隨時告訴我!
<br>
### matplotlib 所畫的圖要如何儲存下來?
- ### Question
plt 要怎麼將圖儲存下來?
- ### gpt-4o-2024-08-06
要將圖儲存下來,你可以在 `matplotlib` 中使用 `plt.savefig()` 函數。在生成圖表後,只需在 `plt.show()` 之前加入此命令即可。這樣可以將圖表儲存為多種格式(如 PNG、PDF、SVG 等)。
範例:
```python=
import matplotlib.pyplot as plt
import numpy as np
# 設定基準測試
benchmarks = ['benchmark1', 'benchmark2', 'benchmark3']
# 設定模型分數
scores = {
"GPT-4o": [90, 95, 88],
"Qwen2": [85, 90, 80],
"LLaMA": [65, 70, 60]
}
# X 軸座標
x = np.arange(len(benchmarks))
# 權重寬度
width = 0.2
# 畫圖
fig, ax = plt.subplots()
# 每個模型的柱狀圖
ax.bar(x - width, scores["GPT-4o"], width, label="GPT-4o")
ax.bar(x, scores["Qwen2"], width, label="Qwen2")
ax.bar(x + width, scores["LLaMA"], width, label="LLaMA")
# 設定 X 軸標籤
ax.set_xticks(x)
ax.set_xticklabels(benchmarks)
# 標題和標籤
ax.set_xlabel('Benchmarks')
ax.set_ylabel('Score')
ax.set_title('Model Performance by Benchmark')
ax.legend()
# 儲存圖表到本地檔案
plt.savefig('model_performance_comparison.png', dpi=300) # 可以調整dpi增加解析度
# 顯示圖表
plt.show()
```
### 說明:
- `plt.savefig('model_performance_comparison.png', dpi=300)`:儲存為 PNG 格式的圖檔,`dpi=300` 設定解析度為 300 DPI,這樣可以保證圖像品質。如果你想使用不同格式,直接改變副檔名即可(例如 `.pdf` 或 `.svg`)。
- `plt.show()`:顯示圖表在螢幕上,這個命令應放在儲存圖表之後,以避免顯示圖表之後影響到圖檔儲存。
這樣你的圖表就會儲存到當前工作目錄下的檔案中。
<br>
### benchmark 的統計圖,以雷達圖呈現
- ### Question
上述畫圖的程式碼,可以轉成雷達圖 ?
- ### gpt-4o-2024-08-06
當然可以!雷達圖(Radar Chart)也叫蜘蛛網圖,適合用來比較多個變數的表現,尤其是在多個維度上比較模型的表現。
這裡是將你的數據轉換成雷達圖的範例程式碼:
```python=
import numpy as np
import matplotlib.pyplot as plt
from math import pi
# 設定基準測試
benchmarks = ['benchmark1', 'benchmark2', 'benchmark3']
categories = len(benchmarks)
# 設定模型分數
scores = {
"GPT-4o": [90, 95, 88],
"Qwen2": [85, 90, 80],
"LLaMA": [65, 70, 60]
}
# 將角度分佈在雷達圖上
angles = [n / float(categories) * 2 * pi for n in range(categories)]
angles += angles[:1] # 為了閉合雷達圖,必須重複第一個角度
fig, ax = plt.subplots(figsize=(6, 6), subplot_kw=dict(polar=True))
# 畫出每個模型的雷達圖
for model, score in scores.items():
score += score[:1] # 為了閉合雷達圖,必須重複第一個數據點
ax.plot(angles, score, label=model)
ax.fill(angles, score, alpha=0.1)
# 設定雷達圖上的刻度
ax.set_xticks(angles[:-1])
ax.set_xticklabels(benchmarks)
# 設定標題和圖例
ax.set_title('Model Performance by Benchmark')
ax.legend(loc='upper right', bbox_to_anchor=(0.1, 0.1))
plt.show()
```
### 說明:
1. **`angles`**:這個列表將用來決定每個基準測試的角度分佈。使用 `2π` 將每個類別均勻分佈在圓形上。
2. **閉合雷達圖**:為了讓雷達圖閉合,我們需要在數據和角度列表的結尾重複第一個值。
3. **`ax.plot` 和 `ax.fill`**:`ax.plot` 畫出多邊形的邊,`ax.fill` 則填充內部區域,並設定透明度來區分不同模型的區域。
### 結果:
這段程式碼將產生一個雷達圖,每個模型在每個基準測試上的表現被連成一個多邊形,方便你比較模型之間的表現。
你可以根據實際需求調整圖例的位置和透明度,讓雷達圖看起來更加清晰。
### 繪製結果:
