本篇文章介紹使用matplotlib繪制雷達圖,
雷達圖也被稱為網路圖,蜘蛛圖,星圖,蜘蛛網圖,是一個不規則的多邊形,雷達圖可以形象地展示相同事物的多維指標,應用場景非常多,
一、matplotlib繪制圓形雷達圖
# coding=utf-8
import numpy as np
import matplotlib.pyplot as plt
results = [{"大學英語": 87, "高等數學": 79, "體育": 95, "計算機基礎": 92, "程式設計": 85},
{"大學英語": 80, "高等數學": 90, "體育": 91, "計算機基礎": 85, "程式設計": 88}]
data_length = len(results[0])
# 將極坐標根據資料長度進行等分
angles = np.linspace(0, 2*np.pi, data_length, endpoint=False)
labels = [key for key in results[0].keys()]
score = [[v for v in result.values()] for result in results]
# 使雷達圖資料封閉
score_a = np.concatenate((score[0], [score[0][0]]))
score_b = np.concatenate((score[1], [score[1][0]]))
angles = np.concatenate((angles, [angles[0]]))
labels = np.concatenate((labels, [labels[0]]))
# 設定圖形的大小
fig = plt.figure(figsize=(8, 6), dpi=100)
# 新建一個子圖
ax = plt.subplot(111, polar=True)
# 繪制雷達圖
ax.plot(angles, score_a, color='g')
ax.plot(angles, score_b, color='b')
# 設定雷達圖中每一項的標簽顯示
ax.set_thetagrids(angles*180/np.pi, labels)
# 設定雷達圖的0度起始位置
ax.set_theta_zero_location('N')
# 設定雷達圖的坐標刻度范圍
ax.set_rlim(0, 100)
# 設定雷達圖的坐標值顯示角度,相對于起始角度的偏移量
ax.set_rlabel_position(270)
ax.set_title("計算機專業大一(上)")
plt.legend(["弓長張", "口天吳"], loc='best')
plt.show()
運行結果:
繪制雷達圖需要先建立極坐標系,關于極坐標系可以自己了解一下,建立好極坐標系后可以在極坐標系中繪制折線圖、柱狀圖等,大部分情況,都是用折線圖,形成一個不規則的閉合多邊形,本文中用某高校大一的期末考試成績作為例子來演示雷達圖的效果,
linspace(): 用于將極坐標系根據資料的維度進行等分,linspace()函式的第一個引數傳入起始角度,第二引數傳入結束角度,第三個引數傳入分成多少等份,其他引數根據需要傳入,如endpoint默認為True,最后一個資料處于結束的角度,根據本例中前面的引數0~2π,應該設定為False,否則最后一個資料與第一個資料角度重疊了,
concatenate(): 使雷達圖的資料是環形封閉的,concatenate()函式的第一個引數是一個元組,元組中的每個元素是一個陣列,concatenate()函式將這些陣列連接到一起,組成一個新的陣列,要讓繪制的雷達圖封閉,將資料的第一個值連接到陣列的結尾即可,
本文用折線圖plot()來繪制雷達圖,使用figure()函式設定好圖形的大小和清晰度,然后使用subplot()函式來創建一張子圖,subplot()函式的第一個引數傳入長度為3的數字,第一個數字表示將畫布分成幾行,第二個數字表示將畫布分成幾列,第三個數字表示當前的子圖處于哪個位置(按從左至右、從上到下的順序排序),第三個數字不能超出前兩個數字切分的子圖數范圍,如111表示將畫布分成一行一列(只有一張子圖),當前的子圖處于第一張子圖中,在subplot()函式中,將polar引數設定成True,得到的圖形才是極坐標,
極坐標系設定完成后,使用子圖物件ax呼叫折線圖函式plot(),即可繪出雷達圖,如果有多組資料,多次呼叫plot()函式即可,
使用set_thetagrids()方法設定雷達圖中每個維度的標簽和顯示位置,使用set_theta_zero_location()方法設定雷達圖的0度位置,可以傳入"N"、"NW"、"W"、"SW"、"S"、"SE"、"E"、"NE"八個方位縮寫,使用set_rlim()方法設定極坐標上的刻度范圍,使用set_rlabel_position()方法設定極坐標上的刻度標簽顯示位置,傳入一個相對于雷達圖0度的角度值,當然還可以根據需要設定其他屬性,如標題、圖例等,
在上面的例子中,將兩位同學的考試成績繪制成了雷達圖,通過雷達圖,可以看出兩個人的單科成績互有高低,而整體來看,兩位同學的成績都很優秀,上面的雷達圖中,網格線都是圓形的,而用折線圖連接的雷達圖兩個維度之間是直線連接的,所以將網格線換成多邊形會更合理一點,
二、matplotlib繪制多邊形雷達圖
import numpy as np
import matplotlib.pyplot as plt
results = [{"大學英語": 87, "高等數學": 79, "體育": 95, "計算機基礎": 92, "程式設計": 85},
{"大學英語": 80, "高等數學": 90, "體育": 91, "計算機基礎": 85, "程式設計": 88}]
data_length = len(results[0])
angles = np.linspace(0, 2*np.pi, data_length, endpoint=False)
labels = [key for key in results[0].keys()]
score = [[v for v in result.values()] for result in results]
score_a = np.concatenate((score[0], [score[0][0]]))
score_b = np.concatenate((score[1], [score[1][0]]))
angles = np.concatenate((angles, [angles[0]]))
labels = np.concatenate((labels, [labels[0]]))
fig = plt.figure(figsize=(10, 6), dpi=100)
fig.suptitle("計算機專業大一(上)")
ax1 = plt.subplot(121, polar=True)
ax2 = plt.subplot(122, polar=True)
ax, data, name = [ax1, ax2], [score_a, score_b], ["弓長張", "口天吳"]
for i in range(2):
for j in np.arange(0, 100+20, 20):
ax[i].plot(angles, 6*[j], '-.', lw=0.5, color='black')
for j in range(5):
ax[i].plot([angles[j], angles[j]], [0, 100], '-.', lw=0.5, color='black')
ax[i].plot(angles, data[i], color='b')
# 隱藏最外圈的圓
ax[i].spines['polar'].set_visible(False)
# 隱藏圓形網格線
ax[i].grid(False)
for a, b in zip(angles, data[i]):
ax[i].text(a, b+5, '%.00f' % b, ha='center', va='center', fontsize=12, color='b')
ax[i].set_thetagrids(angles*180/np.pi, labels)
ax[i].set_theta_zero_location('N')
ax[i].set_rlim(0, 100)
ax[i].set_rlabel_position(0)
ax[i].set_title(name[i])
plt.show()
運行結果:
在極坐標系中,極徑值相等的點在一個圓上,所以繪制的雷達圖中,網格線默認都是圓形的,如果要繪制多邊形的雷達圖,則需要將圓形的網格線隱藏,然后根據刻度范圍繪制出多邊形的網格線,
首先使用plot()函式,根據刻度范圍,繪制出同心的多個多邊形和多個維度方向的極軸,作為雷達圖的網格線,形成一張“網”,
鏈式呼叫極坐標的spines['polar'].set_visible()方法,傳入引數False,將極坐標系最外圈的圓形隱藏,呼叫grid()方法,傳入引數False,將極坐標系中的的圓形網格線隱藏,
修改完網格線后,即可達到多邊形的效果,在第二次繪制雷達圖時,將兩位同學的成績分到兩張不同的雷達圖中,并用text()方法設定了每個維度的資料標注,使用fig物件的suptitle()方法來設定整張圖形的標題,
上面的兩次繪圖,將兩位同學的成績繪制在同一張雷達圖時,更方便對比兩位同學的成績,如比較誰更全面、更優秀,分開繪制時,更方便分析個人的成績情況,如是否偏科,而相對于圓形的雷達圖,在多邊形的雷達圖中,不會出現雷達圖與網格線的不合理交叉(雷達圖與網格線交叉兩次),使用多邊形網格線更合理,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/261253.html
標籤:Python
