単一の図の異なるプロットに対して異なる色の線を取得するにはどうすればよいですか?


202

matplotlibプロットの作成に使用しています。Pythonによって自動的に生成される異なる色で各プロットを識別する必要があります。

同じ図の異なるプロットに異なる色を配置する方法を教えてもらえますか?

回答:


424

Matplotlibはデフォルトでこれを行います。

例えば:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

plt.plot(x, x)
plt.plot(x, 2 * x)
plt.plot(x, 3 * x)
plt.plot(x, 4 * x)
plt.show()

カラーサイクリングを示す基本的なプロット

そして、すでにご存じかもしれませんが、凡例は簡単に追加できます。

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

plt.plot(x, x)
plt.plot(x, 2 * x)
plt.plot(x, 3 * x)
plt.plot(x, 4 * x)

plt.legend(['y = x', 'y = 2x', 'y = 3x', 'y = 4x'], loc='upper left')

plt.show()

凡例付きの基本的なプロット

循環する色を制御したい場合:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

plt.gca().set_color_cycle(['red', 'green', 'blue', 'yellow'])

plt.plot(x, x)
plt.plot(x, 2 * x)
plt.plot(x, 3 * x)
plt.plot(x, 4 * x)

plt.legend(['y = x', 'y = 2x', 'y = 3x', 'y = 4x'], loc='upper left')

plt.show()

デフォルトのカラーサイクリングの制御を示すプロット

matplotlibに慣れていない場合は、チュートリアルを開始するのに適しています。

編集:

まず、1つの図にプロットしたいものがたくさん(> 5)ある場合は、次のいずれかを実行します。

  1. それらを別のプロットに配置します(1つの図でいくつかのサブプロットを使用することを検討してください)、または
  2. 色(マーカースタイルや線の太さ)以外のものを使用して、それらを区別します。

さもなければ、あなたは非常に厄介な計画を巻き起こすでしょう!あなたがしていることを何でも読んでくれる人に優しく、1つの図に15の異なるものを詰め込もうとしないでください。

それを超えて、多くの人々はさまざまな程度で色覚異常であり、多くの微妙に異なる色を区別することは、あなたが理解しているよりも多くの人々にとって困難です。

そうは言っても、1つの軸に20本の比較的はっきりとした色の20本の線を配置したい場合は、次の方法で行います。

import matplotlib.pyplot as plt
import numpy as np

num_plots = 20

# Have a look at the colormaps here and decide which one you'd like:
# http://matplotlib.org/1.2.1/examples/pylab_examples/show_colormaps.html
colormap = plt.cm.gist_ncar
plt.gca().set_prop_cycle(plt.cycler('color', plt.cm.jet(np.linspace(0, 1, num_plots))))

# Plot several different functions...
x = np.arange(10)
labels = []
for i in range(1, num_plots + 1):
    plt.plot(x, i * x + 5 * i)
    labels.append(r'$y = %ix + %i$' % (i, 5*i))

# I'm basically just demonstrating several different legend options here...
plt.legend(labels, ncol=4, loc='upper center', 
           bbox_to_anchor=[0.5, 1.1], 
           columnspacing=1.0, labelspacing=0.0,
           handletextpad=0.0, handlelength=1.5,
           fancybox=True, shadow=True)

plt.show()

指定されたカラーマップに基づく20行の一意の色


17
最後の例について注意してください。matplotlibの新しいバージョンでは、これset_color_cycleは非推奨になっているため、必要に応じて行をplt.gca().set_prop_cycle(plt.cycler('color', plt.cm.jet(np.linspace(0, 1, num_plots))))変更しplt.cm.YOUR_PREFERED_COLOR_MAPます。
2016

1
@JoeKington:説明は素晴らしかった、どうもありがとうございました
Rika

これは素晴らしい。それらをインタラクティブにする方法はありますか?たとえば、RIでggplotをggplotly()に変換すると、プロットはインタラクティブなHTMLになります
kRazzy R

OPはMatplotlibが単一のプロット(単一のプロット)で適切に異なる曲線に色を付けることを知っていてaxes、異なるプロット(異なるaxes)で単一の線の色を変えることについて質問したと確信しています...質問(おそらくOPが尋ねたものとは異なるかもしれませんが、この単一の質問をして消えた
ので誰にもわかりませ

37

後で設定する

プロットしようとしているプロットの数がわからない場合は、プロットしてカラーを変更し.lines、を使用してプロットから直接数値を取得できます。私は次の解決策を使用します。

いくつかのランダムなデータ

import matplotlib.pyplot as plt
import numpy as np

fig1 = plt.figure()
ax1 = fig1.add_subplot(111)


for i in range(1,15):
    ax1.plot(np.array([1,5])*i,label=i)

必要なコードの一部:

colormap = plt.cm.gist_ncar #nipy_spectral, Set1,Paired   
colors = [colormap(i) for i in np.linspace(0, 1,len(ax1.lines))]
for i,j in enumerate(ax1.lines):
    j.set_color(colors[i])
  

ax1.legend(loc=2)

結果は次のとおりです。ここに画像の説明を入力してください


8

TL; DRいいえ、自動的に行うことはできません。はい、可能です。

import matplotlib.pyplot as plt
my_colors = plt.rcParams['axes.prop_cycle']() # <<< note that we CALL the prop_cycle
fig, axes = plt.subplots(2,3)
for ax in axes.flatten(): ax.plot((0,1), (0,1), **next(my_colors))

ここに画像の説明を入力してください 図(axes)の各プロット()にはfigure独自の色の循環があります。各プロットに異なる色を強制しない場合、すべてのプロットは同じ色順を共有しますが、「自動」の意味を少し伸ばすと、それを行うことができます。


OPが書いた

[...] [Matplotlib]によって自動的に生成される異なる色で各プロットを識別する必要があります。

しかし... Matplotlibは異なる曲線ごとに異なる色を自動的に生成します

In [10]: import numpy as np
    ...: import matplotlib.pyplot as plt

In [11]: plt.plot((0,1), (0,1), (1,2), (1,0));
Out[11]:

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

では、なぜOPリクエストなのでしょうか。読み続ければ、

同じ図の異なるプロットに異なる色を配置する方法を教えてもらえますか?

そして、それは理にかなっています。なぜなら、各プロット(それぞれaxesMatplotlibの用語で)には独自のcolor_cycle(つまり、2018年にはそのprop_cycle)があり、各プロット(axes)は同じ色を同じ順序で再利用するためです。

In [12]: fig, axes = plt.subplots(2,3)

In [13]: for ax in axes.flatten():
    ...:     ax.plot((0,1), (0,1))

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

これが元の質問の意味である場合、1つの可能性は、各プロットに異なる色を明示的に指定することです。

(よくあることですが)プロットがループで生成される場合、Matplotlibによって自動的に選択された色をオーバーライドするための追加のループ変数が必要です。

In [14]: fig, axes = plt.subplots(2,3)

In [15]: for ax, short_color_name in zip(axes.flatten(), 'brgkyc'):
    ...:     ax.plot((0,1), (0,1), short_color_name)

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

別の可能性は、サイクラーオブジェクトをインスタンス化することです

from cycler import cycler
my_cycler = cycler('color', ['k', 'r']) * cycler('linewidth', [1., 1.5, 2.])
actual_cycler = my_cycler()

fig, axes = plt.subplots(2,3)
for ax in axes.flat:
    ax.plot((0,1), (0,1), **next(actual_cycler))

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

注意type(my_cycler)ですcycler.Cyclerが、type(actual_cycler)ですitertools.cycle


3

私は前の投稿で与えられた最後のループの答えにマイナーな改善を提供したいと思います(その投稿は正しく、まだ受け入れられるはずです)。最後の例にラベルを付けるときに行われた暗黙の仮定は、X番目の時間に対応する行が呼び出されたときにplt.label(LIST)ラベル番号X を配置LISTすることplotです。私は以前このアプローチで問題に遭遇しました。凡例を作成し、matplotlibsのドキュメント(http://matplotlib.org/users/legend_guide.html#adjusting-the-order-of-legend-item)に従ってラベルをカスタマイズするための推奨される方法は、ラベルが暖かく感じられるようにすることですあなたが彼らが行うと思う正確なプロットとともに:

...
# Plot several different functions...
labels = []
plotHandles = []
for i in range(1, num_plots + 1):
    x, = plt.plot(some x vector, some y vector) #need the ',' per ** below
    plotHandles.append(x)
    labels.append(some label)
plt.legend(plotHandles, labels, 'upper left',ncol=1)

**:Matplotlibの凡例が機能しない


3
ただfyi: "label" kwargを使用してプロットし、引数なしでlegendを呼び出すこともできます。
Joe Kington 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.