web-dev-qa-db-ja.com

matplotlib散布図でパラメーター 'c'および 'cmap'はどのように動作しますか?

pyplot.scatter(x、y、s、c ....)関数の場合、

Matplotlibドキュメントには次のように記載されています:

c:色、シーケンス、または色のシーケンス、オプション、デフォルト: 'b'マーカーの色。可能な値:

単色のフォーマット文字列。長さnの一連の色指定。 cmapとnormを使用して色にマッピングされるn個の数字のシーケンス。行がRGBまたはRGBAである2次元配列。 cは、カラーマップされる値の配列と区別できないため、単一の数値RGBまたはRGBAシーケンスであってはならないことに注意してください。すべてのポイントに同じRGB値またはRGBA値を指定する場合は、単一行の2次元配列を使用します。

しかし、私は望むようにデータポイントの色を変更する方法を理解していません

私はこのコードを持っています:

import matplotlib.pyplot as plt
import numpy as np
import sklearn
import sklearn.datasets
import sklearn.linear_model
import matplotlib


%matplotlib inline
matplotlib.rcParams['figure.figsize'] = (13.0, 9.0)

# Generate a dataset and plot it
np.random.seed(0)
X, y = sklearn.datasets.make_moons(200, noise=0.55)
print(y)
plt.scatter(X[:,0], X[:,1], c=y)#, cmap=plt.cm.Spectral)

出力プロット

どうすれば色を変更して、黒と緑のデータポイントを想定できますか?または、他の何か ?また、cmapが正確に行うことを説明してください。

plt.cm.Spectralを使用するたびにプロットがマゼンタとブルーになるのはなぜですか?

6
user9999114

散布点の色付けには、基本的に2つのオプションがあります。

1.外部マッピング

外部で値を色にマッピングし、scatterc引数にそれらの色のリスト/配列を提供できます。

_z = np.array([1,0,1,0,1])
colors = np.array(["black", "green"])
plt.scatter(x,y, c=colors[z])
_

2.内部マッピング

明示的な色とは別に、正規化とカラーマップに従って色にマッピングされる値のリスト/配列を提供することもできます。

  • colormapは、入力として_0._と_1._の間のfloat値を取り、RGBカラーを返す呼び出し可能オブジェクトです。
  • 正規化は、以前に設定されたいくつかの制限に基づいて、入力として任意の番号を受け取り、別の番号を出力する呼び出し可能オブジェクトです。 Normalizeの通常の場合は、vminvmaxの間の値を_0._と_1._の範囲に線形マッピングします。

したがって、一部のデータから色を取得する自然な方法は、2つを連鎖させることです。

_cmap = plt.cm.Spectral
norm = plt.Normalize(vmin=4, vmax=5)
z = np.array([4,4,5,4,5])
plt.scatter(x,y, c = cmap(norm(z)))
_

ここで_4_の値は、正規化によって_0_にマップされ、_5_の値は_1_にマップされ、カラーマップが2つの最も外側の色を提供します。

このプロセスは、scatterに数値の配列が提供される場合、cで内部的に発生します。

scatterは、PathCollectionをサブクラス化するScalarMappableを作成します。 ScalarMappableは、カラーマップ、正規化、および値の配列で構成されます。したがって、上記は

_plt.scatter(x,y, c=z, norm=norm, cmap=cmap)
_

最小データと最大データを正規化の制限として使用する場合、その引数は省略できます。

_plt.scatter(x,y, c=z, cmap=cmap)
_

これが、cに提供される値に関係なく、質問の出力が常に紫色と黄色のドットになる理由です。

_0_と_1_の配列を黒と緑の色にマッピングする要件に戻ると、 matplotlibが提供するカラーマップ を見て、次を含むカラーマップを探すことができます。黒と緑。例えば。 _nipy_spectral_カラーマップ

enter image description here

ここで、黒はカラーマップの先頭にあり、緑は途中のどこか、たとえば_0.5_にあります。したがって、vminを0に設定し、vmaxを設定して、_vmax*0.5 = 1_(_1_を緑にマップする値)、つまり_vmax = 1./0.5 == 2_に設定する必要があります。 。

_import matplotlib.pyplot as plt
import numpy as np
x,y = np.random.Rand(2,6)
z = np.array([0,0,1,1,0,1])

plt.scatter(x,y, c = z, 
            norm = plt.Normalize(vmin=0, vmax=2),
            cmap = "nipy_spectral")

plt.show()
_

enter image description here

使用可能な目的の色を備えたカラーマップが常に存在するとは限らないため、また既存のカラーマップから色位置を取得するのが簡単ではない可能性があるため、代替手段は目的に特化した新しいカラーマップを作成することです。

ここでは、黒と緑の2色のカラーマップを作成するだけです。

_matplotlib.colors.ListedColormap(["black", "green"])
_

ここには2つの値しかないため、自動正規化に依存できるため、正規化は必要ありません。

_import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
x,y = np.random.Rand(2,6)
z = np.array([0,0,1,1,0,1])

plt.scatter(x,y, c = z, cmap = mcolors.ListedColormap(["black", "green"]))

plt.show()
_

enter image description here

まず、yの値に従って色を設定するには、次のようにします。

_color = ['red' if i==0  else 'green' for i in y]
plt.scatter(X[:,0], X[:,1], c=color)
_

scatter()cmapについて話します。

ColorMapは、float値から色を提供するために使用されます。 カラーマップのリファレンスについてはこのドキュメント を参照してください。

enter image description here

0〜1の値の場合、これらのカラーマップから色が選択されます。

例えば:

_plt.cm.Spectral(0.0)
# (0.6196078431372549, 0.00392156862745098, 0.25882352941176473, 1.0) #<== Magenta

plt.cm.Spectral(1.0)
# (0.3686274509803922, 0.30980392156862746, 0.6352941176470588, 1.0) #<== blue

plt.cm.Spectral(1)
# (0.6280661284121491, 0.013302575932333718, 0.26082276047673975, 1.0)
_

上記のコードでは、1.0と1の結果が異なることに注意してください。これは、 __call__() here のドキュメントに記載されているように、intとfloatの処理が異なるためです。

Floatの場合、Xは、カラーマップ行に沿ってRGBA値_[0.0, 1.0]_パーセントを返すために、間隔_X*100_にある必要があります。

整数の場合、Xは、インデックスXを持つカラーマップからRGBA値indexedを返すために、間隔_[0, Colormap.N)_にある必要があります。

カラーマップについてのより良い説明については、この回答をご覧ください:-

Yには0と1があるので、上記のコードに示されているRGBA値が使用されます(スペクトルカラーマップの2つの端を表します)。

次に、plt.scatter()cおよびcmapパラメーターが相互に作用する方法を示します。

_ _______________________________________________________________________
|No | type of x, y |  c type  | values in c |       result              |
|___|______________|__________|_____________|___________________________|
|1  |   single     |  scalar  |   numbers   | cmap(0.0), no matter      |
|   |    point     |          |             |  what the value in c      |
|___|______________|__________|_____________|___________________________|
|2  |   array of   |  array   |   numbers   | normalize the values in c,|                
|   |    points    |          |             | cmap(normalized val in c) |
|___|______________|__________|_____________|___________________________|
|3  | scalar or    | scalar or| RGBA Values,|  no use of cmap,          |
|   |  array       |  array   |Color Strings|  use colors from c        |
|___|______________|__________|_____________|___________________________|
_

実際の色が完成したら、_x, y_の各ポイントの色を順に切り替えます。 x、yのサイズがcの色のサイズ以下である場合、完全なマッピングが得られるか、古い色が再び使用されます。

これを説明する例を次に示します。

_# Case 1 from above table

# All three points get the same color = plt.cm.Spectral(0)
plt.scatter(x=0.0, y=0.2, c=0, cmap=plt.cm.Spectral)
plt.scatter(x=0.0, y=0.3, c=1, cmap=plt.cm.Spectral)
plt.scatter(x=0.0, y=0.4, c=1.0, cmap=plt.cm.Spectral)

# Case 2 from above table

# The values in c are normalized 
# highest value in c gets plt.cm.Spectral(1.0)
# lowest value in c gets plt.cm.Spectral(0.0)
# Others in between as per normalizing
# Size of arrays in x, y, and c must match here, else error is thrown
plt.scatter([0.1, 0.1, 0.1, 0.1, 0.1], [0.2, 0.3, 0.4, 0.5, 0.6], 
            c=[1, 2, 3, 4, 5], cmap=plt.cm.Spectral)


# Case 3 from above table => No use of cmap here,
#  blue is assigned to the point
plt.scatter(x=0.2, y=0.3, c='b')

# You can also provide rgba Tuple
plt.scatter(x=0.2, y=0.4, c=plt.cm.Spectral(0.0))

# Since a single point is present, the first color (green) is given
plt.scatter(x=0.2, y=0.5, c=['g', 'r'])

# Same color 'cyan' is assigned to all values
plt.scatter([0.3, 0.3, 0.3, 0.3, 0.3], [0.2, 0.3, 0.4, 0.5, 0.6], 
            c='c')

# Colors are cycled through points
# 4th point will get again first color
plt.scatter([0.4, 0.4, 0.4, 0.4, 0.4], [0.2, 0.3, 0.4, 0.5, 0.6], 
            c=['m', 'y', 'k'])

# Same way for rgba values
# Third point will get first color again
plt.scatter([0.5, 0.5, 0.5, 0.5, 0.5], [0.2, 0.3, 0.4, 0.5, 0.6], 
            c=[plt.cm.Spectral(0.0), plt.cm.Spectral(1.0)])
_

出力:

enter image description here

完全に理解するために、コード内のコメントとポイントの位置を色とともに確認してください。

ケース3のコードでparam ccolorに置き換えることもできますが、結果は同じです。

1
Vivek Kumar