2016年3月16日

多「彩」多姿的拼圖:@cnFillPalette 的應用

這篇想分享一個簡單的概念:如何在一張圖中,使用多個不同的 ColorMap。一個看似理所當然的畫圖技巧,但卻在我初學NCL時困擾了我好一陣子...

範例如下:MultiColorMap.png
上圖是 2014/1/1 的近地表氣溫
下圖是此時的氣溫減去全年平均


這是一個常常用到的技巧,譬如說當需要把不同的變數拼在同一張圖上時,將不同的變數用不同顏色的ColorMap來表示,能使讀者一眼就看出這是不同的東西,使圖表更加清楚。以範例圖為例,下圖使用雙色(紅/藍)的 ColorMap 來表示氣溫的變異,不但可以讓讀者一眼就知道下圖跟上圖是不同的東西,將紅藍交界設定在 0-K 更是清楚地表達了何處較暖、何處較冷。

由於這是一個簡單的步驟,在介紹範例 script 之前,我想先簡單用幾句話說明一下背後的概念,以及為何在當初困擾了我好一陣子。

舊版的 NCL 中,邏輯是先選定畫布 (workstation) 的顏色盤,然後畫布上面的圖,可以用顏色盤上面的顏色來著色。指令如下:

gsn_define_colormap   ( wks , "BlAqGrYeOrRe" )

注意這個設定是針對 "wks",也就是畫布。這樣的設計邏輯,若想要在一張畫布上放兩張不同 ColorMap 的圖片,步驟十分繁瑣複雜 (複雜到我也攋得多解釋什麼了...)。

好消息是,在 NCL version 6.1.0 以後,支援了利用畫圖屬性 (attributes, @) 功能,單獨指定每一張圖片的顏色盤,其用法如下:

res@cnFillPalette = "BlAqGrYeOrRe"

實際範例可參考以下的 script:NCL_multiColorMap.ncl,重點部分用螢光筆表示。
另外這裡也順便示範了如何
利用 dim_avg_n_Wrap 計算年平均
利用 conform_dims 將少掉時間維度的 年平均氣溫 (Temp_AnnualMean) 與 氣溫 (Temp) 相減
利用 symMinMaxPlt 強迫 colorbar 的範圍對稱於 0-K (雙色 ColorMap 常用技巧)

;===== NCL_multiColorMap.ncl =====
load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl"
load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl"

begin

        wks                     = gsn_open_wks("png","MultiColorMap")

        ncFile                  = addfile("air.2014.nc","r")
        Temp                    = ncFile->air

        Temp_AnnualMean         = dim_avg_n_Wrap        (Temp,0)
        Temp_Anomaly            = Temp - conform_dims   (dimsizes(Temp),Temp_AnnualMean,(/1,2,3/))
        copy_VarMeta            (Temp,Temp_Anomaly)
        Temp_Anomaly@long_name  = "Anomaly of "+Temp@long_name

;===== setup for plot =====
        res                     = True
        res@gsnDraw             = False
        res@gsnFrame            = False
        res@cnFillOn            = True
        res@cnLinesOn           = False
        res@lbOrientation       = "vertical"

        resS1                   = res
        resS1@cnFillPalette     = "BlAqGrYeOrRe"

        resS2                   = res
        resS2@cnFillPalette     = "BlueRed"

        res_pn                  = True
        res_pn@gsnMaximize      = True
        res_pn@gsnPaperOrientation      = "portrait"

;===== draw the plot =====
        plotAll                 = new   (2,graphic)

        PlotVar1                = Temp          (0,0,:,:)
        PlotVar2                = Temp_Anomaly  (0,0,:,:)

        symMinMaxPlt            (PlotVar2,20,False,resS2)

        plotAll(0)              = gsn_csm_contour_map_ce(wks,PlotVar1,resS1)
        plotAll(1)              = gsn_csm_contour_map_ce(wks,PlotVar2,resS2)

        gsn_panel               (wks,plotAll,(/2,1/),res_pn)

print   ("All Done.")
end
;=====

Take Home Message

指定/改變顏色盤很簡單,去官網的 Color Table Gallery 挑一個喜歡的預設值
利用 @cnFillPalette 個別指定每張圖的 ColorMap。

2 則留言:

  1. 居然還有更新!! 是說Matlab現在也可以一張圖有數個Colormap了!

    回覆刪除
  2. 作者已經移除這則留言。

    回覆刪除