如何用python做資料存取並且視覺化? 其中一種作法是用 pandas 模組讀取資料,然後用 matplotlib 模組畫圖,以下我用一個範例說明程式如何實作。
問題說明:
Pokemon (寶可夢) 手機遊戲中,神奇寶貝 Pikachu (皮卡丘)出現位置的分佈為何?
資料來源:
(1) Predict'em All: https://www.kaggle.com/semioniy/predictemall
寶可夢遊戲中神奇寶貝出現的資料,包含約296,000次的歷史紀錄,資料欄位說明請見Kaggle,資料下載解壓縮後,300k.csv檔案約400 mb。
(2) Pikachu icon from IconArchive : http://www.iconarchive.com/show/cold-fusion-hd-icons-by-chrisbanks2/pikachu-icon.html
程式環境:python 3.6 | pandas 0.20.2 | matplotlib 2.0.2
範例程式:
# 匯入python模組
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.image import BboxImage
from matplotlib.transforms import Bbox, TransformedBbox
# 用 pandas 讀資料,取出需要的欄位。
df = pd.read_csv("300k.csv") # 皮卡丘的 Pokemon ID 是25,資料結構是DataFrame
xData = df[df.pokemonId==25].iloc[:,1] # latitude 緯度
yData = df[df.pokemonId==25].iloc[:,2] # longitude 經度
# 用 matplotlib 畫出散佈圖,並且將marker換成皮卡丘的icon
fig = plt.figure(figsize = (10, 10)) # 設定圖大小 10 inch * 10 inch
ax = fig.add_subplot(111) # 切割子圖 。1*1的第1張子圖
for x, y in zip(xData, yData):
b1 = Bbox.from_bounds(x, y, 5, 10) # maker 大小
b2 = TransformedBbox(b1, ax.transData)
bbox_image = BboxImage(b2, norm=None, origin=None, clip_on=False)
marker = plt.imread("pikachu_icon.png") # 讀入icon圖檔,作為散佈圖(scatter)的標記。
bbox_image.set_data(marker)
ax.add_artist(bbox_image)
ax.set_xlim(-40, 70) # 設定x軸範圍
ax.set_ylim(-180, 180) # 設定y軸範圍
plt.rcParams["font.sans-serif"] = ["SimHei"] # 用來正常顯示中文
plt.rcParams["axes.unicode_minus"] = False # 用來正常顯示負號
plt.xlabel("緯度", fontsize=14) # x軸說明
plt.ylabel("經度", fontsize=14) # y軸說明
plt.title("皮卡丘出現位置散佈圖", fontsize=20) # 圖標題
plt.grid(True) # 加上格線
plt.savefig("pikachu_scatter.png", dpi=600) # 將圖存擋
結果說明:
(1) 總共296,021次出現紀錄中, 皮卡丘只出現 516次, 每1萬次中出現18次不到 (約0.1743%),相當稀少。
(2) 程式畫出來的散佈圖png圖檔,如下所示。
問題說明:
Pokemon (寶可夢) 手機遊戲中,神奇寶貝 Pikachu (皮卡丘)出現位置的分佈為何?
資料來源:
(1) Predict'em All: https://www.kaggle.com/semioniy/predictemall
寶可夢遊戲中神奇寶貝出現的資料,包含約296,000次的歷史紀錄,資料欄位說明請見Kaggle,資料下載解壓縮後,300k.csv檔案約400 mb。
(2) Pikachu icon from IconArchive : http://www.iconarchive.com/show/cold-fusion-hd-icons-by-chrisbanks2/pikachu-icon.html
程式環境:python 3.6 | pandas 0.20.2 | matplotlib 2.0.2
範例程式:
# 匯入python模組
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.image import BboxImage
from matplotlib.transforms import Bbox, TransformedBbox
# 用 pandas 讀資料,取出需要的欄位。
df = pd.read_csv("300k.csv") # 皮卡丘的 Pokemon ID 是25,資料結構是DataFrame
xData = df[df.pokemonId==25].iloc[:,1] # latitude 緯度
yData = df[df.pokemonId==25].iloc[:,2] # longitude 經度
# 用 matplotlib 畫出散佈圖,並且將marker換成皮卡丘的icon
fig = plt.figure(figsize = (10, 10)) # 設定圖大小 10 inch * 10 inch
ax = fig.add_subplot(111) # 切割子圖 。1*1的第1張子圖
for x, y in zip(xData, yData):
b1 = Bbox.from_bounds(x, y, 5, 10) # maker 大小
b2 = TransformedBbox(b1, ax.transData)
bbox_image = BboxImage(b2, norm=None, origin=None, clip_on=False)
marker = plt.imread("pikachu_icon.png") # 讀入icon圖檔,作為散佈圖(scatter)的標記。
bbox_image.set_data(marker)
ax.add_artist(bbox_image)
ax.set_xlim(-40, 70) # 設定x軸範圍
ax.set_ylim(-180, 180) # 設定y軸範圍
plt.rcParams["font.sans-serif"] = ["SimHei"] # 用來正常顯示中文
plt.rcParams["axes.unicode_minus"] = False # 用來正常顯示負號
plt.xlabel("緯度", fontsize=14) # x軸說明
plt.ylabel("經度", fontsize=14) # y軸說明
plt.title("皮卡丘出現位置散佈圖", fontsize=20) # 圖標題
plt.grid(True) # 加上格線
plt.savefig("pikachu_scatter.png", dpi=600) # 將圖存擋
結果說明:
(1) 總共296,021次出現紀錄中, 皮卡丘只出現 516次, 每1萬次中出現18次不到 (約0.1743%),相當稀少。
(2) 程式畫出來的散佈圖png圖檔,如下所示。