Matplotlib Plot Lines with Colors Through Colormap
我在一条绘图上绘制多条线,我希望它们遍历一个颜色图的光谱,而不仅仅是相同的6或7种颜色。 代码类似于此:
1 2 3 4 5 | for i in range(20): for k in range(100): y[k] = i*x[i] plt.plot(x,y) plt.show() |
使用colormap" jet"和我从seaborn导入的另一个,我得到了相同顺序重复的相同7种颜色。 我希望能够绘制多达约60条不同颜色的线。
Matplotlib颜色图接受参数(
1 | col = pl.cm.jet([0.25,0.75]) |
为您提供具有(两种)RGBA颜色的阵列:
array([[ 0. , 0.50392157, 1. , 1. ],
[ 1. , 0.58169935, 0. , 1. ]])
您可以使用它来创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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]) |
Bart的解决方案既好又简单,但有两个缺点。
由于for循环,对于大量的行它可能会很慢(尽管对于大多数应用程序来说这可能不是问题吗?)
这些问题可以通过使用
这是一个我可以一起破解的工作示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | 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 |
这是一个非常简单的示例:
1 2 3 4 5 6 7 | xs = [[0, 1], [0, 1, 2]] ys = [[0, 0], [1, 2, 1]] c = [0, 1] lc = multiline(xs, ys, c, cmap='bwr', lw=2) |
产生:
还有一些更复杂的东西:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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') |
产生:
希望这可以帮助!
Bart答案的另一种形式,其中您没有在每次调用
1 2 3 4 5 6 7 8 9 10 11 12 | 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或默认色板,则可以这样做:
1 | color = plt.cm.hsv(r) # r is 0 to 1 inclusive |
现在,您可以将颜色值传递给您想要的任何API,如下所示:
1 | line = matplotlib.lines.Line2D(xdata, ydata, color=color) |