1つのプロットに複数の線をプロットし、同じ6色または7色だけでなく、カラーマップのスペクトル全体を通過させたい。コードはこれに似ています:
for i in range(20):
for k in range(100):
y[k] = i*x[i]
plt.plot(x,y)
plt.show()
カラーマップ「ジェット」とシーボーンからインポートした別のものの両方で、同じ7色が同じ順序で繰り返されます。最大60までの異なる線を、すべて異なる色でプロットできるようにしたいと思います。
Matplotlibカラーマップは引数(0..1
、スカラーまたは配列)を使用して、カラーマップから色を取得します。例えば:
col = pl.cm.jet([0.25,0.75])
(2つの)RGBA色の配列を提供します。
array([[0.、0.50392157、1.、1.]、[1.、0.58169935、0.、1.]])
これを使用して、N
異なる色を作成できます。
import numpy as np
import matplotlib.pylab as pl
x = np.linspace(0, 2*np.pi, 64)
y = np.cos(x)
pl.figure()
pl.plot(x,y)
n = 20
colors = pl.cm.jet(np.linspace(0,1,n))
for i in range(n):
pl.plot(x, i*y, color=colors[i])
バートのソリューションは素晴らしくシンプルですが、2つの欠点があります。
plt.colorbar()
は、ラインプロットが(たとえば、画像と比較して)マップできないため、適切に機能しません。
Forループが原因で、行数が多い場合は遅くなる可能性があります(これはほとんどのアプリケーションでは問題にならないかもしれませんが?)
これらの問題は LineCollection
を使用して解決できます。ただし、これは私の(控えめな)意見ではユーザーフレンドリーではありません。 plt.scatter(...)
関数と同様に、マルチカラーラインプロット関数を追加するためのオープンな GitHubに関する提案 があります。
これは私が一緒にハッキングすることができた実用的な例です
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
def multiline(xs, ys, c, ax=None, **kwargs):
"""Plot lines with different colorings
Parameters
----------
xs : iterable container of x coordinates
ys : iterable container of y coordinates
c : iterable container of numbers mapped to colormap
ax (optional): Axes to plot on.
kwargs (optional): passed to LineCollection
Notes:
len(xs) == len(ys) == len(c) is the number of line segments
len(xs[i]) == len(ys[i]) is the number of points for each line (indexed by i)
Returns
-------
lc : LineCollection instance.
"""
# find axes
ax = plt.gca() if ax is None else ax
# create LineCollection
segments = [np.column_stack([x, y]) for x, y in Zip(xs, ys)]
lc = LineCollection(segments, **kwargs)
# set coloring of line segments
# Note: I get an error if I pass c as a list here... not sure why.
lc.set_array(np.asarray(c))
# add lines to axes and rescale
# Note: adding a collection doesn't autoscalee xlim/ylim
ax.add_collection(lc)
ax.autoscale()
return lc
これは非常に簡単な例です:
xs = [[0, 1],
[0, 1, 2]]
ys = [[0, 0],
[1, 2, 1]]
c = [0, 1]
lc = multiline(xs, ys, c, cmap='bwr', lw=2)
生成する:
そしてもう少し洗練されたもの:
n_lines = 30
x = np.arange(100)
yint = np.arange(0, n_lines*10, 10)
ys = np.array([x + b for b in yint])
xs = np.array([x for i in range(n_lines)]) # could also use np.tile
colors = np.arange(n_lines)
fig, ax = plt.subplots()
lc = multiline(xs, ys, yint, cmap='bwr', lw=2)
axcb = fig.colorbar(lc)
axcb.set_label('Y-intercept')
ax.set_title('Line Collection with mapped colors')
生成する:
お役に立てれば!
plt.plot
への各呼び出しで色を指定しないBartの回答の代替案は、set_prop_cycle
で新しいカラーサイクルを定義することです。彼の例は次のコードに変換できます(matplotlibのインポートも推奨スタイルに変更しました)。
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2*np.pi, 64)
y = np.cos(x)
n = 20
ax = plt.axes()
ax.set_prop_cycle('color',[plt.cm.jet(i) for i in np.linspace(0, 1, n)])
for i in range(n):
plt.plot(x, i*y)
Brg、hsv、jet、またはデフォルトのパレットなどの連続カラーパレットを使用している場合は、次のようにすることができます。
color = plt.cm.hsv(r) # r is 0 to 1 inclusive
これで、この色の値を次のような任意のAPIに渡すことができます。
line = matplotlib.lines.Line2D(xdata, ydata, color=color)