matplotlibの散布図で各シリーズに異なる色を設定する


162

3つのデータセットがあるとします。

X = [1,2,3,4]
Y1 = [4,8,12,16]
Y2 = [1,4,9,16]

私はこれを散布することができます:

from matplotlib import pyplot as plt
plt.scatter(X,Y1,color='red')
plt.scatter(X,Y2,color='blue')
plt.show()

10セットでこれを行うにはどうすればよいですか?

私はこれを検索し、私が求めているものへの参照を見つけることができました。

編集:私の質問を(うまくいけば)明確にする

scatterを複数回呼び出すと、各scatterに同じ色しか設定できません。また、私は手動でカラー配列を設定できることを知っていますが、これを行うより良い方法があると確信しています。私の質問は、「どのようにして、それぞれが異なる色のいくつかのデータセットを自動的に散布図することができますか?

それが役立つ場合、各データセットに一意の番号を簡単に割り当てることができます。


1
ここでの質問は何ですか?色も配列にすることができますが、scatterを複数回呼び出すだけで解決できないものは何ですか?
Seberg、2012

1
scatterを複数回呼び出すと、同じ色になります。質問を更新します。
Yotam 2012

回答:


269

あなたが「手動で」どういう意味か分かりません。カラーマップを選択して、カラー配列を簡単に作成できます。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm

x = np.arange(10)
ys = [i+x+(i*x)**2 for i in range(10)]

colors = cm.rainbow(np.linspace(0, 1, len(ys)))
for y, c in zip(ys, colors):
    plt.scatter(x, y, color=c)

異なる色のMatplotlibグラフ

またはitertools.cycle、ループしたい色を使用して指定する独自のカラーサイクラーを作成し、使用nextして希望の色を取得することもできます。たとえば、3色の場合:

import itertools

colors = itertools.cycle(["r", "b", "g"])
for y in ys:
    plt.scatter(x, y, color=next(colors))

3色のみのMatplotlibグラフ

考えzipてみてください。最初のものと一緒に使用しないほうがきれいかもしれません。

colors = iter(cm.rainbow(np.linspace(0, 1, len(ys))))
for y in ys:
    plt.scatter(x, y, color=next(colors))

1
+1。itertoolsサイクルは、同じ色の複数のデータセットになるため、この状況ではおそらく良い考えではありません。
David Robinson、

1
@DavidRobinson:10をすべて指定した場合はそうではありませんが、サイクリングの目的はそこにある目的を無効にすることに同意します..:^)
DSM

正確に言えば、それはサイクルではありません:)
デビッド・ロビンソン

4
@macrocosme:私のために働く。plt.legend(['c{}'.format(i) for i in range(len(ys))], loc=2, bbox_to_anchor=(1.05, 1), borderaxespad=0., fontsize=11)上記の下部に追加すると、色の付いた伝説が得られます。
DSM

itertoolsソリューションは、一部の色を避けたい場合に最適です。私の場合、背景が黒なので黒は避けたいです。
ファブリツィオ

50

matplotlibで異なる色の点を持つプロットをプロットする通常の方法は、色のリストをパラメーターとして渡すことです。

例えば:

import matplotlib.pyplot
matplotlib.pyplot.scatter([1,2,3],[4,5,6],color=['red','green','blue'])

3色

リストのリストがあり、リストごとに色分けしたい場合。最もエレガントな方法は、@ DSMに推奨されている方法だと思います。スキャッターに対して複数の呼び出しを行うループを実行するだけです。

しかし、なんらかの理由で1回の呼び出しでそれを実行したい場合は、リスト内包と少しのフローリング分割を使用して、色の大きなリストを作成できます。

import matplotlib
import numpy as np

X = [1,2,3,4]
Ys = np.array([[4,8,12,16],
      [1,4,9,16],
      [17, 10, 13, 18],
      [9, 10, 18, 11],
      [4, 15, 17, 6],
      [7, 10, 8, 7],
      [9, 0, 10, 11],
      [14, 1, 15, 5],
      [8, 15, 9, 14],
       [20, 7, 1, 5]])
nCols = len(X)  
nRows = Ys.shape[0]

colors = matplotlib.cm.rainbow(np.linspace(0, 1, len(Ys)))

cs = [colors[i//len(X)] for i in range(len(Ys)*len(X))] #could be done with numpy's repmat
Xs=X*nRows #use list multiplication for repetition
matplotlib.pyplot.scatter(Xs,Ys.flatten(),color=cs)

すべてのプロット

cs = [array([ 0.5,  0. ,  1. ,  1. ]),
 array([ 0.5,  0. ,  1. ,  1. ]),
 array([ 0.5,  0. ,  1. ,  1. ]),
 array([ 0.5,  0. ,  1. ,  1. ]),
 array([ 0.28039216,  0.33815827,  0.98516223,  1.        ]),
 array([ 0.28039216,  0.33815827,  0.98516223,  1.        ]),
 array([ 0.28039216,  0.33815827,  0.98516223,  1.        ]),
 array([ 0.28039216,  0.33815827,  0.98516223,  1.        ]),
 ...
 array([  1.00000000e+00,   1.22464680e-16,   6.12323400e-17,
          1.00000000e+00]),
 array([  1.00000000e+00,   1.22464680e-16,   6.12323400e-17,
          1.00000000e+00]),
 array([  1.00000000e+00,   1.22464680e-16,   6.12323400e-17,
          1.00000000e+00]),
 array([  1.00000000e+00,   1.22464680e-16,   6.12323400e-17,
          1.00000000e+00])]

19

簡単な修正

コレクションのタイプが1つしかない場合(エラーバーのない散布など)、それらをプロットした後で色を変更することもできます。これは、実行が簡単になる場合があります。

import matplotlib.pyplot as plt
from random import randint
import numpy as np

#Let's generate some random X, Y data X = [ [frst group],[second group] ...]
X = [ [randint(0,50) for i in range(0,5)] for i in range(0,24)]
Y = [ [randint(0,50) for i in range(0,5)] for i in range(0,24)]
labels = range(1,len(X)+1)

fig = plt.figure()
ax = fig.add_subplot(111)
for x,y,lab in zip(X,Y,labels):
        ax.scatter(x,y,label=lab)

必要な唯一のコード:

#Now this is actually the code that you need, an easy fix your colors just cut and paste not you need ax.
colormap = plt.cm.gist_ncar #nipy_spectral, Set1,Paired  
colorst = [colormap(i) for i in np.linspace(0, 0.9,len(ax.collections))]       
for t,j1 in enumerate(ax.collections):
    j1.set_color(colorst[t])


ax.legend(fontsize='small')

同じサブプロットに多くの異なる散布図がある場合でも、出力は異なる色を提供します。

ここに画像の説明を入力してください


それは素晴らしいですが、たとえばこの関数で同じ色のエラーバーをどのように追加しますか?@GM
PEBKAC

1
こんにちは@PEBKACさん、指摘してくれてありがとう。今日の午後、その場合にも機能するように頑張ったが、解決策が見つからなかったので、質問を編集して他のユーザーに警告した。ありがとう!
GM

こんにちは@GM、申し訳ありませんが、解決策を完成させる前にいくつかコメントを投稿しました。これについては、以下で説明します
。stackoverflow.com/ q / 51444364/7541421

1
別の方法を使用して、散布図の各系列に色を割り当てました。うまくいきましたが、残念ながらエラーバーに関してはエレガントな解決策を進めることができませんでしたが、それでも非常に役立つ投稿に本当に感謝しています!乾杯!
PEBKAC

7

あなたはいつもこのようにplot()関数を使うことができます:

import matplotlib.pyplot as plt

import numpy as np

x = np.arange(10)
ys = [i+x+(i*x)**2 for i in range(10)]
plt.figure()
for y in ys:
    plt.plot(x, y, 'o')
plt.show()

散布としてプロットしますが、色を変更します


6

この質問は、2013年1月とmatplotlib 1.3.1(2013年8月)の前に少しトリッキーです。これは、matpplotlib Webサイトで見つけることができる最も古い安定バージョンです。しかし、その後は非常に簡単です。

現在のバージョンのmatplotlib.pylab.scatterサポート割り当て:カラー名文字列の配列、カラーマップ付きの浮動小数点数の配列、RGBまたはRGBAの配列。

この回答は、2015年に自分の2013年版を修正するという@Oxinaboxの無限の情熱に捧げられています。


1回の呼び出しで複数の色を指定してscatterコマンドを使用する2つのオプションがあります。

  1. pylab.scatterコマンドサポートとして、RGBA配列を使用して好きな色を実行します。

  2. 2013年の初めには、このコマンドは散乱ポイントコレクション全体で単一の色のみをサポートするため、これを行う方法はありません。10000行のプロジェクトを行っていたとき、それを回避する一般的な解決策を見つけました。粘着性がありますが、どんな形、色、サイズ、透明でもできます。このトリックは、描画パスコレクション、ラインコレクションにも適用できます。

このコードはのソースコードにも触発されてpyplot.scatterいます。スキャッターが何を行うかを複製して、トリガーすることなく描画しました。

コマンドpyplot.scatterPatchCollectionオブジェクトを返し、ファイル「matplotlib / collections.py」_facecolorsではCollectionクラスのプライベート変数とメソッドを返しますset_facecolors

したがって、描画するスキャッタポイントがあるときはいつでもこれを行うことができます。

# rgbaArr is a N*4 array of float numbers you know what I mean
# X is a N*2 array of coordinates
# axx is the axes object that current draw, you get it from
# axx = fig.gca()

# also import these, to recreate the within env of scatter command 
import matplotlib.markers as mmarkers
import matplotlib.transforms as mtransforms
from matplotlib.collections import PatchCollection
import matplotlib.markers as mmarkers
import matplotlib.patches as mpatches


# define this function
# m is a string of scatter marker, it could be 'o', 's' etc..
# s is the size of the point, use 1.0
# dpi, get it from axx.figure.dpi
def addPatch_point(m, s, dpi):
    marker_obj = mmarkers.MarkerStyle(m)
    path = marker_obj.get_path()
    trans = mtransforms.Affine2D().scale(np.sqrt(s*5)*dpi/72.0)
    ptch = mpatches.PathPatch(path, fill = True, transform = trans)
    return ptch

patches = []
# markerArr is an array of maker string, ['o', 's'. 'o'...]
# sizeArr is an array of size float, [1.0, 1.0. 0.5...]

for m, s in zip(markerArr, sizeArr):
    patches.append(addPatch_point(m, s, axx.figure.dpi))

pclt = PatchCollection(
                patches,
                offsets = zip(X[:,0], X[:,1]),
                transOffset = axx.transData)

pclt.set_transform(mtransforms.IdentityTransform())
pclt.set_edgecolors('none') # it's up to you
pclt._facecolors = rgbaArr

# in the end, when you decide to draw
axx.add_collection(pclt)
# and call axx's parent to draw_idle()

だから読むのはちょっと複雑で、2013年には1年間pythonを使いました。なぜ人々はそれを行う方法を知りたいのでしょうか?それが機能するようになった後、私は二度とそれを見る気になりません。私のプロジェクトは多くの視覚化を描くことでした、上記のコードで、ワークフローは合理化されました。
Hualin

1

これは私にとってはうまくいきます:

シリーズごとに、ランダムなRGBカラージェネレーターを使用する

c = color[np.random.random_sample(), np.random.random_sample(), np.random.random_sample()]

私はあなたの色の変化であるかわからないが、あなたのアプローチを使用して、次のような何かを行うことが可能です:plt.scatter(your values to the graph, color= (np.random.random_sample(), np.random.random_sample(), np.random.random_sample()) )。RGBジェネレータについて言及し、RGBリストを宣言しました。ジェネレータは '()'の間に宣言されています
Joel Carneiro

0

大規模なデータセットと限られた数の色の非常に高速なソリューションは、Pandasとgroupby関数の使用です。

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


# a generic set of data with associated colors
nsamples=1000
x=np.random.uniform(0,10,nsamples)
y=np.random.uniform(0,10,nsamples)
colors={0:'r',1:'g',2:'b',3:'k'}
c=[colors[i] for i in np.round(np.random.uniform(0,3,nsamples),0)]

plt.close('all')

# "Fast" Scatter plotting
starttime=time.time()
# 1) make a dataframe
df=pd.DataFrame()
df['x']=x
df['y']=y
df['c']=c
plt.figure()
# 2) group the dataframe by color and loop
for g,b in df.groupby(by='c'):
    plt.scatter(b['x'],b['y'],color=g)
print('Fast execution time:', time.time()-starttime)

# "Slow" Scatter plotting
starttime=time.time()
plt.figure()
# 2) group the dataframe by color and loop
for i in range(len(x)):
    plt.scatter(x[i],y[i],color=c[i])
print('Slow execution time:', time.time()-starttime)

plt.show()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.