見出し画像

【matplotlib】colormapで3Dデータを見やすく可視化しよう!(見本帳あり)


こんにちは、JS2IIUです。
Matplotlibでグラフを作成する際、データの値を色で表現したい場合があります。そんな時に役立つのが colormap です。colormapは、数値と色を対応づけるもので、データの分布や変化を視覚的に表現するのに非常に役立ちます。今回は3D表示にさまざまなcolormapを適用してみます。

colormapの種類

Matplotlibには、様々なcolormapが用意されています。大きく分けて、以下の種類があります。

  • Sequential: 連続的な値の変化を表現するのに適しています。

  • Diverging: 中心値を基準に、正負の値を異なる色で表現するのに適しています。

  • Cyclic: 周期的な値の変化を表現するのに適しています。

  • Qualitative: 質的なデータの分類を表現するのに適しています。

  • Miscellaneous: その他のcolormapです。


colormapの選択

colormapは、データの性質や可視化の目的に合わせて適切なものを選択する必要があります。

例えば、連続的な値の変化を表現する場合には、Sequentialなcolormapが適しています。また、正負の値を異なる色で表現する場合には、Divergingなcolormapが適しています。

colormapの選択に迷った場合は、以下のサイトを参考にしてみてください。


Perceptually Uniform Sequential


Sequential


Sequential (2)



Diverging


Cyclic


Qualitative


Miscellaneous


colormapを使ってみよう


それでは、実際にcolormapを使ってグラフを作成してみましょう。今回は、3Dのサーフェースプロットを例にします。3Dサーフェースプロットについては以下のリンク先を参照して下さい。

3D surface (colormap) — Matplotlib 3.9.3 documentation


サンプルプログラム

Python

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import LinearLocator

# colormap list
cmaps = [
    ('Perceptually Uniform Sequential',
     ['viridis', 'plasma', 'inferno', 'magma', 'cividis']),
    ('Sequential',
     ['Greys', 'Purples', 'Blues', 'Greens', 'Oranges', 'Reds',
      'YlOrBr', 'YlOrRd', 'OrRd', 'PuRd', 'RdPu', 'BuPu',
      'GnBu', 'PuBu', 'YlGnBu', 'PuBuGn', 'BuGn', 'YlGn']),
    ('Sequential (2)',
     ['binary', 'gist_yarg', 'gist_gray', 'gray', 'bone', 'pink',
      'spring', 'summer', 'autumn', 'winter', 'cool', 'Wistia',
      'hot', 'afmhot', 'gist_heat', 'copper']),
    ('Diverging',
     ['PiYG', 'PRGn', 'BrBG', 'PuOr', 'RdGy', 'RdBu',
      'RdYlBu', 'RdYlGn', 'Spectral', 'coolwarm', 'bwr', 'seismic']),
    ('Cyclic', ['twilight', 'twilight_shifted', 'hsv']),
    ('Qualitative',
     ['Pastel1', 'Pastel2', 'Paired', 'Accent',
      'Dark2', 'Set1', 'Set2', 'Set3',
      'tab10', 'tab20', 'tab20b', 'tab20c']),
    ('Miscellaneous',
     ['flag', 'prism', 'ocean', 'gist_earth', 'terrain', 'gist_stern',
      'gnuplot', 'gnuplot2', 'CMRmap', 'cubehelix', 'brg',
      'gist_rainbow', 'rainbow', 'jet', 'turbo', 'nipy_spectral',
      'gist_ncar'])
]

# Make plot data.
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)

for i in range(len(cmaps)):
    cmap_category = cmaps[i][0]
    cmap_list = cmaps[i][1]

    # 1行3列のグラフをn_row個作成
    for k in range(0, len(cmap_list), 3):
        fig, axes = plt.subplots(1, 3, figsize=(12, 4),
                                 subplot_kw={"projection": "3d"})
        
        # 各行のcolormapを処理
        for j in range(3):
            if k + j < len(cmap_list):
                cmap = cmap_list[k + j]
                ax = axes[j]
                # Plot the surface.
                surf = ax.plot_surface(X, Y, Z, cmap=cmap,
                       linewidth=0, antialiased=False)
                # Customize the z axis.
                ax.set_zlim(-1.01, 1.01)
                ax.zaxis.set_major_locator(LinearLocator(10))
                # A StrMethodFormatter is used automatically
                ax.zaxis.set_major_formatter('{x:.02f}')

                ax.set_title(f'{cmap_category} - {cmap}')

                # カラーバーを追加
                fig.colorbar(surf, shrink=0.5, aspect=5)
            else:
                # 余ったaxesは非表示にする
                axes[j].axis('off')

        plt.tight_layout()
        plt.savefig(f'figs_3d/3D_{cmap_category}_{k // 3 + 1}.png')
        # figureを明示的に閉じる
        plt.close()


プログラムの解説

  1. 準備 まず、必要なライブラリをインポートします。

  • matplotlib.pyplot: グラフを描くためのライブラリです。

  • numpy: 数値計算を行うためのライブラリです。

  • matplotlib.ticker.LinearLocator: グラフの軸の目盛りを調整するためのライブラリです。


  1. カラーマップのリスト cmaps という変数に、Matplotlibに用意されているカラーマップをカテゴリ別にまとめたリストを定義しています。

  2. グラフのデータ X, Y, Z という変数に、グラフを描くためのデータを作っています。今回は、波打つような形の3Dグラフを表示するために、sin関数を使って計算しています。

  3. グラフの作成 いよいよグラフの作成です。ここでは、forループを使って、カラーマップのリストを一つずつ処理していきます。


  • fig, axes = plt.subplots(...): 1行3列のグラフを描くための準備をしています。 subplot_kw={"projection": "3d"} で3Dグラフを描画するように指定しています。

  • 3つずつカラーマップを処理し、それぞれのカラーマップで3Dサーフェスプロットを作成します。

    • surf = ax.plot_surface(...): 3Dサーフェスプロットを作成します。 cmap=cmap で、現在のカラーマップを指定しています。

    • ax.set_zlim(-1.01, 1.01): グラフのz軸の範囲を指定しています。

    • ax.zaxis.set_major_locator(LinearLocator(10)): z軸の目盛の数を10個に設定しています。

    • ax.zaxis.set_major_formatter('{x:.02f}'): z軸の目盛の表示形式を小数点以下2桁に設定しています。

    • ax.set_title(...): グラフのタイトルに、カラーマップのカテゴリ名とカラーマップ名を表示しています。

    • fig.colorbar(surf, shrink=0.5, aspect=5): カラーバーを表示しています。

  • plt.tight_layout(): グラフのレイアウトを調整しています。

  • plt.savefig(...): 作成したグラフを画像ファイルとして保存しています。

  • plt.close(): メモリを節約するために、グラフを閉じています。


プログラムを実行すると…

このプログラムを実行すると、「figs_3d」というフォルダに、様々なカラーマップで描画された3Dグラフの画像が保存されます。これらの画像を見比べることで、それぞれのカラーマップの特徴を掴むことができます。


まとめ

colormapは、データを色で表現することで、データの分布や変化を視覚的に表現するのに役立ちます。Matplotlibには、様々なcolormapが用意されているので、データの性質や可視化の目的に合わせて適切なものを選択しましょう。


いいなと思ったら応援しよう!