xloadct
でカラーテーブル設定ダイアログが表示される。loadct, n
でカラーテーブルを適用する。nはカラーテーブルのインデックスを示す整数。n を省略するとカラーテーブルの一覧が表示される。デフォルトでは #0 から #74 までの75種類のカラーテーブルを利用できる。このうち、#40 から #74は、IDL 8.2.1で追加された ColorBrewer Schemes。tvlct, r, g, b
で長さ 256 の配列r(赤)、g(緑)、b(青) (値は0~255)をカラーテーブルとして設定する。色番号nには、24 bitカラーでb[n] * 65536 + g[n] * 256 + r[n]
が割り当てられる。tvlct, r, g, b, /get
とすることで配列r、g、b
に現在のカラーテーブルの値が保存される。tvlct, v
のように引数を1つのみ与える場合は、v
は 256 x 3 の2次元配列で与える。v[*, 0], v[*, 1], v[*, 2]
がそれぞれ赤・緑・青の値に対応する。device, decomposed = 1
) で、contour や tv でカラーテーブルの色を用いるには次のようにする。
device, decomposed = 1
loadct, 49, rgb_table = color ; または tvlct, color, /get として現在設定されているカラーテーブルを取得する
data = dist(500)
contour, data, nlevels = 30, c_colors = (color[*, 0] + color[*, 1] * 256L + color[*, 2] * 65536L)[[0:29] / 29. * 255], /fill
tv, reform(color[bytscl(data), *], 500, 500, 3), true = 3
IDL 8.2.1 から使えるようになった colortable
関数で簡単にカラーテーブルを作成できる。色は 3 x N の配列で与える。中間色はRGBそれぞれの線形補間で作成されるので、色相が大きく異なる色を用いると中間色がくすんだ色になってしまう。中間色にやや鮮やかな色を指定してやると見栄えがよくなる。
; Graphics Function で使う場合
ctable = colortable([[255, 0, 0], [255, 255, 255], [0, 0, 255]], ncolors = 256)
p = contour(/test, /fill, rgb_table = ctable
xpalette
でインタラクティブにカラーテーブルの編集を行うことができる。
hsl
, hsv
, pseudo
等を用いてカラーテーブルを作成すると、中間色の彩度が落ち込まない。
カラーテーブルのコントラストとガンマを変更する。デフォルトは min = 0, max = 255, gamma 1.0。引数なしでstretch
を実行すると元に戻る。
stretch, min, max, gamma
一部のカラーテーブルは、色番号0と255をそれぞれ背景色(!p.background
)と描画色(!p.color
)で使うために、黒や白の値を入れている。そうでないカラーテーブルを、Direct Graphics の 8 bit カラーモード(device, decomposed = 0
)で利用する時には、以下のようにカラーテーブルを変更して、背景色と描画色用の色を確保しておく必要がある。
device, decomposed = 0
loadct, 74
data = dist(500)
levels = findgen(30) * (max(data) - min(data)) / 29 + min(data)
contour, data, levels = levels, /fill ; 背景、文字、目盛が変な色で表示されてしまう
tvlct, v, /get ; カラーテーブルを取得
v[0, *] = 0 ; 色 #0 を黒にする
v[255, *] = 255 ; 色 #255 を白にする
tvlct, v ; カラーテーブルを設定
!p.color = 0
!p.background = 255
contour, data, levels = levels, c_colors = indgen(30) * 253 / 29 + 1, /fill ; 色番号0と255をcontourで使わないよう、C_COLORS を指定する
modifyct
ユーザーが独自に作成したカラーテーブルを保存することができる。modifyct
はデフォルトではIDLのインストールディレクトリ以下の resource/colors/colors1.tbl を直接書き換えるので、別の場所にコピーしてそこに書き込むとよい。
$ cp <IDLのインストールディレクトリ>/resource/colors/colors1.tbl mycolor.tbl
; 現在のカラーテーブルを取得
IDL> tvlct, r, g, b, /get
; カラーテーブルをファイルに書き込む (41番)
IDL> modifyct, 41, 'My color table', r, g, b, file = 'mycolor.tbl'
; カラーテーブルをファイルから読み込む
IDL> loadct, 41, file = 'mycolor.tbl'
IDL> xloadct, file = 'mycolor.tbl'
modifyct
ではカラーテーブルファイルを新規作成できないので、ファイルを新規作成するには次のようにする(全インデックス黒のテーブルを1つ含むファイルが生成される)。一旦ファイルを作成した後は、modifyct
で新たなテーブルを追加していくことができる。
openw, lun, 'newfile.tbl', /get_lun
writeu, lun, [1b, bytarr(768), replicate(32b, 32)]
free_lun, lun
カラーテーブルファイルの構造は次のようになっている。デフォルトの colors1.tbl では N = 75。
オフセット | サイズ | 説明 |
---|---|---|
0x0000 | 1 byte | カラーテーブルの数 N |
オフセット | サイズ | 説明 |
---|---|---|
0x0001 | 768 bytes |
テーブル1のRGBデータ - 赤成分 256 bytes (0x0001 - 0x0100) - 緑成分 256 bytes (0x0101 - 0x0200) - 青成分 256 bytes (0x0201 - 0x0300) |
0x0301 | 768 bytes | テーブル2のRGBデータ |
... | ||
合計: 768 * N bytes |
オフセット | サイズ | 説明 |
---|---|---|
+0x0000 | 32 bytes | テーブル1の名前(スペースでパディングした固定長文字列) |
+0x0020 | 32 bytes | テーブル2の名前 |
... | ||
合計: 32 * N bytes |
matplotlibではさまざまなカラーマップが組み込まれている。Choosing Colormaps in Matplotlibでその一覧を見ることができる。
IDLでmatplotlib組み込みのカラーマップを利用するには、まず、次のようなPythonプログラムを用いて、matplotlib のカラーマップをファイルに保存する。numpy と matplotlib モジュールが使える状態になっている必要がある。
import matplotlib.pyplot as plt
import numpy as np
def save_colormap(cmap_name, filename=None, num_colors=256):
procedure_name = f"set_{cmap_name.lower()}"
if filename is None:
filename = f"{procedure_name}.pro"
cmap = plt.get_cmap(cmap_name)
colors = cmap(np.linspace(0, 1, num_colors))
colors_scaled = (colors[:, :3] * 255).astype(int)
idl_code = [
"cmap = [[{}], $".format(", ".join(map(str, colors_scaled[:, 0]))),
" [{}], $".format(", ".join(map(str, colors_scaled[:, 1]))),
" [{}]]".format(", ".join(map(str, colors_scaled[:, 2]))),
"",
]
with open(filename, 'w') as f:
f.write("\n".join(idl_code))
# 使用例
save_colormap('viridis')
生成されたファイル (上記の例では set_virdis.pro
) をIDLで実行すると変数 cmap にカラーテーブルの値が入るので、それを適用する。
; IDL
; cmap にカラーテーブルの値が入る
@set_virdis
; Direct Graphics で利用する場合
tvlct, cmap
; Graphics Function で利用する場合
p = contour(/test, /fill, rgb_table = cmap)
Python Bridge を利用可能な場合は、matplotlib のカラーマップを直接 IDL で使うこともできる。
; IDL
np = Python.Import('numpy')
cm = Python.Import('matplotlib.cm')
; YlOrBrを使う例
cmap = transpose((cm.YlOrBr(indgen(256), bytes=1))[0:2, *])
; viridis 等の色数固定のカラーマップ (ListedColormap) の場合は次のようにすることもできる
cmap = transpose(byte(np.array(cm.viridis.colors) * 255))
; Direct Graphics で利用する場合
tvlct, cmap
; Graphics Function で利用する場合
p = contour(/test, /fill, rgb_table = cmap)
matplotlib で IDL のデフォルトカラーテーブルを利用するには、IDLのインストールディレクトリ以下の resource/colors/colors1.tbl にあるカラーテーブルを直接読むのがてっとり早い。
import os
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
# テーブル番号 (0--74)
table = 8
# テーブルファイル名
tblfile = 'IDLのインストールディレクトリ/resource/colors/colors1.tbl'
with open(tblfile, 'br') as f:
f.seek(table * 768 + 1, os.SEEK_SET)
b = f.read(768)
colors = np.frombuffer(b, dtype=np.uint8).reshape(3, 256).T / 255.
cmap = ListedColormap(colors)
gradient = np.linspace(0, 1, 256)
gradient = np.vstack((gradient, gradient))
plt.figure(figsize=(8, 8))
plt.imshow(gradient, aspect='auto', cmap=cmap)
plt.show()