在進行資料的視覺化時,我們很常會使用散佈圖來呈現,但是當我們想要知道圖片上特定的點其背後所代表的資料、圖像時,我們除了從座標去回推之外,可以透過hover annotation的方式來更直觀的讓使用者了解到該資料中所蘊含之資訊。
簡單來說,該功能就是使用matplotlib.pyplot畫圖,當滑鼠游標經過該資料點時,於其周圍顯示出該資料點之資訊,就像是下列影片中所展示的功能:
在這個討論串中有大大提供了一個簡單的範例程式,有興趣的讀者可以直接根據本程式碼來進行修改使用。
底下為分部詳解,有能力的讀者可以跳過:
直接執行的話,會得到本文最一開始的圖片,將滑鼠移到點上時,就會在旁邊顯示出該點所連結到的圖片檔。
當然,matplotlib本身也有提供範例。
接下來進行本範例程式碼的說明:
首先我們一樣是將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的隨機矩陣,之後上下、左右翻轉填入先前製作好的空矩陣裡。
這一段就很直白了,先建立一個畫框叫做fig,在fig裡面加上一個繪圖區叫做ax,最後在ax裡面以x,y資料畫圖。
這邊值得一提的是,到底111代表什麼? 其實就是 1×1 張圖中的第1張。你也可以改成234這樣就是2×3張圖中的第四張。
在plot函數裡ls代表linestyle,這邊填上「””」表示不用畫線,因為plot這個函數是用來畫折線圖的,我們偷吃步假裝它是散佈圖。而marker就是代表點的圖示,有以下選擇:
上述三行執行完之後會得到這個靜態圖片:
這一段,則是製作要顯示在點旁邊的小圖示。首先我們將先前製作的隨機圖片中的第一個 (也就是arr[ 0 , : , : ])轉換成OffsetImage這個Class底下的一個物件,並稱之為im。
ab,是AnnotationBbox這個Class底下的一個物件,裡面包含了上面製作的im。 (50,50)表示該AnnotationBbox的位置,xybox則是距離該標示點的距離,不過第一個參數在底下的程式裡都會不斷的改變,所以在這邊只是先給一個初始值而已,並不太重要。而xycoords在官方文件中的說明如下:
簡單來說呢,用預設值data就好了。boxcoords後面的參數代表了使用與畫圖時相同的座標軸。pad則是邊示圖片的白色邊框大小。arrowprops則是指向該標註點的箭頭相關設定,想要修改的朋友可以往這邊走: 點我
最後兩行程式碼,則是在ax中加入我們剛剛製作好的小箱子,並使之顯示。
到這邊為止的範例程式碼如下:
執行完畢之後,會得到下圖:
接下來就是我們的重頭戲了,該如何將互動性的功能給加上去。
我們自定義一個function 名叫hover,這個名字隨便我們取,你喜歡讓程式碼裡充滿屎尿的話也可以叫做shit。
其實每一行都有完整的註解了,那我這邊就不再多贅述。
最精華的,在這一行:
將我們在上頭所製作的fig給連結到我們方才定義的function,那當什麼時候要執行該hover功能呢?就是 “motion_notify_event”,它代表了當滑鼠有動作時,就呼叫後面的hover功能,當然也可以改,以下是可以選擇的列表:
如果今天我們替換成’button_press_event’,那就變成點擊之後才會顯示圖片,可以試試看。
好,以上就是如何製作互動式圖片的方式,那實際應用在Deep Learning中的話,就是在畫完t-SNE之後,可以透過滑鼠移動,來觀察特定群聚之間的圖片特性。
有任何問題,歡迎寫信給我。