Matplotlib通过Colormap绘制颜色线条

Sco*_*ott 13 python numpy matplotlib colormap

我正在一个绘图上绘制多条线,我希望它们能够遍历色图的光谱,而不仅仅是相同的6或7种颜色.代码类似于:

for i in range(20):
     for k in range(100):
          y[k] = i*x[i]
     plt.plot(x,y)
plt.show()
Run Code Online (Sandbox Code Playgroud)

使用colormap"jet"和我从seaborn导入的另一个,我得到相同的7种颜色以相同的顺序重复.我希望能够绘制多达60种不同的线条,所有线条都有不同的颜色.

Bar*_*art 30

Matplotlib色图接受一个参数(0..1,标量或数组),用于从色彩图中获取颜色.例如:

col = pl.cm.jet([0.25,0.75])    
Run Code Online (Sandbox Code Playgroud)

给你一个包含(两种)RGBA颜色的数组:

数组([[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])
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • PyLab 是将 PyPlot 和 NumPy 命名空间组合为一个命名空间(以避免导入两个命名空间)。现在不鼓励使用 Pylab。对于此示例,您可以使用“import matplotlib.pyplot as pl”而不是“import matplotlib.pylab as pl” (2认同)

Ram*_*uet 15

Bart 的答案的一个替代方案,其中您没有在每次调用中指定颜色,plt.plot而是使用 定义一个新的颜色循环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)
Run Code Online (Sandbox Code Playgroud)


Ale*_*ams 12

Bart的解决方案很简单但有两个缺点.

  1. plt.colorbar() 不会以一种很好的方式工作,因为线图不可映射(与例如图像相比)

  2. 由于for循环,对于大量行可能会很慢(尽管对于大多数应用程序来说这可能不是问题?)

这些问题可以通过使用来解决LineCollection.但是,在我的(卑微)意见中,这不是太用户友好.在GitHub上有一个开放的建议,用于添加多色线图功能,类似于该plt.scatter(...)功能.

这是一个我能够一起破解的工作示例

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
Run Code Online (Sandbox Code Playgroud)

这是一个非常简单的例子:

xs = [[0, 1],
      [0, 1, 2]]
ys = [[0, 0],
      [1, 2, 1]]
c = [0, 1]

lc = multiline(xs, ys, c, cmap='bwr', lw=2)
Run Code Online (Sandbox Code Playgroud)

生产:

例1

还有一些更复杂的东西:

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')
Run Code Online (Sandbox Code Playgroud)

生产:

在此输入图像描述

希望这可以帮助!


Shi*_*hah 5

如果您使用的是 brg、hsv、jet 或默认的连续颜色托盘,那么您可以这样做:

color = plt.cm.hsv(r) # r is 0 to 1 inclusive
Run Code Online (Sandbox Code Playgroud)

现在您可以将此颜色值传递给您想要的任何 API,如下所示:

line = matplotlib.lines.Line2D(xdata, ydata, color=color)
Run Code Online (Sandbox Code Playgroud)