2025-02-10

【備忘録】等高線図 (contour map)

Matplotlib は、Python と NumPy のためのプロットライブラリです。Tkinter、wxPython、Qt、GTK のような汎用 GUI ツールキットを使ったアプリケーションにプロットを埋め込むためのオブジェクト指向 API を提供しています。

Wikipedia より引用、翻訳

いくつものパラメータで、ある特性の最適点を探索するとき、興味がある2つのパラメータとその特性の関係を視覚化したい場合があります。(他のパラメータ値を固定した上で)2つのパラメータを変動させて、メッシュ状に総当たりのデータを用意できれば、Matplotlib の countour で等高線図を作成することができます。

数式からループを回して大きなメッシュ状のデータを用意して見た目に美しい等高線図を作成したことはあっても、生のデータから直接作成したことがありませんでした。どちらもやっていることは本質的には同じなのですが、あらためて少ないデータから等高線図を作ってみると、線形モデルを前提としなくとも、データの挙動をざっくり捉えるには使えそうだと思ったので、備忘録にまとめました。

下記の OS 環境で動作確認をしています。

Fedora Linux 41 Workstation x86_64
Python 3.13.2
jupyterlab 4.3.5
matplotlib 3.10.0
numpy 2.2.2
pandas 2.2.3

以下の作業は JupyterLab 上でおこなっています。

最初に必要なライブラリをインポートします。

import matplotlib.ticker as ticker
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

等高線図用データの準備

サンプルの CSV データを読み込みます。ファイル sample_contour.csv は下記からダウンロードできます。

sample_contour.csv
csvfile = 'sample_contour.csv'
df = pd.read_csv(csvfile)
df.head(10)

 

このデータは、X と Y それぞれのパラメータを一つずつ変化させて全ての組み合わせで Z を取得した総当たりのデータです。

X の値は下記のように 3 から 7 までの 5 つの整数です。

df['X'].unique()
array([3, 4, 5, 6, 7])

X のユニークな数 (5) を n_x に保存しておきます。

n_x = len(df['X'].unique())

Y の値は下記のように 0 から 5 までの 6 つの整数です。

df['Y'].unique()
array([0, 1, 2, 3, 4, 5])

Y のユニークな数 (6) を n_y に保存しておきます。

n_y = len(df['Y'].unique())

データフレームの列を Y, X の順番でソートします。

df.sort_values(['Y', 'X'], ignore_index=True, inplace=True)
df.head(10)

 

matplotlib の concour に渡す二次元配列 x, y, z を用意します。二次元配列は縦横のサイズが同じである必要があります。

データフレーム df から X, Y, Z 列を Series で取り出し、numpy の配列にした後、n_y 行 × n_x 列の二次元配列に整形します。

x = np.array(df['X']).reshape([n_y, n_x])
y = np.array(df['Y']).reshape([n_y, n_x])
z = np.array(df['Z']).reshape([n_y, n_x])
x
array([[3, 4, 5, 6, 7],
       [3, 4, 5, 6, 7],
       [3, 4, 5, 6, 7],
       [3, 4, 5, 6, 7],
       [3, 4, 5, 6, 7],
       [3, 4, 5, 6, 7]])
y
array([[0, 0, 0, 0, 0],
       [1, 1, 1, 1, 1],
       [2, 2, 2, 2, 2],
       [3, 3, 3, 3, 3],
       [4, 4, 4, 4, 4],
       [5, 5, 5, 5, 5]])
z
array([[ 900.,  550.,  450.,  150., -250.],
       [ 800.,  250.,  300.,  200., -100.],
       [ 150., -300., -150., -450., -450.],
       [ 400.,  -50.,  100., -200., -200.],
       [ 450.,    0.,  150., -150., -150.],
       [ 450.,    0.,  150., -150., -150.]])

等高線図のプロット

matplotlib の coucour で、二次元配列 x, y, z の等高線図をプロットします。

plt.rcParams['font.family'] = 'monospace'

fig = plt.figure(figsize=(6, 6))
ax = fig.add_subplot(111)

cont = ax.contour(
    x, y, z,
    linestyles='solid',
    linewidths=1,
)
cont.clabel(fmt='%.f', fontsize=12)

ax.xaxis.set_major_locator(ticker.MultipleLocator(1))
ax.yaxis.set_major_locator(ticker.MultipleLocator(1))

ax.xaxis.set_tick_params(labelsize=12)
ax.yaxis.set_tick_params(labelsize=12)

ax.set_xlabel('X', fontsize=14)
ax.set_ylabel('Y', fontsize=14)

ax.grid()

plt.tight_layout()
plt.show()

 

凸凹な等高線図ですが、これでもパラメータの変化にどのように依存するかの傾向を捉えることができます。

実用的には数あるパラメータから、JupyterLab 上であれこれパラメータを変えてプロットを作成するのは手間なので、PySide6 で GUI を用意して、使い勝手を良くしています。GUI を用意するのに時間がかかりますが、そこそこ使えるようにしてしまえば、あとは改善を重ねてどんどん使いやすくできます。

参考サイト

  1. matplotlib.pyplot.contour — Matplotlib documentation
  2. matplotlib.contour — Matplotlib documentation

 

ブログランキング・にほんブログ村へ bitWalk's - にほんブログ村 にほんブログ村 IT技術ブログ オープンソースへ
にほんブログ村

オープンソース - ブログ村ハッシュタグ
#オープンソース



このエントリーをはてなブックマークに追加

0 件のコメント: