[筆記] 用matplotlib畫出互動式圖像 [1]

內容目錄
這只是一般的圖片。

在進行資料的視覺化時,我們很常會使用散佈圖來呈現,但是當我們想要知道圖片上特定的點其背後所代表的資料、圖像時,我們除了從座標去回推之外,可以透過hover annotation的方式來更直觀的讓使用者了解到該資料中所蘊含之資訊。

簡單來說,該功能就是使用matplotlib.pyplot畫圖,當滑鼠游標經過該資料點時,於其周圍顯示出該資料點之資訊,就像是下列影片中所展示的功能:

這個討論串中有大大提供了一個簡單的範例程式,有興趣的讀者可以直接根據本程式碼來進行修改使用。

底下為分部詳解,有能力的讀者可以跳過:

https://gist.github.com/MortisHuang/8eace8b870c5042b2110f01eeb15fde0

直接執行的話,會得到本文最一開始的圖片,將滑鼠移到點上時,就會在旁邊顯示出該點所連結到的圖片檔。

當然,matplotlib本身也有提供範例

接下來進行本範例程式碼的說明:

https://gist.github.com/MortisHuang/10d32edf962da8d28657fd04ace276b6

首先我們一樣是將Library給匯入,除了常見的plt跟np之外呢,是這次功能的主要腳色:OffsetImage、AnnotationBbox。

我在讀這功能時,一直想到我怎樣都學不會的Bbox,不好意思扯遠了。

接下來,我們要畫散佈圖,那就必須要有資料,於是我們先將x令為一從0-19,共含20個數字的array,而y則是一含有20個隨機數字的array,len(x)只是為了方便,如果想要看更多點的話只要改變x = np.arange(20)中的數字即可。

接下來將20張10×10的隨機影像儲存在arr這個變數裡。製作方式,是先產生一個5×5的隨機矩陣,之後上下、左右翻轉填入先前製作好的空矩陣裡。

https://gist.github.com/MortisHuang/5832cb0a1dbd24d5aa26168fa11de644

這一段就很直白了,先建立一個畫框叫做fig,在fig裡面加上一個繪圖區叫做ax,最後在ax裡面以x,y資料畫圖。

這邊值得一提的是,到底111代表什麼? 其實就是 1×1 張圖中的第1張。你也可以改成234這樣就是2×3張圖中的第四張。

在plot函數裡ls代表linestyle,這邊填上「””」表示不用畫線,因為plot這個函數是用來畫折線圖的,我們偷吃步假裝它是散佈圖。而marker就是代表點的圖示,有以下選擇:

上述三行執行完之後會得到這個靜態圖片:

靜態的,還無法動喔!
https://gist.github.com/MortisHuang/8c489ffdaf22dc973a88247f6a967677

這一段,則是製作要顯示在點旁邊的小圖示。首先我們將先前製作的隨機圖片中的第一個 (也就是arr[ 0 , : , : ])轉換成OffsetImage這個Class底下的一個物件,並稱之為im。

ab,是AnnotationBbox這個Class底下的一個物件,裡面包含了上面製作的im。 (50,50)表示該AnnotationBbox的位置,xybox則是距離該標示點的距離,不過第一個參數在底下的程式裡都會不斷的改變,所以在這邊只是先給一個初始值而已,並不太重要。而xycoords在官方文件中的說明如下:

簡單來說呢,用預設值data就好了。boxcoords後面的參數代表了使用與畫圖時相同的座標軸。pad則是邊示圖片的白色邊框大小。arrowprops則是指向該標註點的箭頭相關設定,想要修改的朋友可以往這邊走: 點我

最後兩行程式碼,則是在ax中加入我們剛剛製作好的小箱子,並使之顯示。

到這邊為止的範例程式碼如下:

https://gist.github.com/MortisHuang/e14b4f6095d5436c41c4a9125a94f1d2

執行完畢之後,會得到下圖:

一張有標註,但是無法隨著游標改變的靜態圖。

接下來就是我們的重頭戲了,該如何將互動性的功能給加上去

https://gist.github.com/MortisHuang/a1d509b3c20876bca3e9b66b527edbbf

我們自定義一個function 名叫hover,這個名字隨便我們取,你喜歡讓程式碼裡充滿屎尿的話也可以叫做shit。

其實每一行都有完整的註解了,那我這邊就不再多贅述。

最精華的,在這一行:

https://gist.github.com/MortisHuang/fad299f533bbae50807bd31d0c678640

將我們在上頭所製作的fig給連結到我們方才定義的function,那當什麼時候要執行該hover功能呢?就是 “motion_notify_event”,它代表了當滑鼠有動作時,就呼叫後面的hover功能,當然也可以改,以下是可以選擇的列表:

如果今天我們替換成’button_press_event’,那就變成點擊之後才會顯示圖片,可以試試看。

好,以上就是如何製作互動式圖片的方式,那實際應用在Deep Learning中的話,就是在畫完t-SNE之後,可以透過滑鼠移動,來觀察特定群聚之間的圖片特性。

有任何問題,歡迎寫信給我。

發佈留言