【MATLAB】gnuplotのカラーマップをmatlabで再現する

#はじめに
12月はエンジニアの皆様が1日1人記事を投稿してクリスマスを指折り数える文化（[Advent Calendar](https://qiita.com/advent-calendar/2020/matlab)）があるが，そういうのは無視して投稿することにする．(スキルに自信がないのでそういうのに参加するのは躊躇してしまうため)

今回は`gnuplot`カラーマップを`matlab`にて再現し，スペクトログラムを描画したいと思う．

#このカラーマップが欲しい
仕事で`matlab`を用いてスペクトログラムを描画することがたまにあり，カラーマップはいつも`jet`を使っている．インターネットでスペクトログラムなどで検索すると，下図のような紫～黄色のカラーマップで作成された画像をよく見るが，どうやらこのカラーマップは`matlab`には無いようなのである．
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373168/d1777480-33b8-9e54-c4fe-4b762a5e1668.png">

[現在のカラーマップの表示と設定 - MATLAB colormap](https://jp.mathworks.com/help/matlab/ref/colormap.html)

調べてみたところ，どうやらこのカラーマップは`matplotlib`では`gnuplot`という名前で入っているらしい．（`gnuplot`とは昔の描画ソフトのことで，このソフトで用いられてきたカラーマップなのだと思うが，コンピュータの歴史は詳しくないのでその辺は分からないです）
[Choosing Colormaps in Matplotlib](https://matplotlib.org/3.1.0/tutorials/colors/colormaps.html)

カッコいいカラーマップが`matplotlib`では使えるのに`matlab`で使えないのは悔しいので，自分で実装してみることにする．

#画像を拝借
[上記のサイト](https://matplotlib.org/3.1.0/tutorials/colors/colormaps.html)よりカラーマップの画像をダウンロードして，MSペイントを駆使してgnuplotのカラーバー部分をトリミングした．

![gnuplot_colormap.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373168/fd952fad-381e-3452-1e41-577ca02ff846.png)

こいつを`matlab`で読み取ればいいんじゃねえのかしら．
倫理的にアアアではあるが・・・


```matlab:
clc
clear all
close all

% 画像からカラーマップを生成する
IM = imread('gnuplot_colormap.png');% IMの型はuint8かuint16である
IM = squeeze(IM(1,:,:));% IMを1行分だけ抽出する
% colormapは0~1の範囲なのでuintの最大値で割って正規化する
myColormap = double(IM) / double(intmax(class(IM))); 


% 分析する信号
[y, Fs] = audioread('異国のシグナル.mp3');
y = y(:,1);% 1chだけ用いる

% STFTする
Nw = 512;                   % 時間窓の長さ
Nol = round(Nw/2);          % オーバーラップ
NFFT = Nw;                  % FFT点数
spectrogram(y,Nw,Nol,NFFT,Fs,'yaxis');  % スペクトログラムを描画
caxis([-120 -40]);          % レベルの範囲を指定
colormap(myColormap);       % カラーマップを設定

```

## 結果
![spectrogram_from_gnuplot_colormap.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373168/fc55818e-2ca1-f052-e192-9c5dfef3e005.png)

うむ，期待通りの画像が得られている．



# カラーマップを解析
前の節で終わってもいいのだが，せっかくなので，読み取ったカラーマップ画像のRGBのグラフを描いてみる．


```matlab:

clc
clear all
close all

IM = imread('gnuplot_colormap.png');
IM = squeeze(IM(1,:,:));
myColormap = double(IM) / double(intmax(class(IM)));
% ここまでは上と同じ

% RGBのグラフを描く
figure
c = ['r'; 'g'; 'b'];
L = length(myColormap);
n = ((1:L)-1)/L;% 横軸を[0 1]で正規化
for ind = 1:3
    plot(n, myColormap(:,ind), c(ind));
    hold on
end
legend(c);
title('カラーマップ（画像より生成）のRGB値');
hold off
```

## 結果
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373168/50e8e153-24ee-cfd7-af00-561e960641a9.png">

結果は割と分かりやすい感じになった．
これなら手で実装できそうである．多分こういうことでしょ．

```math:
{\rm RED} = \sqrt{x}\\
```
```math:
{\rm GREEN} = {x}^3\\
```
```math:
{\rm BLUE} = \sin({2 \pi x}) \ \ (0 \le x \le 0.5), \ \ 0 \ \ ({\rm else})\\
```

# カラーマップを手実装
```matlab:

r = sqrt(n);
g = n.^3;
b = sin(2*pi*1*n);
b(round(length(b)/2):end) = 0;
myColormap2 = [r', g', b'];
figure
n = ((1:L)-1)/L;
for ind = 1:3
    plot(n,myColormap2(:,ind), c(ind));
    hold on
end
legend(c);
title('カラーマップ（手実装）のRGB値');
hold off

```
## 結果
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373168/8b11376e-30a0-195d-418d-4aec96727e73.png">


うむ，いい感じ．
これを重ね書きしてみる．


```matlab:
figure
for ind = 1:3
    plot(n,myColormap(:,ind), c(ind));
    hold on
end
for ind = 1:3
    plot(n,myColormap2(:,ind), c(ind), 'LineStyle', ':');
    hold on
end
legend({'R(画像)', 'G(画像)', 'B(画像)', 'R(手実装)', 'G(手実装)', 'B(手実装)'});

```


![rgb3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373168/ea03152f-20b8-f00c-58e8-1d9dd880c272.png)

完全に一致した．ノルムの比較とかはしなくてもいいでしょ．
ヨシ！



# まとめ
最後に，手実装したカラーマップでスペクトログラムを描いてみる．

```matlab:
% 分析する信号
[y, Fs] = audioread('異国のシグナル.mp3');
y = y(:,1);

% STFTする
Nw = 512;                   % 時間窓の長さ
Nol = round(Nw/2);          % オーバーラップ
NFFT = Nw;                  % FFT点数
figure
spectrogram(y,Nw,Nol,NFFT,Fs,'yaxis');  % スペクトログラムを描画
caxis([-120 -40]);            % レベルの範囲を指定
% ここまでは同じ

colormap(myColormap2);               % 手実装したcolormapを指定する
```

![spectrogram_from_mycolormap.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373168/f3c76250-f3b6-d429-3500-e973c7f06399.png)
所望の結果が得られた．


![spectrogram_jet.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373168/15c993a1-ddb1-79d6-5cc8-9fd0ac73c33d.png)
ちなみにこちらはいつも使っている`jet`である．
見やすさは正直`jet`のほうが良いと個人的には思うが，気分で使い分けていきたいと思う．