Python Matplotlib使用线条颜色渐变和颜色条

13

我一直在琢磨这个问题,离我想要的只差那一两行了。

基本上,我想绘制一条单独的线,其颜色根据第三个数组的值而变化。我研究过,发现这个方法效果不错(尽管速度相对较慢),能够解决这个问题。

import numpy as np
import matplotlib.pyplot as plt
c = np.arange(1,100)
x = np.arange(1,100)
y = np.arange(1,100)

cm = plt.get_cmap('hsv')

fig = plt.figure(figsize=(5,5))
ax1 = plt.subplot(111)

no_points = len(c)
ax1.set_color_cycle([cm(1.*i/(no_points-1)) 
                     for i in range(no_points-1)])

for i in range(no_points-1):
    bar = ax1.plot(x[i:i+2],y[i:i+2])
plt.show()

这给了我这个:

单行带颜色变化

我想能够在这个图中包含一个颜色条。到目前为止,我还没有成功解决它。可能会有其他线条包含不同的x,y但相同的c,因此我认为标准化对象将是正确的路径。

更大的图像是该图是2x2子图网格的一部分。我已经用matplotlib.colorbar.make_axes(ax4)为颜色条轴对象腾出了空间,其中ax4是第4个子图。


1
请参考这里的第二个示例:http://matplotlib.org/examples/pylab_examples/multicolored_line.html,您应该使用`LineCollection`,它是一个`ScalarMappable`子类,因此您可以将艺术家传递给`fig.colorbar()`以获取颜色条。 - tacaswell
1个回答

18

请查看Matplotlib图库中的多彩线条示例dpsanders的colorline笔记本

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.collections as mcoll

def multicolored_lines():
    """
    http://nbviewer.ipython.org/github/dpsanders/matplotlib-examples/blob/master/colorline.ipynb
    http://matplotlib.org/examples/pylab_examples/multicolored_line.html
    """

    x = np.linspace(0, 4. * np.pi, 100)
    y = np.sin(x)
    fig, ax = plt.subplots()
    lc = colorline(x, y, cmap='hsv')
    plt.colorbar(lc)
    plt.xlim(x.min(), x.max())
    plt.ylim(-1.0, 1.0)
    plt.show()

def colorline(
        x, y, z=None, cmap='copper', norm=plt.Normalize(0.0, 1.0),
        linewidth=3, alpha=1.0):
    """
    http://nbviewer.ipython.org/github/dpsanders/matplotlib-examples/blob/master/colorline.ipynb
    http://matplotlib.org/examples/pylab_examples/multicolored_line.html
    Plot a colored line with coordinates x and y
    Optionally specify colors in the array z
    Optionally specify a colormap, a norm function and a line width
    """

    # Default colors equally spaced on [0,1]:
    if z is None:
        z = np.linspace(0.0, 1.0, len(x))

    # Special case if a single number:
    # to check for numerical input -- this is a hack
    if not hasattr(z, "__iter__"):
        z = np.array([z])

    z = np.asarray(z)

    segments = make_segments(x, y)
    lc = mcoll.LineCollection(segments, array=z, cmap=cmap, norm=norm,
                              linewidth=linewidth, alpha=alpha)

    ax = plt.gca()
    ax.add_collection(lc)

    return lc

def make_segments(x, y):
    """
    Create list of line segments from x and y coordinates, in the correct format
    for LineCollection: an array of the form numlines x (points per line) x 2 (x
    and y) array
    """

    points = np.array([x, y]).T.reshape(-1, 1, 2)
    segments = np.concatenate([points[:-1], points[1:]], axis=1)
    return segments

multicolored_lines()

请注意,调用plt.plot数百次会影响性能。 使用 LineCollection 构建多色线段要快得多。


输入图像描述


我本来想粘贴一个答案,不过我决定点个赞就好了 :-p - tacaswell
太好了!谢谢你,正是我在寻找的! - TJG
像往常一样,unutbu的回答非常出色。人们可能认为使用一些默认的matplotlib参数应该更容易实现。 - Gabriel
回复晚了,你怎么在这里添加另一行?(一个图中有两行,每行颜色不同) - DsCpp
很棒的答案。此外,您可能需要查看https://dev59.com/tqfja4cB1Zd3GeqPx5Ri#47856091以获取更粗线条的高级用法。 - Leonard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接