4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

python の imshow と pcolormesh を用いた2Dヒストグラム生成時の微妙な違いを整理してみる

Last updated at Posted at 2023-10-18

はじめに

python で 2D ヒストグラムを生成する方法には、大きくは、imshow と pcolormesh を使う方法があるが、微妙な違いがあって、時々忘れてしまうのでまとめておきました。

サンプルプログラム

縦と横を間違えやすいので、ここでは x 軸方向の方が長いデータを擬似的に生成します。

頻度分布を出しても良いのですが、ここでは、z = f(x,y) の z の平均値を 2D ヒストグラムで生成するサンプルで imshow と pcolormesh の比較をしてみます。

# 必要なライブラリをインポート
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm

# xとyの範囲を定義
xmin, xmax = -10, 10
ymin, ymax = -5, 5

# 10000のランダムなxとyのデータポイントを生成
x, y = 20 * (np.random.rand(10000) - 0.5), 10 * (np.random.rand(10000) - 0.5)

# zのデータをxとyを基にして計算
z = 100 * np.random.normal(0.5*x + 0.5*y, 0.1, 10000)**2 + 1000

NBINS = 30
x_bins = np.linspace(xmin, xmax, NBINS)
y_bins = np.linspace(ymin, ymax, NBINS)

# xとyの範囲ごとのzの平均値を計算
z_avg = np.zeros((len(x_bins)-1, len(y_bins)-1))
for i in range(len(x_bins)-1):
    for j in range(len(y_bins)-1):
        mask = (x >= x_bins[i]) & (x < x_bins[i+1]) & (y >= y_bins[j]) & (y < y_bins[j+1])
        z_avg[i, j] = np.mean(z[mask])

# imshowを使ってヒートマップをプロット
plt.tight_layout()
plt.imshow(z_avg, cmap='viridis', origin='lower', 
           extent=[x_bins[0], x_bins[-1], y_bins[0], y_bins[-1]], norm=LogNorm())
plt.colorbar(shrink=0.4, label="a.u.")
plt.xlabel('x')
plt.ylabel('y')
plt.title('z Average Heatmap using imshow')
plt.savefig("test_imshow.png")
plt.show()

# pcolormeshを使ってヒートマップをプロット
plt.tight_layout()
mesh = plt.pcolormesh(x_bins, y_bins, z_avg.T, shading='auto', cmap='viridis', norm=LogNorm())
plt.colorbar(mesh, shrink=0.4, label="a.u.")
plt.xlabel('x')
plt.ylabel('y')
plt.title('z Average Heatmap using pcolormesh')
plt.savefig("test_pcolormesh.png")
plt.show()

結果

生成された図を見てみましょう。こちらが imshow で生成した場合です。

test_imshow.png

これが pcolormesh を用いた場合です。

test_pcolormesh.png

中身はどちらも同じですが、imshow の方は x : y が 2:1 の要素数であることを反映して横長になるのに対して、pcolormesh は画像サイズに従って調整していますね。

pcolormesh の使用時の注意点:

  • pcolormeshは、行と列の境界の配列を引数として取ります。これにはx_binsとy_binsが使用されます。
  • pcolormeshは、Z値(ここではz_avg)を行ごとに読み取るため、z_avgを転置する必要があります。これは、z_avg.T で行います。
mesh = plt.pcolormesh(x_bins, y_bins, z_avg.T, shading='auto', cmap='viridis', norm=LogNorm())

この部分で、z_avg.T.T を忘れないようにしましょう。

その他

from matplotlib.colors import LogNorm

を用いて、 norm=LogNorm() というオプションを用いて z軸方向を log スケールにするのは pcolormesh も imshow も同じです。

関連ページ

secondary_axis の利用については下記の記事を参照ください。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?