1. ホーム
  2. python

[解決済み] Matplotlib の離散カラーバー

2022-08-27 11:18:28

質問

matplotlibで散布図に不連続なカラーバーを作ろうとしています。

x, y データがあり、各点に一意の色で表現したい整数のタグ値があります。

plt.scatter(x, y, c=tag)

通常、タグは0から20までの整数になりますが、正確な範囲は変更される可能性があります。

これまでのところ、私はデフォルトの設定を使っています。

plt.colorbar()

これは色の連続的な範囲を与えるものです。理想的には、n個の離散的な色のセット(この例ではn=20)が必要です。さらに良いのは、タグの値が0で灰色になり、1〜20でカラフルになることです。

いくつかの「クックブック」スクリプトを見つけましたが、非常に複雑で、一見単純に見える問題を解決する正しい方法とは思えません。

どのように解決するのですか?

散布図の正規化として BoundaryNorm を使用することで、非常に簡単にカスタム離散カラーバーを作成することができます。風変わりなビット (私の方法では) は、0 を灰色として表示することです。

画像については、私はしばしばcmap.set_bad()を使用し、データをnumpyのマスクされた配列に変換します。それは0をグレーにするためにはるかに簡単ですが、私はこれをスキャッタまたはカスタムcmapで動作させることができませんでした。

別の方法として、ゼロから独自のcmapを作成するか、既存のものを読み出していくつかの特定のエントリだけをオーバーライドすることができます。

import numpy as np
import matplotlib as mpl
import matplotlib.pylab as plt

fig, ax = plt.subplots(1, 1, figsize=(6, 6))  # setup the plot

x = np.random.rand(20)  # define the data
y = np.random.rand(20)  # define the data
tag = np.random.randint(0, 20, 20)
tag[10:12] = 0  # make sure there are some 0 values to show up as grey

cmap = plt.cm.jet  # define the colormap
# extract all colors from the .jet map
cmaplist = [cmap(i) for i in range(cmap.N)]
# force the first color entry to be grey
cmaplist[0] = (.5, .5, .5, 1.0)

# create the new map
cmap = mpl.colors.LinearSegmentedColormap.from_list(
    'Custom cmap', cmaplist, cmap.N)

# define the bins and normalize
bounds = np.linspace(0, 20, 21)
norm = mpl.colors.BoundaryNorm(bounds, cmap.N)

# make the scatter
scat = ax.scatter(x, y, c=tag, s=np.random.randint(100, 500, 20),
                  cmap=cmap, norm=norm)

# create a second axes for the colorbar
ax2 = fig.add_axes([0.95, 0.1, 0.03, 0.8])
cb = plt.colorbar.ColorbarBase(ax2, cmap=cmap, norm=norm,
    spacing='proportional', ticks=bounds, boundaries=bounds, format='%1i')

ax.set_title('Well defined discrete colors')
ax2.set_ylabel('Very custom cbar [-]', size=12)

<イグ

私は個人的に、20種類の色があると、特定の値を読み取るのが少し難しくなると思っています。