Matplotlibを使用して、1つのプロットに20の異なるラインをプロットしています。 forループを使用してプロットし、すべての行にそのキーでラベルを付けてから、凡例関数を使用します
for key in dict.keys():
plot(x,dict[key], label = key)
graph.legend()
しかし、この方法を使用すると、グラフは凡例で多くの色を繰り返します。 matplotlibと20行以上を使用して各行に一意の色を割り当てる方法はありますか?
ありがとう
あなたの質問に対する答えは、他の2つのSOの質問に関連しています。
matplotlibのFigure内のプロットされた各ラインの新しい色を選択する方法 への答えは、プロットする次の色を選択するために循環するデフォルトの色のリストを定義する方法を説明します。これは_Axes.set_color_cycle
_ method で行われます。
正しい色のリストを取得したいのですが、この質問に対する答えで説明されているように、これはカラーマップを使用して最も簡単に実行できます。 matplotlibの指定されたカラーマップからカラージェネレーターを作成 。そこでは、カラーマップは0〜1の値を取り、色を返します。
したがって、20行の場合、1/20のステップで0から1に循環させます。具体的には、1が0にマップされるため、フォーム0から19/20を循環させます。
これはこの例で行われます:
_import matplotlib.pyplot as plt
import numpy as np
NUM_COLORS = 20
cm = plt.get_cmap('Gist_Rainbow')
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_color_cycle([cm(1.*i/NUM_COLORS) for i in range(NUM_COLORS)])
for i in range(NUM_COLORS):
ax.plot(np.arange(10)*(i+1))
fig.savefig('moreColors.png')
plt.show()
_
これは結果の図です:
代替案、より良い(議論の余地のある)解決策
ScalarMappable
オブジェクトを使用して値の範囲を色に変換する別の方法があります。この方法の利点は、非線形Normalization
を使用して、ラインインデックスから実際の色に変換できることです。次のコードは、まったく同じ結果を生成します。
_import matplotlib.pyplot as plt
import matplotlib.cm as mplcm
import matplotlib.colors as colors
import numpy as np
NUM_COLORS = 20
cm = plt.get_cmap('Gist_Rainbow')
cNorm = colors.Normalize(vmin=0, vmax=NUM_COLORS-1)
scalarMap = mplcm.ScalarMappable(norm=cNorm, cmap=cm)
fig = plt.figure()
ax = fig.add_subplot(111)
# old way:
#ax.set_color_cycle([cm(1.*i/NUM_COLORS) for i in range(NUM_COLORS)])
# new way:
ax.set_color_cycle([scalarMap.to_rgba(i) for i in range(NUM_COLORS)])
for i in range(NUM_COLORS):
ax.plot(np.arange(10)*(i+1))
fig.savefig('moreColors.png')
plt.show()
_
廃止予定ノート
mplib(1.5+)の最近のバージョンでは、ax.set_prop_cycle(color=[...])
を支持して_set_color_cycle
_関数は廃止されました。
12行のプロットがありましたが、 Yannの手法 を試してみると、同じような色の行を区別するのが難しいことがわかりました。私のラインもペアで表示されるため、各ペアの2つのラインに同じ色を使用し、2つの異なるライン幅を使用しました。線のスタイルを変更して、より多くの組み合わせを取得することもできます。
set_prop_cycle()
を使用できますが、plot()
を呼び出した後にlineオブジェクトを変更しました。
次に、3つの異なる線幅を使用したYannの例を示します。
import matplotlib.pyplot as plt
import numpy as np
NUM_COLORS = 20
cm = plt.get_cmap('Gist_Rainbow')
fig = plt.figure()
ax = fig.add_subplot(111)
for i in range(NUM_COLORS):
lines = ax.plot(np.arange(10)*(i+1))
lines[0].set_color(cm(i//3*3.0/NUM_COLORS))
lines[0].set_linewidth(i%3 + 1)
fig.savefig('moreColors.png')
plt.show()
異なる線種の同じ例です。もちろん、必要に応じて2つを組み合わせることができます。
import matplotlib.pyplot as plt
import numpy as np
NUM_COLORS = 20
LINE_STYLES = ['solid', 'dashed', 'dashdot', 'dotted']
NUM_STYLES = len(LINE_STYLES)
cm = plt.get_cmap('Gist_Rainbow')
fig = plt.figure()
ax = fig.add_subplot(111)
for i in range(NUM_COLORS):
lines = ax.plot(np.arange(10)*(i+1))
lines[0].set_color(cm(i//NUM_STYLES*float(NUM_STYLES)/NUM_COLORS))
lines[0].set_linestyle(LINE_STYLES[i%NUM_STYLES])
fig.savefig('moreColors.png')
plt.show()
Don Kirkby's answer を構築するために、 seaborn をインストール/使用する場合は、色を計算できます:
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
NUM_COLORS = 20
LINE_STYLES = ['solid', 'dashed', 'dashdot', 'dotted']
NUM_STYLES = len(LINE_STYLES)
sns.reset_orig() # get default matplotlib styles back
clrs = sns.color_palette('husl', n_colors=NUM_COLORS) # a list of RGB tuples
fig, ax = plt.subplots(1)
for i in range(NUM_COLORS):
lines = ax.plot(np.arange(10)*(i+1))
lines[0].set_color(clrs[i])
lines[0].set_linestyle(LINE_STYLES[i%NUM_STYLES])
fig.savefig('moreColors.png')
plt.show()
Seabornのさまざまなカラーパレットを使用できるほかに、必要に応じて後で使用/操作できるRGBタプルのリストを取得できます。明らかに、matplotlibのカラーマップを使用して同様の何かを計算できますが、これは便利だと思います。